【问题标题】:active record returning all relations of an object that are archived: false返回已归档对象的所有关系的活动记录:false
【发布时间】:2021-07-28 02:35:27
【问题描述】:

在 ruby​​ on rails 中,我有一个 users 模型,这个用户可以有一个 potential_match 作为导师或被指导者。这些潜在匹配可以归档:true 或归档 false,我无法让这个查询为我的一生工作。

scope :potential_matches,
        -> {
          joins('LEFT JOIN potential_matches ON potential_matches.mentor_id = users.id OR potential_matches.mentee_id = users.id')
          .where('potential_matches.archived = false')
          .where('users.active = true')
        }

总是失败的测试如下:

describe '.potential_matches' do
    it 'returns only active potential matches' do
      user1 = FactoryBot.create(:user)
      user2 = FactoryBot.create(:user)
      user3 = FactoryBot.create(:user)
      user4 = FactoryBot.create(:user)
  
      pot_match1 = FactoryBot.create(:potential_match, {mentor_id: user1.id, mentee_id: user2.id})
      pot_match2 = FactoryBot.create(:potential_match, {mentor_id: user2.id, mentee_id: user1.id})
      pot_match3 = FactoryBot.create(:potential_match, {mentor_id: user3.id, mentee_id: user4.id, archived: true})
      pot_matches = User.potential_matches
      expect(pot_matches).to include(pot_match1, pot_match2)
      expect(pot_matches).not_to include(pot_match3)
    end
  end

我在这里错过了什么?它快把我逼疯了。

【问题讨论】:

  • 检查数据库表中的值,尤其是“potential_matches”,检查存档值是否存在。
  • 这段代码毫无意义。我猜测范围是用户模型,因此它将返回用户记录的集合 - 而不是潜在的匹配。而且我无法理解您正在尝试做什么,而这不能仅通过PotentialMatch.where(archived: false) 来实现。为什么这个代码甚至在 User 模型中?
  • 只有在实例方法和您获得特定用户的潜在匹配项时才有意义。您可能想重新开始并向我们解释您真正想要实现的目标。
  • 是的。我意识到查询不返回潜在的匹配大声笑。工作 15 小时后我很累。谢谢你的回答。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

如果您想要获取没有任何存档匹配的用户,最简单的方法是创建子查询:

class User < ApplicationRecord
  def self.potential_matches
    pm = PotentialMatch.arel_table
    id = arel_table[:id]
    where(
      PotentialMatch.where(
        pm[:mentor_id].eq(id).or(pm[:mentee_id].eq(id))
      ).where(archived: true).arel.exists.not
    ).where(active: true)
  end
end

这会生成以下 SQL:

SELECT "users".*
FROM   "users"
WHERE  NOT ( EXISTS (SELECT "potential_matches".*
                     FROM   "potential_matches"
                     WHERE  ( "potential_matches"."mentor_id" = "users"."id"
                               OR "potential_matches"."mentor_id" =
                            "users"."id" )
                            AND "potential_matches"."archived" = ?) )
       AND "users"."active" = ? /* loading for inspect */
LIMIT  ? 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    相关资源
    最近更新 更多