opción de fuente de has_one / has_many a través de rieles: comprensión
-
08-10-2019 - |
Pregunta
Por favor me ayude en la comprensión de la opción :source
de asociación has_one/has_many :through
. La API explicación rieles hace muy poco sentido para mí.
"especifica el nombre de asociación fuente utilizado por
has_many
:through => :queries
. Sólo se debe usar si el nombre no puede deducirse a partir de la asociación. voluntadhas_many :subscribers, :through => :subscriptions
buscar ya sea:subscribers
o:subscriber
enSubscription
, a no ser que se le da un:source
. "
Solución
A veces, se desea utilizar diferentes nombres para diferentes asociaciones. Si el nombre que desea utilizar para una asociación en el modelo no es el mismo que el assocation en el modelo :through
, se puede utilizar para especificar que :source
.
No creo que el párrafo anterior es más más claro que el de los documentos, por lo que aquí es un ejemplo. Asumamos 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 optado por espacio de nombres del Dog::Breed
, porque queremos Dog.find(123).breeds
acceso como un agradable y cómodo asociación.
Ahora, si ahora queremos crear una asociación has_many :dog_breeds, :through => :dogs
en Pet
, de repente tenemos un problema. Raíles no serán capaces de encontrar una asociación :dog_breeds
en Dog
, por lo que los carriles no puede saber posiblemente , que Asociación Dog
que desea utilizar. Introduzca :source
:
class Pet < ActiveRecord::Base
has_many :dogs
has_many :dog_breeds, :through => :dogs, :source => :breeds
end
Con :source
, estamos contando rieles para buscar una asociación llamada :breeds
en el modelo Dog
(ya que es el modelo utilizado para :dogs
), y el uso que.
Otros consejos
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, se puede hacer algo como Newsletter.find(id).users
para obtener una lista de suscriptores del boletín. Pero si quieres ser más claro y ser capaz de escribir Newsletter.find(id).subscribers
lugar, debe cambiar la clase a este boletín:
class Newsletter
has_many :subscriptions
has_many :subscribers, :through => :subscriptions, :source => :user
end
Se está cambiando el nombre a la asociación users
subscribers
. Si usted no proporciona la :source
, rieles buscará una asociación llamada subscriber
en la clase de suscripción. Tienes que decirle a utilizar la asociación user
en la clase de suscripción para hacer la lista de suscriptores.
respuesta más simple:
Es el nombre de la relación en la tabla en el medio.