Carriles: Con los modelos A has_many B belongs_to C retorno A, donde B pertenece a C y B es la más reciente creación de una determinada?
-
20-09-2019 - |
Pregunta
tengo tres modelos A, B, y C, donde A has_many B
; B belongs to C
y B has a created_on timestamp
. C has_many A a B.
Quiero volver todos A, donde A tiene un B que pertenece a C y B, donde B es la más reciente creación para que A.
I puede hacer esto con un bucle método. ¿Es posible hacerlo únicamente con named_scopes ?, o es alguna otra manera elegante / eficiente?
Según la petición para ejemplos del mundo real (TM) A, B y C puede ser imaginado como, por ejemplo, animales domésticos (A), PetsName (B), y los nombres de (C). PetsNames se les da a los animales domésticos en un momento determinado, y cualquier Nombre dado se puede dar a muchos animales domésticos. Cualquier animal doméstico puede tener muchos nombres (a: a través de la relación). Para un nombre dado quiero todos de los Animales en la que ese nombre es el Petname de más reciente creación para que el PET. La llamada puede ser algo como @name.pets.most_recently_named_as
Solución
La forma de hacer esto Carriles es un ámbito con nombre en las mascotas.
Algo como esto:
class Pets
has_many :pet_names
has_many :names, :through => :pet_names
named_scope :with_current_name, lambda {|name|
{ :joins => "JOIN (pet_names pna, names) " +
"ON (pna.pet_id = pets.id AND pna.name_id = names.id) " +
"LEFT JOIN pet_names pnb " +
"ON (pnb.pet_id = pets.id AND pna.created_at < pnb.created_at)",
:conditions => ["pnb.id IS NULL AND names.id = ? ", name]
}
}
end
Pets.with_current_name(@name)
@name.pets.with_current_name(@name)
Para mantener el nombre Centric cosas que siempre se podía definir un método en C / nombre que invoca el ámbito con nombre.
Siempre se puede hacer
class Name < ActiveRecord::Base
has_many :pet_names
has_many :pets, :through => :pet_names
def currently_named_pets
Pets.with_current_name(self)
end
end
y
@name.currently_named_pets
Es una muy complicada unión. Lo cual es un indicador de que probablemente debería debería replantearse la forma en que almacena esta información. ¿Por qué es tan importante que los nombres de estar en una mesa separada?
Usted puede ser mejor hacer algo como esto:
Después de añadir columnas name
y old_name
para mascotas:
class Pet < ActiveRecord::Base
serialize :old_name, Array
def after_initialization
@old_name ||= []
end
def name= new_name
self.old_name << new_name
self.name = new_name
end
named_scope :with_name, lambda {|name|
{ :conditions => {:name => name}}
}
end