Ruby on rails Rails正在加载所有记录,但仍生成N+;1查询
我使用的是Rails 4.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
事件
模型:
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个预订。