【问题标题】:Rails activerecord find objects with specific children associationsRails activerecord 查找具有特定子关联的对象
【发布时间】:2014-11-04 19:10:40
【问题描述】:

我有一个模型用户,他可以拥有许多功能:

class User << ActiveRecord::Base
  has_many :features, dependent: :destroy
end

class Feature << ActiveRecord::Base
  belongs_to :user
  # columns id, user_id, name
end

我可以为名为“feat1”和“feat2”的用户添加 2 个功能。这 2 个功能可以组合用于总共 4 种类型的用户:

  1. 用户只有feat1
  2. 用户只有feat2
  3. 用户同时拥有 feat1 和 feat2
  4. 用户既没有feat1也没有feat2

我想在用户上创建范围来确定 4 种类型的用户。

User.only_feat1
User.only_feat2
User.both_feats
User.no_feats

我一直在使用 .merge、.uniq、.joins、.includes,但似乎无法弄清楚 activerecord 的方式。

【问题讨论】:

  • 使用常规 where。 scope :name, lambda { where("(SELECT ... FROM features ... LIMIT 1) = ?", 123) }
  • @lurker 看看上面的模型。应该很明显。
  • 我将改写我的问题:特征表是否只包含两个特征?如果有两个以上,那么在这种情况下您是否不关心其他功能(feat3、feat4 等)?
  • 会有其他功能,但是这个问题,我们假设只有2个功能需要担心。

标签: mysql ruby-on-rails activerecord scope


【解决方案1】:

所以这是我的解决方案。它涉及大量原始 SQL,但它完成了工作。问题是如果我将同一个表(功能)加入到我的用户表中不止一次,那么 where 子句会被覆盖并且我不能进行多个连接。

所以为了解决这个问题,我写了很多原始 sql,它们在强制双连接表的连接上显式别名表。

scope :without_feature, ->(feat) { joins("LEFT OUTER JOIN features af ON users.id = af.user_id AND af.name = '#{feat}'").where(af: {id: nil}) }
scope :feat1, -> { joins("INNER JOIN features rs ON users.id = rs.user_id AND rs.name = 'feat1'") }
scope :feat2, -> { joins("INNER JOIN features rr ON users.id = rr.user_id AND rr.name = 'feat2'") }
scope :both_feats, -> { feat1.feat2 }
scope :only_feat1, -> { feat1.without_feature('feat2') }
scope :only_feat2, -> { feat2.without_feature('feat1') }

希望这对其他人有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多