はじめに
この記事は2023年度の振り返りです。
こちらの続きとなります。
問題を解いてる時の実話を元に、作成しております
勉強会内の小話
初学者達:よし!次の問題に行きましょう!
講師:え?いやいやいや・・・・他の解き方もあるでしょ?
初学者達:え?ありますっけ?
講師:ほら・・・結合のあれだよ。ジョ・・・
初学者達:ジョジョの奇妙な冒険!
講師:んなもん、ねーよ!joinな!
初学者達:あーjoinですね!知ってますよ!
初学者達:has_manyとbelongs_to使えばサクッと終わるやつですね。
講師:ほう。じゃぁ、まずはリレーションを組んでみよう
初学者達:こんな感じでどうですか?
class Author < ApplicationRecord
has_many :writes
end
class Write < ApplicationRecord
belongs_to :author
belongs_to :comic
end
class Comic < ApplicationRecord
has_many :writes
end
講師:じゃぁ、確認してみよう
author = Author.find_by(name: '冨樫 義博')
author.writes
`method_missing': undefined method `writes' for #<Author id: 3, name: "冨樫 義博", created_at: "2023-12-22 14:32:29.866785000 +0000", updated_at: "2023-12-22 14:32:29.866785000 +0000"> (NoMethodError)
講師:エラーでてんじゃーん。(ニヤニヤ)
初学者達:あれ?なんで?
講師:なんで、ここをこう書いたんだ?
class Author < ApplicationRecord
has_many :writes # ← ココ
end
講師:なるほど。これは、railsが勝手な解釈をしてしまったが故にこうなったんだよ
初学者達:???
講師:試しに、writeテーブルにauthor_idカラムを追加した状態で、さっきのを動かしてみよう
author = Author.find_by(name: '冨樫 義博')
author.writes
Write Load (0.3ms) SELECT `writes`.* FROM `writes` WHERE `writes`.`author_id` = 3
初学者達:あ、動きました!なんで???
講師:重要なのはココ!
author = Author.find_by(name: '冨樫 義博')
author.writes
Write Load (0.3ms) SELECT `writes`.* FROM `writes` WHERE `writes`.`author_id` = 3
---------
講師:Authorモデルに、has_many :writesと書いたことで、writesテーブルにauthor_idがあると解釈して、author_idと紐づけようとしたんだ。
講師:今回は、author_idではなく、user_idと紐づけたいので、どうすればいい?
初学者達:公式に乗ってる、foreign_keyかprimary_keyですね!
講師:では、やってみよう
初学者達:はい!
class Author < ApplicationRecord
has_many :writes , foreign_key: 'user_id' # ココだけを修正
end
初学者達:なった!
author = Author.find_by(name: '冨樫 義博')
author.writes
Write Load (0.4ms) SELECT `writes`.* FROM `writes` WHERE `writes`.`user_id` = 3
---------
初学者達:試しに・・・
class Author < ApplicationRecord
has_many :writes, primary_key: 'user_id'
-----------
end
初学者達:NULLになった!
author = Author.find_by(name: '冨樫 義博')
author.writes
Write Load (0.4ms) SELECT `writes`.* FROM `writes` WHERE `writes`.`author_id` IS NULL
--------
初学者達:この参照先というのは、authorsテーブルのuser_idカラムを参照しようとしてるけど、そんなカラムがないからNULLになってる?
講師:正解!なので、この場合は、foreign_keyを使うのが正解となりますね
初学者達:なるほど・・・。こんな感じにrailsが勝手に解釈するんですね・・・
講師:カラムを整合性合わせて作るなら問題ないけど、整合性が取れないカラムと連携が必要になった場合は、foreign_keyなどのオプションが必要になってくる。
講師:オプションを省略してる場合、どのようにrailsが解釈して動いているかは理解しといた方がいいですよ
初学者達:わかりました!!
長くなったので次回へ。。。
さいごに
序盤のくだりはすみません。
アーニャのジト目を使いたかっただけなんです。ホントすみません。