Ruby on RailsのActive Recordでテーブル間の関連付け(アソシエーション)を行うメソッドbelongs_to
、has_one
、has_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からは外部キーのデータが存在しない場合はエラーになります。
😼 自テーブルが対象を1つ持っている:has_one
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 |
子レコードがある場合は削除が失敗し、親レコードにエラー情報を付与 |
🍮 補足:joinsで結合先のscopeを使う
class Movie < ApplicationRecord belongs_to :actress scope :year_2017, -> { where(year: 2017) } end
class Cast < ApplicationRecord has_many :movies end
Cast.joins(:movies).merge(Movie.year_2017)
|
🚕 補足:内部結合で結合先の情報を取得する
class Movie < ApplicationRecord belongs_to :actress scope :year_2017, -> { where(year: 2017) } end
class Cast < ApplicationRecord has_many :movies end
Cast.joins(:movies).eager_load(:movies).each do |cast| puts cast.name cast.movies.each { |movie| puts " - #{movie.title}" } end
|
🐝 補足:where句に別テーブルのカラムを設定する
SQLのWHERE
句に別のテーブルのカラムを設定するには次のように記述します。
Article.joins(:comments).where("comment.content LIKE '%ABC%''").count
|
🏀 参照リンク
🖥 VULTRおすすめ
「VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。
最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!