tanish-kr's learning log

Learning output log

Ruby Rails

ActiveRecord Association

Railsガイド

関連付けの種類

belongs_to

belongs_to関連付けを行うと、他方のモデル間に1:1の関係が設定される。この宣言を行うと他方のモデルインスタンスに「従属(belogns to)」することができる。 一般的には外部キーを持つテーブルのモデルに指定される。

class Book < ApplicationRecord
  belongs_to :author
end

belongs_toで指定するモデル名は必ず単数形にする必要がある

Options

:class_name

belongs_toで指定したモデル名が推測できない場合に、クラス名を直接指定することが可能

:foreign_key

関連付けに使用される外部キーを指定する。デフォルトではモデル名 + _idが外部キーとして推測されている

:primary_key

関連付けに使用される主キーを指定する。デフォルトではid

:dependent

:destroy を指定すると削除時にこのモデルに関連するモデルも同時に削除する。:destroy_asyncを指定するとバックグラウンドジョブで削除されるようにスケジュールされる。

:polymorphic

この関連付けがポリモーフィック(多態性)関連であることを示す。

has_one

has_one関連付けも、1:1の関連付けが設定される。has_oneの場合は、その宣言が行われているモデルのインスタンスが、他方のモデルインスタンスを「まるごと含んでいる」または「所有している」ことを示す。一般的には外部キーの関連元のテーブルのモデルに指定される。

class Supplier < ApplicationRecord
  has_one :account
end

Scopes

scopeを定義することで、アソシエーション関連付ける際に条件を追加することができる

has_one :author, -> { where(deleted_at: nil) }

Options

:through

has_one :through関連付けは、他方のモデルに対して「1対1」の関連付けを設定する。2つのモデルの間に「第3のモデル」が介在する

class Supplier < ApplicationRecord
  has_one :account
  has_one :account_history, through: :account
end

class Account < ApplicationRecord
  belongs_to :supplier
  has_one :account_history
end

class AccountHistory < ApplicationRecord
  belongs_to :account
end
:inverse_of

双方向の関連付けを明示的に宣言できる

has_many

has_many関連付けは、他のモデルとの間に「1:多」のつながりであることを示す。

class Author < ApplicationRecord
  has_many :books
end

has_many :through

has_many :through関連付けは、他方のモデルと「多対多」のつながりを設定する場合に使われる

class Physician < ApplicationRecord
  has_many :appointments
  has_many :patients, through: :appointments
end

class Appointment < ApplicationRecord
  belongs_to :physician
  belongs_to :patient
end

class Patient < ApplicationRecord
  has_many :appointments
  has_many :physicians, through: :appointments
end

ポリモーフィック関連付け

ポリモーフィック関連付けを使うと、ある1つのモデルが他の複数のモデルに属していることを、1つの関連付けだけで表現できる

class CreatePictures < ActiveRecord::Migration[5.2]
  def change
    create_table :pictures do |t|
      t.string  :name
      t.references :imageable, polymorphic: true
      t.timestamps
    end
  end
end
class Picture < ApplicationRecord
  belongs_to :imageable, polymorphic: true
end

class Employee < ApplicationRecord
  has_many :pictures, as: :imageable
end

class Product < ApplicationRecord
  has_many :pictures, as: :imageable
end

@employee.pictures # Employeeに属しているpicturesを取得できる

自己結合

class_nameを自身のモデル、foregen_keyを自身の関連キーを指定するようにすると自己結合が可能になる

class Employee < ApplicationRecord
  has_many :subordinates, class_name: "Employee",
                          foreign_key: "manager_id"

  belongs_to :manager, class_name: "Employee", optional: true
end
class CreateEmployees < ActiveRecord::Migration[5.0]
  def change
    create_table :employees do |t|
      t.references :manager
      t.timestamps
    end
  end
end

キャッシュ制御

ActiveRecordの結果は基本的にキャッシュされている。reloadメソッドを呼び出すことで、キャッシュが破棄され再度DBに問い合わせを行う。