Ruby on rails Rails正在加载所有记录,但仍生成N+;1查询

Ruby on rails Rails正在加载所有记录,但仍生成N+;1查询,ruby-on-rails,eager-loading,Ruby On Rails,Eager Loading,我使用的是Rails 4.1,在快速加载工作时遇到了一个非常基本的问题 我将一个复杂的程序简化为一个非常基本的事件、用户和预订示例: 事件模型: class Event < ActiveRecord::Base has_many :reservations def reserved?(user) reservations.where(user: user).present? end end class User < ActiveRecord::Base h

我使用的是Rails 4.1,在快速加载工作时遇到了一个非常基本的问题

我将一个复杂的程序简化为一个非常基本的事件、用户和预订示例:

事件
模型:

class Event < ActiveRecord::Base
  has_many :reservations

  def reserved?(user)
    reservations.where(user: user).present?
  end
end
class User < ActiveRecord::Base
  has_many :reservations
end
class Reservation < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
end
预订
型号:

class Event < ActiveRecord::Base
  has_many :reservations

  def reserved?(user)
    reservations.where(user: user).present?
  end
end
class User < ActiveRecord::Base
  has_many :reservations
end
class Reservation < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
end
我的
视图/events/index.html.erb
视图:

<% @events.each do |event| %>
  <p>Event: <%= event.name %><br>
  Reserved?: <%= event.reserved?(@user) %><br></p>
<% end %>

正如您所看到的,rails正确地加载了my events的所有预订。但是,在
reserved?(user)
调用期间,它会继续再次查询数据库。我做错了什么?谢谢。

您的
保留?
方法使用
保留
关联的
where
方法。
where
方法是用于构建SQL查询的ARel方法。对
where
方法的结果调用
present?
,将导致执行查询

要避免在
保留?
中执行另一个数据库查找,应改用Ruby收集方法,例如:

def reserved?(user)
  reservations.select { |reservation| reservation.user == user }.empty?
end
或者,对于更简洁的版本(有人将此添加为注释,但看起来可能已被删除):


我同意这个解决方案,但这可能是一件坏事。如果您每个活动有1000个预订,则此解决方案不太理想。还有
reservations.any吗?{| reservation | reservation.user==user}
它更优化了。非常感谢。除了在不生成SQL查询的情况下对
where
作用域使用collection方法外,还有其他好方法吗?e、 g.重写
reservations.late\u cancelled.map(&:user\u id)。包括?(user.id)
scope:late\u cancelled,->{加入(:事件)。其中(“reservations.cancelled\u at>(events.starts\u at-events.late\u cancel\u window*INTERVAL'1秒'))
我有很多作用域,我将它们链接在一起,并真正享受Rails的这种灵活性。德亨纳:同意急于加载的危险;在我的特定应用程序中,事件限制为每个事件大约20个预订。