4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

勉強会での小話3

Posted at

はじめに

この記事は2023年度の振り返りです。

こちらの続きとなります。

問題を解いてる時の実話を元に、作成しております

勉強会内の小話

初学者達:よし!次の問題に行きましょう!

講師:え?いやいやいや・・・・他の解き方もあるでしょ?

初学者達:え?ありますっけ?

講師:ほら・・・結合のあれだよ。ジョ・・・

初学者達:ジョジョの奇妙な冒険!

講師:んなもん、ねーよ!joinな!

初学者達:あーjoinですね!知ってますよ!

講師:
image.png

初学者達:has_manyとbelongs_to使えばサクッと終わるやつですね。

講師:ほう。じゃぁ、まずはリレーションを組んでみよう

初学者達:こんな感じでどうですか?

app/models/author.rb
class Author < ApplicationRecord
  has_many :writes
end
app/models/write.rb
class Write < ApplicationRecord
  belongs_to :author
  belongs_to :comic
end
app/models/comic.rb
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)

講師:エラーでてんじゃーん。(ニヤニヤ)

初学者達:あれ?なんで?

講師:なんで、ここをこう書いたんだ?

app/models/author.rb
class Author < ApplicationRecord
  has_many :writes  # ← ココ
end

初学者達:公式だと、こう書かれてるからですね。。。
image.png

講師:なるほど。これは、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が解釈して動いているかは理解しといた方がいいですよ

初学者達:わかりました!!

長くなったので次回へ。。。

さいごに

序盤のくだりはすみません。
アーニャのジト目を使いたかっただけなんです。ホントすみません。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?