belongs_to/has_one/has_manyの簡単まとめ


Ruby on RailsのActive Recordでテーブル間の関連付け(アソシエーション)を行うメソッドbelongs_tohas_onehas_manyを簡単に説明します。

🐮 言いたいこと

  • 対象を1つ持っているなら、has_one
  • 対象を複数持っているなら、has_many
  • 自分が対象に所属しているなら、belongs_to

🚕 belongs_to:自テーブルが対象に所属

belongs_toは、自分のテーブルが対象テーブルのレコードに所属する(対象テーブルのidカラムがある)場合に使います。

belongs_to(関連モデル名 [, scope, オプション])
オプション 説明
:class_name 関連するモデルクラス名を指定。関連名と参照先のクラス名を分けたい場合に使う
:foreign_key 参照先のテーブルの外部キーのカラム名
:primary_key 参照元(自分)のテーブルの外部キーのカラム名
:optional trueを指定すると参照先のテーブルのデータがない場合にエラーにならない

Rails 5からは外部キーのデータが存在しない場合はエラーになります。

🍄 has_one:自テーブルが対象を1つ持っている

has_oneは自分のテーブルが対象テーブルを1つ持っている(複数持たない)場合に使います。対象テーブル側に自分のidのカラムがある場合に使います。

has_one(関連モデル名 [, scope ,オプション])
オプション 説明
:class_name 関連するモデルクラス名を指定。関連名と参照先のクラス名を分けたい場合に使う
:foreign_key 参照先のテーブルの外部キーのカラム名
:primary_key 参照元(自分)のテーブルの外部キーのカラム名

🎂 has_many:自テーブルが対象を複数持っている

has_manyは自分のテーブルが対象テーブルを複数もつ場合に使います。対象テーブル側に自分のidのカラムがある場合に使います。

has_many(関連モデル名 [, scope ,オプション])
オプション 説明
:class_name 関連するモデルクラス名を指定。関連名と参照先のクラス名を分けたい場合に使う
:foreign_key 参照先のテーブルの外部キーのカラム名
:primary_key 参照元(自分)のテーブルの外部キーのカラム名

🏀 補足:dependentオプション

dependentオプションは、モデルの親レコードを削除するときに子のレコードを削除するかどうかを決めるオプションです。

class Category < ActiveRecord::Base
has_many :products, dependent: :option
end

オプションの種類は次のとおりです。

オプション 説明
:destroy 親レコードと一緒に子レコードを削除。子レコードのコールバックも実行
:delete_all 親レコードと一緒に子レコードを削除。SQL直接実行なのでコールバックなし
:nullify 子レコードの外部キーをNULL更新する
:restrict_with_exception 子レコードがある場合はActiveRecord::DeleteRestrictionErrorを発生
:restrict_with_error 子レコードがある場合は削除が失敗し、親レコードにエラー情報を付与

😸 補足:バージョン情報

Rails 5.1.0(Active Record 5.1.0)での情報です。

🚜 参照リンク

📚 おすすめの書籍