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

时间:2013-10-06 16:20:47

标签: ruby-on-rails ruby activerecord ruby-on-rails-4

我有两种模式:

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

add_stats范围表示附加到User对象的大量计算。因此,如果我想获取包含统计信息的所有User个对象,我只需编写User.all.add_stats

到目前为止一切顺利。现在我想获取一些Purchase个对象,并急切加载User s 和stats 。我试过这个:

belongs_to :user, -> { add_stats }

但是当Rails急切加载用户时,似乎删除.group("user.id").joins(:purchases)并在purchases.price上抱怨 - “购买表格未知”。所以.select()是范围内唯一保留的东西。

如何将范围(包含工作.group().joins())应用于所有包含的belongs_to :user对象的预先加载查询?

1 个答案:

答案 0 :(得分:0)

我刚刚在我的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 }
在rails console中

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

我猜这不是你想要的,因为这不包括include的范围。