【问题标题】:Facet search with dynamic ransackers使用动态洗劫者进行构面搜索
【发布时间】:2015-10-28 16:38:16
【问题描述】:

我正在尝试使用 Rails 创建一个通用的产品目录应用程序,为了获得具有不同属性的不同类型的产品,我将产品属性抽象到它们自己的表中,并在产品和存储价值。

-------------   --------------------
|products   |   |product_properties|   ------------
|-----------|   |------------------|   |properties|
|name       |---|value             |---|----------|
|description|   |product_id        |   |name      |
|etc...     |   |property_id       |   ------------
-------------   --------------------

例如,产品可能有一个宽度属性(将存储在属性表中以便可以重复使用),而宽度的值将存储在 product_properties 表中,其中包含将属性链接到产品的记录.

这很好用,但我需要在产品模型中实现 facet-able 搜索并选择使用 ransack。所以要找到所有宽度大于 30 的产品,我必须这样做

Product.ransack(product_properties_property_name_eq: 'width', product_properties_value_gt: 30).result

这又可以正常工作,但我更愿意使用属性名称“洗劫”

Product.ransack(width_gt: 30).result

是否有任何方法可以动态创建允许我这样做的洗劫者(或替代品)?我曾尝试使用 method_missing 但这让我感到无所适从。我正在考虑使用属性表中的所有名称值在模型上创建范围,但我想我会先征求一些建议。

更新

我已经尝试在产品模型上实现一系列自定义 ransackers

class Product < ActiveRecord::Base
  Property.pluck(:name, :id).each do |name, id|
    ransacker name, formatter: -> (value) { value.to_s.downcase } do
      product_properties = Arel::Table.new(:product_properties)
      product_properties[:value]
    end
  end
end

这让我越来越接近我能感觉到的答案。我还应该在这里做什么?

【问题讨论】:

    标签: ruby-on-rails ransack


    【解决方案1】:

    这完美地完成了这项工作。这里的问题是Arel::Nodes.build_quoted。我最初忽略了这一点,我不会收到任何错误/警告,但我同样不会得到任何结果,这让我很困惑。这显然只有在使用Rails 4.2+(Arel 6.0+)时才有必要。

    Property.pluck(:id, :name).each do |id, name|
      product_properties = Arel::Table.new(:product_properties)
    
      ransacker name.to_sym, formatter: -> (value) { value.to_s.downcase } do
        Arel::Nodes::InfixOperation.new('AND',
          Arel::Nodes::InfixOperation.new('=',
            product_properties[:property_id], Arel::Nodes.build_quoted(id)
          ),
          product_properties[:value]
        )
      end
    end
    

    要实际使用它,我需要将 product_properties 表显式连接到查询中

    Product.joins(:product_properties).ransack(width_gt: 30)
    

    正如 ransack 文档所述,有些人在使用 ransackers 时遇到的困难并非源于 Ransack,而是源于不了解 Arel。这绝对是这里的情况。

    【讨论】:

    • 您的解决方案有效,但是它将在整个表中搜索这些值。如果桌子很大,这并不理想,不是吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多