【问题标题】:Rails ActiveRecord join table with array of ids without n+1 requestRails ActiveRecord 连接表,带有 id 数组,没有 n+1 请求
【发布时间】:2020-01-13 10:44:07
【问题描述】:

我需要从一组 Id 中检索记录,例如: User.where(id: [1,1,2]) 但问题是我只从这个请求中得到了两条记录,我想让 [#User id:1] 翻倍,因为数字 1 在数组中出现了两次。 我可以做一个 n+1 请求,但这不是很乐观...

【问题讨论】:

  • 所以这个查询的编写方式,你只会得到每个唯一用户一次。但是,一旦执行此查询,rails 会缓存此结果,并且引用 id=1 的 User 不会运行额外的查询(这取决于您如何编写查询以及如何使用结果,但这是可能的以及 rails 如何一般解决N+1问题)。更详细地解释为什么您需要这种方式,例如查找用户的东西...然后我们可以帮助您展示 rails 方式

标签: ruby-on-rails postgresql activerecord


【解决方案1】:

如果您想要一个简单的数据库查询,您应该遵循的步骤:

  • 根据数组创建哈希,如:

    hash = {1=>2, 2=>1, 3=>1, 4=>3} for [1, 1, 2, 3, 4, 4, 4]

  • 简单查询:

    users = User.where(id: your_array.uniq)

    #你的情况

    users = User.where(id: [1, 1, 2].uniq) # because [1, 1, 2].uniq => [1, 2]

  • 制作你的数组:

  the_way_i_want = []
  hash.each do |key, value|
    value.times do
      the_way_i_want.push users.where(id: key)
    end

  end
  • 设置 users = the_way_i_want 并返回
 users =  the_way_i_want

粗略但会节省数据库访问权限:-)

【讨论】:

    【解决方案2】:

    如何创建 1 个对 DB 的请求,然后格式化您的数据

    user_ids = [1, 1, 2] # this you have
    
    • 创建一个哈希{ user_id: user_record, .... }

      users = User.where(id: user_ids).map { |u| [u.id, u]}.to_h

    • 然后创建一个包含所有你想要的记录的数组

      user_ids.map do |u_id|
        users[u_id]
      end
      

    【讨论】:

      猜你喜欢
      • 2020-06-02
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 2011-09-24
      • 1970-01-01
      • 2013-10-30
      相关资源
      最近更新 更多