ruby-on-rails-3 - inverse_of - rails references
Comprender: opción de fuente de has_one/has_many a través de Rails (3)
has_one/has_many :through comprender la opción de :source de has_one/has_many :through asociación. La explicación de Rails API tiene muy poco sentido para mí.
"Especifica el nombre de asociación de origen utilizado por
has_many:through => :queries.:through => :queriessolo si el nombre no puede inferirse de la asociación.has_many :subscribers, :through => :subscriptionsbuscarán:subscriberso:subscriberenSubscription, a menos que se proporcione una:source".
A veces, quieres usar diferentes nombres para diferentes asociaciones. Si el nombre que desea utilizar para una asociación en el modelo no es el mismo que el de la asociación en el modelo :through , puede usar :source para especificarlo.
No creo que el párrafo anterior sea mucho más claro que el de los documentos, así que aquí hay un ejemplo. Supongamos que tenemos tres modelos, Pet , Dog y 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
En este caso, hemos elegido el espacio de nombre Dog::Breed , porque queremos acceder a Dog.find(123).breeds como una asociación agradable y conveniente.
Ahora, si ahora queremos crear una has_many :dog_breeds, :through => :dogs en Pet , repentinamente tenemos un problema. Rails no podrá encontrar una asociación :dog_breeds en Dog , por lo que Rails no puede saber qué asociación de Dog quieres usar. Ingrese :source :
class Pet < ActiveRecord::Base
has_many :dogs
has_many :dog_breeds, :through => :dogs, :source => :breeds
end
Con :source , le estamos diciendo a Rails que busque una asociación llamada :breeds en el modelo Dog (como ese es el modelo utilizado para :dogs ) y la usa.
La respuesta más simple:
Es el nombre de la relación en la tabla en el medio.
Permítanme ampliar ese ejemplo:
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
Con este código, puede hacer algo como Newsletter.find(id).users para obtener una lista de los suscriptores del boletín. Pero si quiere ser más claro y poder escribir Newsletter.find(id).subscribers en Newsletter.find(id).subscribers lugar, debe cambiar la clase Newsletter a este:
class Newsletter
has_many :subscriptions
has_many :subscribers, :through => :subscriptions, :source => :user
end
Está cambiando el nombre de la asociación de users a subscribers . Si no proporciona la :source Rails buscará una asociación llamada subscriber en la clase de Suscripción. Debes indicarle que use la asociación de user en la clase de Suscripción para crear la lista de suscriptores.