2011-07-17 51 views
5

對於那些瞭解rails和sql的人來說,我正在尋找一些可以指向我的良好信息。我的查詢是非常相似的「加入嵌套協會」例如,在本節 - http://guides.rubyonrails.org/active_record_querying.html#using-array-hash-of-named-associations加入嵌套關聯,多級

我的模型(簡稱)如下,

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 

我想從一個事件收集訂單用戶(賣方),這是我的最佳解決方案。

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 

這個連接應該是什麼樣子?

我應該把它分解成菊花鏈上各種模型的範圍嗎?

只是爲了表明我這裏有一個基本的瞭解,我已經能夠得到我的第一份工作嵌套連接表中去(我對這個成績很興奮)

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

回答

0

你的點子突破這進入範圍是好的。但是,您可能不需要按照您的想法進行菊花鏈連接,因爲您可以將其他模型的範圍合併到任何關聯的模型中。這裏有一篇關於ARel#merge的偉大文章,它使這個美好的事物成爲可能:http://ben.hoskings.net/2012-07-04-arel-merge-a-hidden-gem

這樣,你可以將你的想法分解成更小的塊。因此,從Post開始,創建一個範圍,讓您獲得給予用戶的所有關聯產品。然後創建一個範圍,將該範圍鏈接到可以讓所有帖子發出事件的範圍。然後將這個範圍合併到你的用戶範圍中。

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) } 

因爲我無法測試,所以我不確定我在這裏的正確軌道上......但也許這可以讓你開始。這個想法是將責任分解成可管理的塊,讓ARel執行瘋狂的SQL合併工作。