【问题标题】:Rails Active Record Query - multiple values condition (AND instead of OR)Rails Active Record 查询 - 多值条件(AND 而不是 OR)
【发布时间】:2014-11-03 19:01:11
【问题描述】:

我在 Rails 4.1 应用程序中使用acts_as_taggable_on gem。我正在使用范围基于标签或多个标签进行搜索。当多个标签作为参数给出时,我希望搜索只返回包含所有标签的标记项目。目前,我的范围返回包含至少一个标签(tag_a OR tag_b OR tag_c)的标记项目。我想要一个范围,而不是 AND 条件(tag_a AND tag_b AND tag_c)。

示例

document_a_tags = ['programming', 'ruby']
document_b_tags = ['programming', 'python']

class User < ActiveRecord::Base
  has_many :documents, dependent: :destroy
  scope :with_fields, proc { |fields|
    if fields.reject!(&:empty?).present?
      joins(documents: [{ taggings: :tag }]).where(tags: { slug: fields })
    end
  }
end

class Document < ActiveRecord::Base
  acts_as_taggable
  belongs_to :user
end

目前,如果搜索参数包括programmingruby,则返回document_a 和document_b。我想要的是一个范围,如果搜索参数包括 programmingruby,则只会返回 document_a。

【问题讨论】:

  • 你试过了吗:tagged_with?例如:Item.joins(documents: [{ taggings: :tag }]).tagged_with(fields)?
  • @User089247 感谢您的建议。这给了我一个错误,因为标签在 Document 模型上,而不是 User 模型上:NoMethodError (undefined method tagged_with' for #<:activerecord_relation>
  • @diask2:我没有写成User...,而是Item..,但是,必须了解示例代码和实际代码之间的区别,并使用该想法使解决方案有效。

标签: ruby-on-rails activerecord


【解决方案1】:

鉴于 mysql 的工作方式,我认为这很难在单个活动记录查询中完成。

连接为连接到您的条目的每个标签添加一行,并且条件一次仅应用于一行。也就是说,不能通过条件排除结果中的某些其他行来排除行。

我认为可以编写一些复杂的递归查询,将不确定数量的列添加到结果中并将条件应用于它们。但我认为简单地使用您当前的范围然后在 ruby​​ 代码中丢弃没有所有标签的条目会更容易和更高效。

编辑: 这可以在您使用的 gem 中完成。看:

User.tagged_with(["awesome", "cool"], :match_all => true)

【讨论】:

  • 谢谢。然而,这个范围在用户模型上,但它是文档模型(用户 has_many :documents)有标签。所以如果我尝试 tagged_with 我得到NoMethodError (undefined method 'tagged_with' for #&lt;User::ActiveRecord_Relation:
  • 这只是从他们的文档中复制的一个示例。它必须根据您的设置进行调整
  • 谢谢,你说得真好。
猜你喜欢
  • 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
相关资源
最近更新 更多