はじめに
Railsなどを中心に勉強中のエンジニア初心者が他の記事を参考にしたり、実際に実装してみたりして、アウトプットの一環としてまとめたものです。
間違っていることもあると思われるので、その際は指摘いただけると幸いです。
アソシエーションの基本
下記のテーブルを想定して記述する。
カラム名の設定など冗長かもしれませんがご容赦ください。
以下のようなアソシエーションが組まれているとする。
class Supplier < ActiveRecord::Base
has_many :rooms
end
class Room < ActiveRecord::Base
belongs_to :supplier
end
ここで、room.supplier.supplier_name
とすることで、あるroom
のsupplier
のsupplier_name
を取得することができる。
関連モデルに直接する
モデルにメソッドを記述する
以下のようにモデルにsupplier
メソッドを記述すれば、room.suuplier_name
のみで、あるroom
のsupplier
のsupplier_name
を取得することができる。
すなわち、直接supplier
モデルの値を取得することができている。
class Room < ActiveRecord::Base
belongs_to :supplier
def supplier_name
supplier.supplier_name
end
end
delegateを使用する
delegate
を使用することで、前述したsupplier
メソッドの役割をさらに短縮して記載することができる。
このように記載した場合もroom.suuplier_name
のみで、あるroom
のsupplier
のsupplier_name
を取得することができる。
class Room < ActiveRecord::Base
belongs_to :supplier
delegate :supplier_name, to: :supplier
end
delegateについて
前述した例のようにdelegateメソッドは、メソッドを委譲することができる。
基本形
# 基本形
delegate :メソッド名(カラム名), to: :関連付けしているモデル名
# 複数のメソッド(カラム)を指定する場合
delegate :メソッド1, :メソッド2, :メソッド3, to: :関連付けしているモデル名
allow_nil
オプション
取得しようとした先の値がない場合、NoMethodError
となってしまう。
そこで、allow_nil
オプションを使用することで、例外の代わりにnil
を返すようにできる。
class Room < ActiveRecord::Base
belongs_to :supplier
delegate :supplier_name, to: :supplier, allow_nil: true
end
prefix
オプション
prefix
オプションをtrue
にすることで、委譲先で生成されるメソッドにprefix
(接頭辞)をつけることができる。
以下のように記述した場合は、room.supplier_supplier_name
で取得することができる。
class Room < ActiveRecord::Base
belongs_to :supplier
delegate :supplier_name, to: :supplier, prefix: true
end
また、prefix
をカスタマイズすることも可能である。
以下のように記述した場合は、room.host_supplier_name
で取得することができる。
class Room < ActiveRecord::Base
belongs_to :supplier
delegate :supplier_name, to: :supplier, prefix: :host
end
private
オプション
delegate
によって委譲先で生成されたメソッドは、デフォルトではpublic
なメソッドになるため、どこからでもアクセスが可能になる。
アクセスを制限したい場合は、以下のようにprivate
オプションを付与することで、スコープを制限することができる。
class Room < ActiveRecord::Base
belongs_to :supplier
delegate :supplier_name, to: :supplier, private: true
end
delegate_missing_to
delegate_missing_to
メソッドを使用することで、全てのメソッドを委譲することができる。
delegate
で一つ一つ宣言しなくとも、委譲できる
class Room < ActiveRecord::Base
belongs_to :supplier
delegate_missing_to :supplier
end
参考
最後に
いかがでしたでしょうか。
ここ違うよ!でしたり、こうした方がいいよ!などがあればコメントいただけると幸いです。
他にも下記のような記事を投稿しております。
興味がありましたら、ぜひご覧ください。