こんにちは。菜笑[なえ]です。
今回は「Rails カラム名を変えてアソシエーションを設定する!foreign_keyを使おう」という内容で書いていきます。
目次
事象
create_table :shops do |t|
t.string :name
end
create_table :customers do |t|
t.string :name
t.integer :visit_shop_id
end
このテーブルで構成で、以下のアソシエーションを実現させたいと思います。
class Shop < ApplicationRecord
has_many :customers
end
class Customer < ApplicationRecord
belongs_to :shop
end
普通なら、こんな感じでcustomers
にshop_id
を持たせれば終わる話なんですが。
create_table :customers do |t|
t.string :name
t.integer :shop_id
end
今回は訳あって、shop.id
とcustomer.visit_shop_id
を関連付けました。
エラー内容
上記のアソシエーションだけだと、以下のエラーが出ました。
> Shop.first.customers
CACHE Shop Load (0.0ms) SELECT `shops`.* FROM `shops` ORDER BY `shops`.`id` ASC LIMIT 1
=> Customer Load (1.2ms) SELECT `customers`.* FROM `customers` WHERE `customers`.`shop_id` = 1
Customer Load (1.8ms) SELECT `customers`.* FROM `customers` WHERE `customers`.`shop_id` = 1 LIMIT 11
#<Customer::ActiveRecord_Associations_CollectionProxy:0x3fca018c12b0>
> Customer.first.shop
Customer Load (0.5ms) SELECT `customers`.* FROM `customers` WHERE `customers`.`id` = 1 LIMIT 1
=> nil
解決方法
class Shop < ApplicationRecord
has_many :customers, foreign_key: 'visit_shop_id'
end
class Customer < ApplicationRecord
belongs_to :shop, foreign_key:'visit_shop_id'
end
これで、どちらも正しく情報が取得できました。
おわりに
いろんな組み合わせで、foreign_key
とprimary_key
を指定してみたけど上手くいきませんでした。
こんな感じでずっと一方のforeign_key
にvisit_shop_id
を指定して、もう一方のprimary_key
ににvisit_shop_id
という感じでやってました。
has_many :customers, primary_key: 'id', foreign_key: 'visit_shop_id'
belongs_to :shop, primary_key: 'visit_shop_id', foreign_key:'id'
結果的にどっちも、foreign_key
でいいようです。
この辺りはもう少しちゃんと理解できるように勉強しようと思います。