加入嵌套关联,多层次

时间:2011-07-17 20:37:30

标签: ruby-on-rails join grandchild

对于那些了解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

1 个答案:

答案 0 :(得分:1)

你想把它分解成范围很好。但是你可能没有像你想象的那样连接菊花链,因为你可以将范围从其他模型合并到任何相关的模型中。这是关于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合并工作。