我有一个应用程序,可以帮助网球运动员找到对手。我有以下模型:
TennisMatch (id, description, user_id)
User (id, name, type)
AvailabilityWindow(tennis_match_id, start_time, end_time, requester_id)
用户可以使用该应用程序发布网球比赛列表。作为其中的一部分,他们必须提供一些可用性。例如,如果他们想在周六上午8点到10点之间比赛。这将创建一个可用性记录作为创建匹配的一部分:
AvailabilityWindow.new(tennis_match_id: 1, start_time: '8am Saturday', end_time: '10am Saturday', requester_id: user.id)
如果其他玩家看到列表,他们可以接受并同意在建议的时间和日期玩游戏。他们还可以建议其他可用性,这将导致向AvailabilityWindow表中添加一条记录。因此一场网球比赛可以有来自多个不同用户的多个availability_window记录。
我的问题是:我需要一个页面,列出所有网球比赛以及创建列表的用户建议的可用性(忽略其他用户建议的可用性)。例如
class TennisMatch < ApplicationRecord
has_many :availability_windows
end
class TennisMatchController < ApplicationController
def index
@tennis_matches = TennisMatch.all
end
end
index.html.erb:
<% @tennis_matches.each do |match| %>
<h4><%= match.description %>
<% match.availability_windows.where(requester_id: match.user_id).each do |window| %>
<p><%= window.start_time %>-<%= window.end_time %>
<% end %>
<% end %>
这是可行的,但会受到n+1的影响,因为它会对每个匹配项进行查询以获得可用性。如何预加载此数据以避免n+1?
我们还假设,简单地在控制器中预加载所有窗口(例如TennisMatch.all.includes(:availability_windows)
),并在视图中的集合上执行select(&block)
以避免查询是不可行的。
发布于 2021-04-02 16:27:30
试试这个:
class TennisMatchController < ApplicationController
def index
matches = TennisMatch.all
user_ids = matches.pluck(:user_id)
@tennis_matches = matches.includes(:availability_windows).
where(availability_windows: { user_id: user_ids })
end
end
然后在index.html.erb中:
<% @tennis_matches.each do |match| %>
<h4><%= match.description %>
<% match.availability_windows.each do |window| %>
<p><%= window.start_time %>-<%= window.end_time %>
<% end %>
<% end %>
https://stackoverflow.com/questions/66921796
复制