web-dev-qa-db-ja.com

has_one / has_manyのRailsの:sourceオプションを理解する

:source関連付けのhas_one/has_many :throughオプションを理解するのを手伝ってください。 Rails AP​​Iの説明は、私にはほとんど意味がありません。

has_many:through => :queriesが使用するソース関連付け名を指定します。名前を関連付けから推測できない場合にのみ使用します。has_many :subscribers, :through => :subscriptionsは、:subscribersが指定されない限り、Subscription:subscriberまたは:sourceを探します。」

174
Tri Vuong

場合によっては、関連付けごとに異なる名前を使用することがあります。モデルの関連付けに使用する名前が:throughモデルの関連付けと異なる場合、:sourceを使用して指定できます。

上記の段落はドキュメント内の段落よりもmuch明確ではないと思うので、ここに例を示します。 PetDog、およびDog::Breedの3つのモデルがあるとします。

class Pet < ActiveRecord::Base
  has_many :dogs
end

class Dog < ActiveRecord::Base
  belongs_to :pet
  has_many :breeds
end

class Dog::Breed < ActiveRecord::Base
  belongs_to :dog
end

この場合、Dog.find(123).breedsにニースで便利な関連付けとしてアクセスするため、Dog::Breedの名前空間を選択しました。

Pethas_many :dog_breeds, :through => :dogsアソシエーションを作成したい場合、突然問題が発生します。 RailsはDog:dog_breedsアソシエーションを見つけることができないため、Railsはおそらく知ることができません whichDog使用する関連付け。 :sourceを入力:

class Pet < ActiveRecord::Base
  has_many :dogs
  has_many :dog_breeds, :through => :dogs, :source => :breeds
end

:sourceを使用すると、RailsにDogモデルで:breedsという関連付けを探します(使用されるモデルとして) :dogs)、およびそれを使用します。

221
vonconrad

その例を拡張してみましょう。

class User
  has_many :subscriptions
  has_many :newsletters, :through => :subscriptions
end

class Newsletter
  has_many :subscriptions
  has_many :users, :through => :subscriptions
end

class Subscription
  belongs_to :newsletter
  belongs_to :user
end

このコードを使用すると、Newsletter.find(id).usersなどの操作を実行して、ニュースレターの購読者のリストを取得できます。ただし、より明確になり、代わりにNewsletter.find(id).subscribersと入力できるようにするには、ニュースレタークラスを次のように変更する必要があります。

class Newsletter
  has_many :subscriptions
  has_many :subscribers, :through => :subscriptions, :source => :user
end

users関連付けの名前をsubscribersに変更しています。 :sourceを指定しない場合、RailsはSubscriptionクラスでsubscriberと呼ばれる関連付けを探します。購読者のリストを作成するには、Subscriptionクラスでuserアソシエーションを使用するように指示する必要があります。

187
Jeremy Ruten

最も簡単な答え:

中央のテーブル内の関係の名前です。

9
andfb18