【问题标题】:In Ransack update ranackers dynamically when a model gets updated在 Ransack 中,当模型更新时动态更新 ranackers
【发布时间】:2019-02-21 19:27:14
【问题描述】:

我有 Company Customer 和 CompanyCustomerField 模型。客户将 hstore 值存储在“属性”列中 - 键来自 CompanyCustomerField#name 字段。创建新的 CompanyCustomerField 时,我需要将 #name 添加到 ransack 以使其可搜索。

当一个新的 CompanyCustomerField 被添加并且我转到我得到的搜索表单时

undefined method `*_cont' for #<Ransack::Search:0x00007ff670100978>

因为新字段不可用于搜索。如果我关闭失败的服务器并重新启动它,它会工作,因为它会进入洗劫状态。 我不知道如何将功能动态添加到 ransack 中。任何想法都非常感谢。

客户.rb。这会将所有可搜索字段放入洗劫,但在添加新字段时不会更新它。因为这只被调用一次。

class Customer < ApplicationRecord
  # ['favorite_color', 'receive_email_marketing' etc etc]
  CompanyCustomerField.pluck(:name).each do |name|
    ransacker name.to_sym do |parent|
      Arel::Nodes::InfixOperation.new('->', parent.table[:properties], Arel::Nodes.build_quoted(name))
    end
  end
end

这里是搜索表单:

#customers/index.html
<%= search_form_for @search, remote: true do |f| %>
  <% current_company.customer_fields.each do |field| %>
    <%= render "customers/search_fields/#{field.field_type}", f: f, field: field %>
  <% end %>
<% end %>

#customers/search_fields/text_field
<%= f.label (field.name + "_cont").to_sym, field.name.humanize %>
<%= f.text_field (field.name + "_cont").to_sym %>

....
即使将重载移动到控制器,结果仍然相同。

CustomersController.rb

def index
  Customer.reload_ransacker
  @search = current_company.customers.includes(:owner).ransack(params[:q])
  @customers = @search.result.page(params[:page])
end

客户.rb

def self.reload_ransacker
  puts "==="
  puts "reload ransacker"
  puts "==="
  CompanyCustomerField.pluck(:name).each do |name|
    ransacker name.to_sym do |parent|
      Arel::Nodes::InfixOperation.new('->', parent.table[:properties], Arel::Nodes.build_quoted(name))
    end
  end
end
ActionView::Template::Error (undefined method `foo_cont' for #<Ransack::Search:0x00007fba3c05d5b8>):

【问题讨论】:

    标签: ruby-on-rails ransack arel hstore


    【解决方案1】:

    解决方案:

    需要覆盖:

    module Ransack
      module Adapters
        module ActiveRecord
          module Base
            def ransacker(name, opts = {}, &block)
              @ransackable_attributes = nil
              self._ransackers = _ransackers.merge name.to_s => Ransacker
                .new(self, name, opts, &block)
            end
          end
        end
      end
    end
    

    @ransackable_attributes 需要重置为 nil,因此在 def ransackable_attributes(auth_object = nil) 中,实例 var 为 nil 并且可以重新加载

    应该被认为是ransack中的一个bug。

    【讨论】:

      猜你喜欢
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 2019-10-09
      相关资源
      最近更新 更多