我试图将查询数量从n + 1减少到一对拥有收藏夹的黑客。
用户有很多黑客攻击。 (黑客的创造者) Hack有很多喜欢的东西 用户有很多收藏 收藏夹属于黑客和用户。
收藏夹只是一个连接表。它只包含外键,没有别的。
在hacks索引页面上,我根据给定hack和current_user是否存在收藏记录显示星形图标。
index.hmtl
- @hacks.each do |h|
- if h.favorites(current_user)
#star image
如何在' .SQL'中使用活动记录或原始SQL?方法调用急切加载相关的收藏夹?
我首先考虑获取分页黑客,获取当前用户,并查询所有拥有黑客和当前用户的收藏夹。
我对语法不确定。此外,无法从模型中调用Current_user。
更新
我尝试了这些查询
@hacks = Hack.includes(:tags, :users, :favorites).where("favorites.user_id = ?", current_user.id).references(:favorites)
我还尝试了以下内容,并且两者都没有使用.references
方法
@hacks = Hack.includes(:tags, :users, :favorites).where(favorites: { user_id: current_user.id } ).references(:favorites)
WHERE子句作用于hacks以限制hacks的类型。 但我想要的是将收藏夹限制为具有条件的收藏夹(即favorites.user_id = current_user.id)。
(毕竟,成千上万的用户可能会喜欢黑客,但客户端只关心当前用户,因此加载所有支持黑客的用户可能非常昂贵和糟糕)
如何使条件适用于急切加载的关联而不是原始模型?
答案 0 :(得分:1)
如果你有belongs_to :user
和belongs_to :hack
,那么假设你有一个"有很多通过" favorites
,hack
和user
之间的关系设置?以下是如何通过收藏夹和用户急切加载Hack。
# app/controllers/hacks_controller.b
def index
@hacks = Hack.includes(favorites: :user)
end
以上代码将运行三个查询,一个用于从hacks
中选择全部,第二个用于hacks
与favorites
之间的联接,第三个用于从users
选择全部已通过users
在第二个查询中选择了favorites
。
在单个查询中执行这些联接的另一种方法是使用joins
使用内部联接:
# app/controllers/hacks_controller.b
def index
@hacks = Hack.joins(favorites: :user)
end
使用此查询,在三个表users
,favorites
和hacks
之间只有一个内部联接查询。