Rails カラム名を変えてアソシエーションを設定する!foreign_keyを使おう

rails

こんにちは。菜笑[なえ]です。
今回は「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

普通なら、こんな感じでcustomersshop_idを持たせれば終わる話なんですが。

create_table :customers do |t|
  t.string :name
  t.integer :shop_id
end

今回は訳あって、shop.idcustomer.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_keyprimary_keyを指定してみたけど上手くいきませんでした。

こんな感じでずっと一方のforeign_keyvisit_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でいいようです。
この辺りはもう少しちゃんと理解できるように勉強しようと思います。

SNS

Twitter:@nae310_
Instagram:310nae