has_many关系重新加载父级

时间:2013-07-12 18:42:59

标签: ruby-on-rails performance activerecord

我有这样的关系:

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会运行查询?

在回复评论时:查询未标记为CACHED:

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

2 个答案:

答案 0 :(得分:1)

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

您似乎可以使用inverse_of选项来保留相同的实例:

  

没有:inverse_of m和f.man将是同一对象的不同实例(f.man再次从数据库中拉出)。使用这些新的:inverse_of选项m和f.man在内存实例中是相同的。

答案 1 :(得分:0)

与Michael Szyndel同意,模型缓存可能会在开发中被禁用,我相信您也希望更新您的代码,如下所示

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

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

希望它有所帮助..