勉強会での小話3

# はじめに

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

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

https://qiita.com/youfuku/items/a579bcb4506c73475200

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

# 勉強会内の小話

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

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

初学者達：え？ありますっけ？

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

初学者達：ジョジョの奇妙な冒険！

講師：んなもん、ねーよ！joinな！

初学者達：あーjoinですね！知ってますよ！

講師：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/5cdc1ce5-c85f-9351-a288-ecdc5f211473.png)

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

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

初学者達：こんな感じでどうですか？
```ruby:app/models/author.rb
class Author < ApplicationRecord
  has_many :writes
end
```
```ruby:app/models/write.rb
class Write < ApplicationRecord
  belongs_to :author
  belongs_to :comic
end
```
```ruby:app/models/comic.rb
class Comic < ApplicationRecord
  has_many :writes
end
```

講師：じゃぁ、確認してみよう
```ruby
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)
```

講師：エラーでてんじゃーん。（ニヤニヤ）

初学者達：あれ？なんで？

講師：なんで、ここをこう書いたんだ？
```ruby:app/models/author.rb
class Author < ApplicationRecord
  has_many :writes  # ← ココ
end
```

初学者達：公式だと、こう書かれてるからですね。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/08ebe221-ce64-ad1b-8aaf-e446b848ecbc.png)

https://railsdoc.com/page/has_many

講師：なるほど。これは、railsが勝手な解釈をしてしまったが故にこうなったんだよ

初学者達：？？？

講師：試しに、writeテーブルにauthor_idカラムを追加した状態で、さっきのを動かしてみよう
```ruby
author = Author.find_by(name: '冨樫 義博')
author.writes
Write Load (0.3ms)  SELECT `writes`.* FROM `writes` WHERE `writes`.`author_id` = 3
```

初学者達：あ、動きました！なんで？？？

講師：重要なのはココ!
```ruby
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ですね！

講師：では、やってみよう

初学者達：はい！
```ruby
class Author < ApplicationRecord
  has_many :writes , foreign_key: 'user_id' # ココだけを修正
end
```
初学者達：なった！
```ruby
author = Author.find_by(name: '冨樫 義博')
author.writes
  Write Load (0.4ms)  SELECT `writes`.* FROM `writes` WHERE `writes`.`user_id` = 3
                                                                    ---------
```
初学者達：試しに・・・
```ruby
class Author < ApplicationRecord
  has_many :writes, primary_key: 'user_id'
                    -----------
end
```
初学者達：NULLになった！
```ruby
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が解釈して動いているかは理解しといた方がいいですよ

初学者達：わかりました！！

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

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