0

我有这样的 has_many 关系:

class Event < ActiveRecord::Base 
    has_many :event_rows
    ...
end
class EventRow < ActiveRecord::Base
    belongs_to :event
    ...
end

当我运行下面的代码片段时,它显示了 36 个查询:

@events = Event.where("date = ?", @date).all
@events.each do |e|
    first = e.event_rows.first
    first.event
end

当我运行这个片段时,我只得到 19 个查询

@events = Event.where("date = ?", @date).all
@events.each do |e|
    first = e.event_rows.first
    first.event = e # forcing the parent
    first.event
end

我做错了什么,或者每次 EventRow 要求它的事件时,rails 都会运行一个查询?

回应评论:查询未标记为缓存:

SQL (0.7ms)[0m  SELECT "event_rows"."id" AS t0_r0, "event_rows"."event_id" ... WHERE "event_rows"."event_id" = 1 LIMIT 1
Event Load (0.6ms)[0m  [1mSELECT "events".* FROM "events" WHERE "events"."id" = 1 LIMIT 1[0m
SQL (3.2ms)[0m  SELECT "event_rows"."id" AS t0_r0, "event_rows"."event_id" ... WHERE "event_rows"."event_id" = 2 LIMIT 1
Event Load (0.5ms)[0m  [1mSELECT "events".* FROM "events" WHERE "events"."id" = 2 LIMIT 1[0m
4

2 回答 2

1

我偶然发现了问题的答案。

看来您可以使用inverse_of选项来保持相同的实例:

如果没有 :inverse_of m 和 f.man 将是同一对象的不同实例(f.man 再次从数据库中提取)。有了这些新的 :inverse_of 选项,m 和 f.man 在内存实例中是相同的。

于 2013-08-27T21:29:31.407 回答
0

同意 Michael Szyndel 的观点,模型缓存可能在开发中被禁用,我相信你也想更新你的代码如下,

@events = Event.includes(:event_rows).where(date: @date)
@events.each do |e|
    # your code
end

我认为您不需要all,这里重要的是包括哪些会急切加载 event_rows。

希望它会有所帮助..

于 2013-07-12T20:00:19.687 回答