【发布时间】:2015-08-16 18:42:00
【问题描述】:
给定一个允许用户邀请其他用户参加活动的系统:
class Event
has_many :invites
end
class User
has_many :invites
has_many :invited, inverse_of: :inviter, foreign_key: :inviter_id, class_name: 'Invite'
end
class Invite
belongs_to :user
belongs_to :event
belongs_to :inviter, class_name: 'User'
has_many :invited, -> (invite) { where(invites: { event_id: invite.event_id }) }, through: :user, class_name: 'Invite'
end
我正在生成一个简单的报告,其中显示了某个活动的所有邀请。我正在尝试修改报告以包含一些可以针对示例事件的invited 执行的操作:
<%- event.includes(:user).each do |invite| -%>
<%= invite.user.name %>
<%- invite.invited.each do |other| -%>
<%= link_to invite_path(other), method: :destroy do %>
...
<% end %>
<%- end -%>
<%- end -%>
这工作正常,但有一个 N+1 问题。尝试预先加载自定义关联会给出:
弃用警告:关联范围“已邀请”取决于实例(范围块接受参数)。预加载发生在创建单个实例之前。这意味着没有实例被传递到关联范围。这很可能会导致损坏或不正确的行为。这些关联的加入、预加载和预加载已被弃用,将来将被删除。
有没有办法像这样进行急切加载?是否可以给has_many 提供其他提示而不是使用实例变量?
【问题讨论】:
-
我正在尝试了解您要获取的内容。来自同一用户的邀请参加同一活动?
-
@D-Side 是的,试图获得每个受邀用户的其他邀请。实际的例子要复杂得多,但我尽量简化了这个问题。
-
嗯,您正在获取每个邀请的邀请集合。这将是一个痛苦,因为它需要一个自连接,而这又需要对所涉及的表实例之一进行别名。所以,Arel 的使用似乎是必须的。
-
您是否需要按... 嗯... 邀请对邀请进行分组?我的意思是,一个奇怪的排序列表是否足以满足您的需求,还是您需要按相关邀请整齐地分组?
标签: ruby-on-rails ruby