0Pricing
Ruby Academy · レッスン

関連付け

has_many と belongs_to です。

「関連付け」はCoddyKit上の無料Ruby Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはRuby Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Ruby Academyコースには全4レッスンが含まれています。

関連付けとは

関連付けはモデル間の関係を宣言するもので、Active Recordが関連する行を自動的にたどれるようにします。結合SQLを書く代わりに、user.postsのようなメソッドを呼び出せます。

  • データベースの外部キーを反映します。
  • ヘルパーメソッドを自動的に生成します。
  • ドメインに沿った読みやすいコードになります。

belongs_to

belongs_toは、このモデルが別のモデルを指す外部キーを保持することを表します。Postに属するCommentには、post_idカラムがあります。

class Comment < ApplicationRecord
  belongs_to :post
end

# comment.post returns the parent Post
# Requires a post_id column on comments

has_many

has_manyは反対側の関連付けで、1つのレコードが別のモデルの複数のレコードを持つことを表します。Postは複数のCommentレコードを持ちます。外部キーは複数側にあります。

class Post < ApplicationRecord
  has_many :comments
end

# post.comments returns all related comments
# post.comments.create(body: "Nice!")

外部キーがある場所

belongs_toを持つモデルが外部キーを保持します。PostとCommentの場合、commentsテーブルにpost_idがあります。マイグレーションでt.references :postまたはadd_referenceを使って設定します。

create_table :comments do |t|
  t.references :post, foreign_key: true
  t.text :body
  t.timestamps
end

生成されるメソッド

has_many :commentsを設定すると、便利なメソッドを備えたコレクションを利用できます。

  • 読み取るにはpost.commentsを使用します。
  • 関連付けられたレコードを追加するにはpost.comments.create(...)を使用します。
  • 数を数えるにはpost.comments.countを使用します。
  • IDを取得するにはpost.comment_idsを使用します。
post = Post.find(1)
post.comments.create(body: "First!")
puts post.comments.count

has_one

has_oneは、Userが1つのProfileを持つ場合のような1対1の関連付けを表します。外部キーは引き続きもう一方のモデル(profiles.user_id)にあります。

class User < ApplicationRecord
  has_one :profile
end

class Profile < ApplicationRecord
  belongs_to :user
end

throughによる多対多

多対多の関連付けには、結合モデルとhas_many throughを使用します。Studentは、Enrollmentの行を通じて複数のCourseレコードを持ちます。

class Student < ApplicationRecord
  has_many :enrollments
  has_many :courses, through: :enrollments
end

class Enrollment < ApplicationRecord
  belongs_to :student
  belongs_to :course
end

dependentオプション

親を削除したときに子のレコードをどうするかをdependentで指定します。

  • dependent: :destroyは子のレコードも削除します。
  • dependent: :nullifyは子の外部キーをクリアします。
  • dependent: :restrict_with_errorは削除を阻止します。
class Post < ApplicationRecord
  has_many :comments, dependent: :destroy
end

N+1クエリ問題

レコードをループ処理して関連付けにアクセスすると、レコードごとに1回のクエリが発行され、悪名高いN+1が発生することがあります。10件の投稿とそのコメントを読み込む場合、2回ではなく11回のクエリが実行される可能性があります。

この問題は、データが増えるにつれてアプリケーションを気付かないうちに遅くします。

# N+1: one query per post for comments
Post.all.each do |post|
  puts post.comments.count
end

includesでN+1を解消する

includesを使うと、Active Recordは多数のクエリを発行する代わりに、数回のクエリで関連付けを先行読み込みします。これはN+1に対する標準的な解決策です。

Post.includes(:comments).each do |post|
  puts post.comments.count
end

class_nameで名前をカスタマイズする

関連付けの名前がモデル名と一致しない場合は、class_nameやforeign_keyなどのオプションを使用します。たとえば、Userモデルを参照するauthor関連付けを設定できます。

class Post < ApplicationRecord
  belongs_to :author, class_name: "User"
end

理解度チェック

関連付けについての理解度を確認します。

まとめ:関連付け

モデル同士を関連付ける方法を学びました。

  • belongs_toが外部キーを保持し、has_manyとhas_oneが反対側を表します。
  • has_many throughで多対多の関連付けを表します。
  • dependentで連鎖削除を制御します。
  • includesでN+1クエリを回避します。

次は、バリデーションでデータの整合性を確保し、クエリの方法を学びます。

よくある質問

「関連付け」レッスンは無料ですか?

はい。「関連付け」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Ruby Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Ruby Academyコースには全4レッスンが含まれています。

「関連付け」で何を学びますか?

has_many と belongs_to です。 ブラウザで直接実行するハンズオンコードでRuby Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Ruby Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのRuby Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「関連付け」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このRuby Academyレッスンでコードを書いて実行できますか?

はい。すべてのRuby Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Active Record の基礎
  2. マイグレーション
  3. 関連付け
  4. バリデーションとクエリ
← Ruby Academyに戻る