ruby on rails 3 - with - Entendendo: opção de origem de has_one/has_many através de Rails




rails nested params form (2)

Às vezes, você deseja usar nomes diferentes para associações diferentes. Se o nome que você deseja usar para uma associação no modelo não for o mesmo que a associação no modelo :through , será possível usar :source para especificá-lo.

Eu não acho que o parágrafo acima é muito mais claro do que o dos documentos, então aqui está um exemplo. Vamos supor que temos três modelos, Pet , Dog e 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

Neste caso, optamos pelo namespace do Dog::Breed , porque queremos acessar o Dog.find(123).breeds como uma associação agradável e conveniente.

Agora, se agora queremos criar um has_many :dog_breeds, :through => :dogs association no Pet , de repente temos um problema. Rails não será capaz de encontrar uma associação :dog_breeds no Dog , então Rails não pode saber qual associação Dog você quer usar. Digite :source :

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

Com :source , estamos dizendo ao Rails para procurar uma associação chamada :breeds no modelo Dog (como é o modelo usado para :dogs ), e use isso.

Por favor, ajude-me a compreender a opção :source de has_one/has_many :through associação. A explicação da API do Rails faz muito pouco sentido para mim.

"Especifica o nome da associação de origem usada por has_many :through => :queries . Use-a apenas se o nome não puder ser inferido da associação. has_many :subscribers, :through => :subscriptions procurarão por :subscribers ou :subscriber na Subscription , a menos que :source seja dada. "


Deixe-me expandir esse exemplo:

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

Com este código, você pode fazer algo como Newsletter.find(id).users para obter uma lista dos assinantes da newsletter. Mas se você quiser ser mais claro e conseguir digitar Newsletter.find(id).subscribers , você deve alterar a classe Newsletter para isto:

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

Você está renomeando a associação de users para subscribers . Se você não fornecer a :source :, o Rails procurará uma associação chamada subscriber na classe Assinatura. Você tem que dizer para usar a associação de user na classe Assinatura para fazer a lista de assinantes.