【问题标题】:Rails query/scope: exclude objects according to attribute of joined modelRails 查询/范围:根据连接模型的属性排除对象
【发布时间】:2012-01-15 13:58:01
【问题描述】:

我的模型如下所示:

class Ticket < ActiveRecord::Base
  has_and_belongs_to_many :tags
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :tickets
end

我希望有一个范围,可以为我提供所有未标记 unresolved 的不同 Tickets(如 tag.name != "unresolved"

我该怎么做呢?例如,如果 1 张票有 6 个标签(其中一个是 unresolved),我只想返回该票的 1 个实例,而不是范围内的 5 个。我设法做到了相反的事情(所有Tickets标记为unresolved):

scope :unresolved, :select => "DISTINCT tickets.*", :joins => :tags, :conditions => "tags.name = 'unresolved'"

【问题讨论】:

  • 你的情况中的双 == 是错字吗?
  • @iWasRobbed:因此,如果我有一张带有 6 个标签的票,它将在连接表中出现 6 次。如果我没有 DISTINCT 子句,该调用将返回 5 张门票... tags_ticket 表中未链接到名称为 "unresolved" 的标签的每个“条目”
  • @iWasRobbed:重新阅读我的场景以了解细微差别。我在数据库中有 一个 票,有 6 个标签。如果我按照您的建议在没有DISTINCT:conditions =&gt; "tags.name != 'unresolved'" 的情况下拨打电话,我将获得 same 票 5 次——每次出现在未链接到 unresolved 的连接表中一次标记。
  • 如果不编写非常复杂的自定义 SQL 查询,我认为这是不可能的。标签可能不是这个钉子的最佳锤子。将布尔“已解析”字段添加到 Ticket 模型并根据需要打开或关闭它可能更合适。查询肯定会更容易。
  • @JonGarvin 你可能是对的,使用布尔字段可能是我最好的选择

标签: mysql sql ruby-on-rails ruby


【解决方案1】:

根据您希望范围链接的灵活性,您有两种选择。

  1. 在范围内使用uniq(注意:这可能会对该范围与其他范围的链接产生负面影响,尤其是在添加更复杂的条件时):

    scope :unresolved, -&gt; { joins(:tags).where(tags: { name: 'unresolved' }).uniq }

  2. 通过includes(:tags) 使用左外连接,而不是joins(:tags) 默认使用的内连接

    scope :unresolved, -&gt; { includes(:tags).where(tags: { name: 'unresolved' }) }

【讨论】:

    猜你喜欢
    • 2018-05-25
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多