如何急切加载具有条件和当前用户的关联表?

Posted

技术标签:

【中文标题】如何急切加载具有条件和当前用户的关联表?【英文标题】:How to eager load associated table with conditions and current user? 【发布时间】:2014-10-25 03:22:21 【问题描述】:

我正在尝试将查询数量从 n+1 减少到几个有收藏夹的黑客。

用户有很多技巧。 (黑客的创造者) 哈克有很多最爱 用户有很多收藏夹 收藏夹属于黑客和用户。

Favorites 只是一个连接表。它只包含外键,没有别的。

在 hacks 索引页面上,我根据给定的 hack 和 current_user 是否存在最喜欢的记录显示一个星形图标。

index.hmtl

- @hacks.each do |h| 
  - if h.favorites(current_user)
    #star image

如何在“.SQL”方法调用中使用活动记录或原始 SQL 来预先加载相关收藏夹?

我想先获取分页hack,获取当前用户,然后查询所有拥有hack的收藏夹和当前用户。

我不确定语法。也不能从模型中调用 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 子句作用于 hack 以限制 hack 的类型。 但我想要的是将收藏夹限制为具有条件的收藏夹(即收藏夹.user_id = current_user.id)。

(毕竟,成千上万的用户可能会喜欢一个 hack,但客户端只关心当前用户,因此加载所有喜欢该 hack 的用户可能会非常昂贵和糟糕)

如何使条件适用于预先加载的关联而不是原始模型?

【问题讨论】:

【参考方案1】:

如果您有belongs_to :userbelongs_to :hack,那么假设您在favoriteshackuser 之间建立了“多通”关系设置是否安全?以下是您如何使用收藏夹和用户急切加载 Hack。

# app/controllers/hacks_controller.b

def index
  @hacks = Hack.includes(favorites: :user)
end

上面的代码将运行三个查询,一个是从hacks 中全选,第二个是在hacksfavorites 之间进行连接,第三个是从users 中全选,而users 在第二个中已经被选中通过favorites查询。

在单个查询中执行这些连接的另一种方法是使用 joins 的内部连接:

# app/controllers/hacks_controller.b

def index
  @hacks = Hack.joins(favorites: :user)
end

使用此查询,三个表之间只有一个内连接查询,usersfavoriteshacks

【讨论】:

是的,应该是用户。通过收藏夹。但我也有user has many hacks 用于黑客的创建者。对于相同的两个模型,你可以有很多,并且有很多通过吗?你的回答是假设,还是改变了事情? 我尝试使用.eager_load 进行单个查询。 我还有其他条件,比如tagged_with(params[:tag])(这是acts_as_taggable_on gem提供的自定义范围方法)我也在使用分页,即kaminari(没关系),它附加了@ 987654341@ 我认为运行条件和分页会更有效,然后仅在这些 hack 上查询相关的收藏夹和用户。或者它是否为每个分页页面请求执行单个查询,并且没关系?很抱歉提出一堆问题。请随意回答您希望的多或少。不用担心=] @gwho,我很抱歉说我对 kaminari 还不熟悉,我建议您尝试第二个查询。您是否在 Rails 控制台中尝试过它们?这会更好地解释。 我的意思是一般情况下返回子集的其他条件,以及调用包含时是否有所不同。

以上是关于如何急切加载具有条件和当前用户的关联表?的主要内容,如果未能解决你的问题,请参考以下文章

急切加载“二级”关联对象时出现问题

预加载 has_many 与动态条件的关联

使用 HQL 急切加载嵌套关联

急切加载与加入获取相同吗?

具有嵌套关联条件检查的has_many范围

Sequelize:急切加载和排序(在父表上)