0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Ruby on Rails】delegateで関連モデルに直接アクセスする

Posted at

はじめに

Railsなどを中心に勉強中のエンジニア初心者が他の記事を参考にしたり、実際に実装してみたりして、アウトプットの一環としてまとめたものです。
間違っていることもあると思われるので、その際は指摘いただけると幸いです。

アソシエーションの基本

下記のテーブルを想定して記述する。

カラム名の設定など冗長かもしれませんがご容赦ください。

Untitled.png

以下のようなアソシエーションが組まれているとする。

class Supplier < ActiveRecord::Base
  has_many :rooms
end
class Room < ActiveRecord::Base
  belongs_to :supplier
end

ここで、room.supplier.supplier_nameとすることで、あるroomsuppliersupplier_nameを取得することができる。

関連モデルに直接する

モデルにメソッドを記述する

以下のようにモデルにsupplierメソッドを記述すれば、room.suuplier_nameのみで、あるroomsuppliersupplier_nameを取得することができる。

すなわち、直接supplierモデルの値を取得することができている。

class Room < ActiveRecord::Base
  belongs_to :supplier

	def supplier_name 
    supplier.supplier_name
  end
end

delegateを使用する

delegateを使用することで、前述したsupplierメソッドの役割をさらに短縮して記載することができる。

このように記載した場合もroom.suuplier_nameのみで、あるroomsuppliersupplier_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

参考

最後に

いかがでしたでしょうか。
ここ違うよ!でしたり、こうした方がいいよ!などがあればコメントいただけると幸いです。

他にも下記のような記事を投稿しております。
興味がありましたら、ぜひご覧ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?