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
4

1 に答える 1

1

これをスコープに分割するというあなたのアイデアは良いです。ただし、他のモデルのスコープを関連付けられたモデルにマージできるため、思ったほどデイジー チェーン接続する必要はありません。ARel#merge に関するすばらしい記事を次に示します。これにより、この素晴らしいことが可能になります

こうすることで、思考を小さな塊に分割することができます。したがって、Post から始めて、特定のユーザーに関連付けられたすべての製品を取得するスコープを作成します。次に、そのスコープを 1 つのイベントにチェーンするスコープを作成し、イベントを指定してすべての投稿を取得します。次に、このスコープを User スコープにマージします。

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 マージ作業を行わせることです。

于 2013-08-23T13:15:05.870 に答える