Zrozumienie: opcja źródła ma jeden / ma wiele przez szyny

Proszę o pomoc w zrozumieniu :source opcji has_one/has_many :through asocjacji. Wyjaśnienie rails API nie ma dla mnie większego sensu.

" określa źródłową nazwę asocjacji używaną przez has_many :through => :queries. Używać go tylko wtedy, gdy nazwy nie można wywnioskować z Stowarzyszenie. has_many :subscribers, :through => :subscriptions will Szukaj :subscribers lub :subscriber na Subscription, chyba że podano :source. "

Author: user2262149, 2011-01-08

3 answers

Czasami chcesz używać różnych nazw dla różnych skojarzeń. Jeśli nazwa, której chcesz użyć dla asocjacji w modelu, nie jest taka sama jak Asocjacja w modelu :through, możesz użyć :source, aby ją określić.

Nie sądzę, aby powyższy akapit był dużo jaśniejszy niż ten w dokumentach, więc oto przykład. Załóżmy, że mamy trzy modele, Pet, Dog i Dog::Breed.

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

W tym przypadku wybraliśmy przestrzeń nazw Dog::Breed, ponieważ chcemy access Dog.find(123).breeds jako miłe i wygodne skojarzenie.

Teraz, jeśli teraz chcemy utworzyć has_many :dog_breeds, :through => :dogs skojarzenie na Pet, nagle mamy problem. Rails nie będzie w stanie znaleźć skojarzenia :dog_breeds na Dog, więc Rails nie może wiedzieć , które Dog stowarzyszenie, którego chcesz użyć. Wpisz :source:

class Pet < ActiveRecord::Base
  has_many :dogs
  has_many :dog_breeds, :through => :dogs, :source => :breeds
end
Rails może być używany do tworzenia asocjacji o nazwie :breedsna modelu Dog (ponieważ jest to model używany do:dogs) i używać go.
 197
Author: vonconrad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 11:08:54

Pozwolę sobie rozwinąć ten przykład:

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

Za pomocą tego kodu możesz zrobić coś w rodzaju Newsletter.find(id).users, aby uzyskać listę subskrybentów newslettera. Ale jeśli chcesz być jaśniejszy i móc zamiast tego wpisać Newsletter.find(id).subscribers, musisz zmienić klasę newslettera na tę:

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

Zmieniasz nazwę Stowarzyszenia users na subscribers. Jeśli nie podasz :source, Rails będzie szukał skojarzenia o nazwie subscriber w klasie Subscription. Trzeba powiedzieć, aby używać asocjacji user w Klasa subskrypcji do tworzenia listy subskrybentów.

 167
Author: Jeremy Ruten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-08 05:07:32

Najprostsza odpowiedź:

To nazwa relacji w tabeli w środku.

 6
Author: andfb18,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 15:12:03