#既存のモデル
Moving
Room
上記のモデル間にhas_many
& belongs_to
関係を追加する。
#やり方
##各モデルのテーブルにお互いのidをforeign_key
として追加し、マイグレートする
$ rails g migration add_room_to_movings room:references
下記のマイグレーションが生成される。間違いがないか確認。
class AddRoomToMovings < ActiveRecord::Migration
def change
add_reference :movings, :room, index: true, foreign_key: true
end
end
$ rails g migration add_moving_to_rooms moving:references
下記のマイグレーションが生成される。間違いがないか確認。
class AddMovingToRooms < ActiveRecord::Migration
def change
add_reference :rooms, :moving, index: true, foreign_key: true
end
end
$ rake db:migrate
##has_many
、belongs_to
を関係するモデルのクラスに追加
class Moving < ActiveRecord::Base
...
has_many :rooms, dependent: :destroy
...
class Room < ActiveRecord::Base
...
belongs_to :moving
...
これで完了。
##コンソールで思い通りの振る舞いになっているか確認
$ rails console --sandbox
色々試す。本当にこれで良いのかここでよく考える。場合によってはhas_many
, through
を使えばもっと効率よくデータの管理ができるかもしれない。
##気が変わったら、早いうちにやり直す(許されるなら)
$ rails destroy migration add_moving_to_rooms moving:references
invoke active_record
remove db/migrate/20150725142845_add_moving_to_rooms.rb
$ rails destroy migration add_room_to_movings room:references
invoke active_record
remove db/migrate/20150725142417_add_room_to_movings.rb
忘れずにhas_many
、belongs_to
をモデルのクラスから取り除くこと。
以下のタスクでschemaを更新する。
$ bundle exec rake db:drop
$ bundle exec rake db:create
$ bundle exec rake db:migrate
$ bundle exec rake db:seed
##has_many, through
に変更することにした
以下のコマンドで中間テーブルのクラスとマイグレーションをつくる。
rails g model MovingRoom moving_id:integer room_id:integer
class CreateMovingRooms < ActiveRecord::Migration
def change
create_table :moving_rooms do |t|
t.integer :moving_id
t.integer :room_id
t.timestamps null: false
end
end
end
class MovingRoom < ActiveRecord::Base
end
中間テーブルのクラスにbelongs_to
を追加し、モデルを関連させる。
class MovingRoom < ActiveRecord::Base
belongs_to :moving
belongs_to :room
end
各モデルクラスにhas_many...through...
を追加し、中間テーブル経由でお互いにアクセスできるようにする。
class Moving < ActiveRecord::Base
...
has_many :moving_rooms, dependent: :destroy
has_many :rooms, through: :moving_rooms
...
class Room < ActiveRecord::Base
...
has_many :moving_rooms, dependent: :destroy
has_many :movings, through: :moving_rooms
...
効率よくクエリできるようIndexを追加
class AddIndexToMovingRooms < ActiveRecord::Migration
def change
add_index :moving_rooms, :moving_id
add_index :moving_rooms, :room_id
add_index :moving_rooms, [:moving_id, :room_id], unique: true
end
end
以上。
#参考資料