在ransack中,当模型更新时动态更新ranackers

时间 2019-02-22
阅读 36
点赞 0
收藏 0
连接pdev

我有公司客户和公司客户现场模型。客户将hstore值存储在“属性”列中-键来自CompanyCustomerField名称字段。创建新公司客户字段时,我需要添加名称以进行搜索。

当添加新的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 %>

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

客户控制器.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>):
建议答案

解决方案:

需要覆盖:

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需要重置为零,因此def ransackable_attributes(auth_object = nil)实例var为零,可以重新加载

应该被认为是一个漏洞在洗劫。

👍 0