我正在使用 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
我的事件 Controller
:
def index
@events = Event.includes(:reservations).all
@user = User.find(1)
end
我的views/events/index.html.erb
View :
<% @events.each do |event| %>
<p>Event: <%= event.name %><br>
Reserved?: <%= event.reserved?(@user) %><br></p>
<% end %>
我创建了一个用户和三个事件。事件索引页的结果服务器日志
:
Started GET "/events" for 127.0.0.1 at 2014-12-03 11:26:20 +0800
Processing by EventsController#index as HTML
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Event Load (0.1ms) SELECT "events".* FROM "events"
Reservation Load (0.2ms) SELECT "reservations".* FROM "reservations" WHERE "reservations"."event_id" IN (1, 2, 3)
Reservation Load (0.1ms) SELECT "reservations".* FROM "reservations" WHERE "reservations"."event_id" = ? AND "reservations"."user_id" = 1 [["event_id", 1]]
Reservation Load (0.0ms) SELECT "reservations".* FROM "reservations" WHERE "reservations"."event_id" = ? AND "reservations"."user_id" = 1 [["event_id", 2]]
Reservation Load (0.1ms) SELECT "reservations".* FROM "reservations" WHERE "reservations"."event_id" = ? AND "reservations"."user_id" = 1 [["event_id", 3]]
Rendered events/index.html.erb within layouts/application (10.0ms)
Completed 200 OK in 76ms (Views: 68.7ms | ActiveRecord: 1.3ms)
如您所见,rails 正确地预先加载了我的事件的所有预订。但是,它会在 reserved?(user)
调用期间再次查询数据库。我究竟做错了什么?谢谢。
最佳答案
您的 reserved?
方法使用 reservations
关联的 where
方法。 where
方法是一个 ARel 方法,用于构建 SQL 查询。对 where
方法的结果调用 present?
会导致执行查询。
为了避免在 reserved?
中进行另一次数据库查找,您应该使用 Ruby 集合方法,例如:
def reserved?(user)
reservations.select { |reservation| reservation.user == user }.empty?
end
或者,对于更简洁的版本(有人将其添加为评论,但看起来可能已被删除):
def reserved?(user)
reservations.map(&:user_id).include?(user.id)
end
关于ruby-on-rails - Rails 急于加载所有记录但仍生成 N+1 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27263199/