如何根据条件和当前用户急切加载关联表?

时间:2014-10-25 03:22:22

标签: sql ruby-on-rails orm rails-activerecord

我试图将查询数量从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)。

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

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

1 个答案:

答案 0 :(得分: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之间只有一个内部联接查询。