如何在where子句中传递哈希值?

3

我正在列出产品,希望能够传递哈希作为我的where条件,这样我就可以执行以下操作:

filter = {}
filter[:category_id] = @category.id
filter[:is_active] = true

@products = Products.where(filter)

有没有办法以某种方式完成这个操作?

我还需要在where子句中添加类似于以下内容的东西:

WHERE price > 100

我该如何将它添加到筛选器中?

我想这么做的原因是因为在UI界面上,我会有一组可选的筛选器,然后我会在控制器中使用if语句来设置每个筛选器。

2个回答

3
您可以像之前一样将散列传递给 where

filter = {
  category_id: @category_id,
  is_active: true
}

@products = Product.where(filter)

仅使用哈希仅适用于相等性(例如category_id = 123),因此您不能将诸如price > 100之类的内容放在其中。要添加该条件,请将另一个where添加到链中:

@product = Product.where(filter).where('price > 100')

或者...

@product = Product.where(filter)

if params[:min_price]
  @product = @product.where('price > ?', min_price)
end

我可以根据“if子句”添加其他where子句吗?例如,如果param[:abc]为真,则将其添加到where子句中? - Blankman
是的。我已经修改了我的答案中的最后一个示例,以显示您可以如何执行该操作。 - Jordan Running

1
你可以通过作用域来进行一些有趣的操作:编写一个作用域,它实际上是一个小型谓词构建器,对字符串进行清理和模式匹配,并将其他标量类型委托给标准谓词构建器。例如:
# app/models/concerns/searchable.rb
module Searchable
  extend ActiveSupport::Concern

  included do
    scope :search, ->(params) {
      params.inject(self) do |rel, (key, value)|
        next rel if value.blank?
        case value
        when String
          rel.where arel_table[key].matches '%%%s%%' % sanitize_sql_like(value)
        when Range, Numeric, TrueClass, FalseClass
          rel.where key => value
        else
          raise ArgumentError, "unacceptable search type"
        end
      end
    }
  end
end

# app/models/product.rb
class Product < ApplicationRecord
  include Searchable

然后你可以。
filter = { name: 'cheese', description: 'aged', age: 42.. }

Product.search(filter) #=> SELECT "products".* FROM products WHERE "products"."name" ILIKE '%cheese%' AND "products"."description" ILIKE '%aged%' AND "products"."age" >= 42

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接