简体   繁体   English

Rails 4:使用.includes(:association)时修改热切负载查询

[英]Rails 4: Modify eager load query when using .includes(:association)

I have two models: 我有两个模型:

class User < ActiveRecord::Base
  has_many :purchases

  # Perform joins and attach some calculations to the User object
  scope :add_stats, -> { group("users.id").joins(:purchases).select("users.*, SUM(purchases.price) AS total_purchases") }
end

class Purchase < ActiveRecord::Base
  belongs_to :user
end

The add_stats scope represents heavy calculations attached to the User objects. add_stats范围表示附加到User对象的大量计算。 So if I want to get all User objects with stats, I just write User.all.add_stats . 因此,如果要获取具有统计信息的所有User对象,只需编写User.all.add_stats

So far so good. 到现在为止还挺好。 Now I want to fetch some Purchase objects and eager load the User s with stats as well. 现在,我想获取一些Purchase对象,并也希望向User加载统计信息 I've tried this: 我已经试过了:

belongs_to :user, -> { add_stats }

But then when Rails eager load the users, it seems to remove .group("user.id").joins(:purchases) and complain on purchases.price - "purchases table unknown". 但是,当Rails急于加载用户时,似乎删除了.group("user.id").joins(:purchases)并抱怨purchases.pricepurchases.price -“购买表未知”。 So the .select() is the only thing preserved from the scope. 因此, .select()是唯一保留在范围之外的东西。

How do I apply a scope (with working .group().joins() ) to the eager load query of all included belongs_to :user objects? 我如何将范围(具有可工作的.group().joins() )应用于所有包含的belongs_to :user对象的急切负载查询?

i just tried it in my rails4 app and it works 我刚刚在我的rails4应用程序中尝试过

class User < ActiveRecord::Base
  scope :add_stats, -> { group("users.id").joins(:events).select("users.*, SUM(events.id) AS total_events") }

class Event
  belongs_to :user, -> { add_stats }

in rails console 在Rails控制台中

Event.includes(:users).first.user.total_events
Reloading...
  Event Load (0.1ms)  SELECT "events".* FROM "events" WHERE "events"."label" = 'hamburg' ORDER BY "events"."id" ASC LIMIT 1
  Participant Load (0.3ms)  SELECT "participants".* FROM "participants" WHERE "participants"."event_id" IN (2)
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2, 3, 4, 8, 10, 11, 12, 14, 16, 17, 18, 19, 20)
  User Load (0.3ms)  SELECT users.*, SUM(events.id) AS total_events FROM "users" INNER JOIN "events" ON "events"."user_id" = "users"."id" WHERE "users"."id" = ? GROUP BY users.id ORDER BY "users"."id" ASC LIMIT 1  [["id", 2]]
=> 68

Event.first.user.total_events
Reloading...
  Event Load (0.2ms)  SELECT "events".* FROM "events" WHERE "events"."label" = 'hamburg' ORDER BY "events"."id" ASC LIMIT 1
  User Load (0.2ms)  SELECT users.*, SUM(events.id) AS total_events FROM "users" INNER JOIN "events" ON "events"."user_id" = "users"."id" WHERE "users"."id" = ? GROUP BY users.id ORDER BY "users"."id" ASC LIMIT 1  [["id", 2]]
=> 68

i guess that this is not what you want, as this does not use the scope for the include. 我想这不是您想要的,因为这没有使用包含的作用域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM