2011-07-17 7 views
5

Para aquellos de ustedes que conocen los rieles y SQL bien, estoy buscando alguna buena información que pueda señalarme. Mi consulta es muy similar al ejemplo los 'Joining anidadas de las asociaciones sobre esta sección - http://guides.rubyonrails.org/active_record_querying.html#using-array-hash-of-named-associationsUnirse a asociaciones anidadas, nivel múltiple

Mis modelos (abreviado) son los siguientes,

User has_many :products # User is 'great-grandparent' 
Product has_many :posts # Product is grandparent #1 
Event has_many :posts  # Event is grandparent #2 
Post belongs_to :event 
Post belongs_to :product 
Post has_many :orders  # Post is parent 
Order belongs_to :post  # Order is great-grandchild, grandchild, & child 

Quiero recoger las órdenes de un evento para un usuario (el vendedor), y aquí está mi mejor versión.

class Order < ActiveRecord::Base 
    def self.collect_for_seller_and_event(user_id, event_id) 
    self.joins(:post => [{:product => :user }, :event]).where(:post => [{:product => {:user_id => user_id}}, {:event_id => event_id}]) 
    end 

¿Cómo debería ser esta unión?

¿Debo dividir esto en alcances en los diversos modelos en la cadena?

Sólo para demostrar que tengo un conocimiento básico aquí, he sido capaz de conseguir mi primer trabajo anidada tabla de unión va (estoy bastante entusiasmado con este logro)

BuyerFeedback 
belongs_to :order 
def self.from_past_events 
    self.joins(:order => {:post => :event}).where(:order => {:post => {:event => {:date.lt => Date.today}}}) 
end 

Respuesta

0

Tu idea de romper esto en ámbitos es bueno. Pero es posible que no tengas que conectar en cadena tanto como pensarías porque puedes unir los ámbitos de otros modelos en cualquier modelo asociado. Aquí hay un excelente artículo sobre AREL # merge, que hace que esto sea posible: http://ben.hoskings.net/2012-07-04-arel-merge-a-hidden-gem

De esta manera, puede dividir su pensamiento en trozos más pequeños. Por lo tanto, comience con Publicar y cree un alcance que le otorgue todos los productos asociados a un usuario. A continuación, cree un alcance que encadene ese alcance en uno que obtenga todas las publicaciones dado un evento. Luego solo combine este alcance en su alcance de Usuario.

Product 
    scope :for_user, ->(user) { where(user_id: user) } # The passed in `user` can be an instance of user or an id 

Post 
    scope :for_product, ->(product) { where(product_id: product) } 
    scope :for_product_given_user, ->(product, user) { for_product(product).merge(Product.for_user(user)) } 
    scope :for_product_given_user_and_event, ->(product, user, event) { for_product_given_user(product, user).where(event_id: event) } 

no estoy seguro de que soy bastante en el camino correcto aquí, ya que no puedo probar ... pero tal vez esto puede empezar. La idea es dividir las responsabilidades en fragmentos manejables y dejar que ARel haga el loco trabajo de combinación de SQL.

Cuestiones relacionadas