Rails - 保存 Ransack 查询供以后使用

Rails - Saving Ransack Query for later use

我已经成功安装了 Ransack gem 并在我的应用程序中使用它进行简单和高级搜索。我正在尝试为 "Save a Search" 的用户添加一项功能。从本质上讲,他们可以为搜索查询添加书签,并在以后随时访问它。

我通过创建一个 SavedSearch 模型来设置它。当用户保存搜索时,它会从他们的搜查搜索中获取参数 [:q] 并将其存储在数据库中。

稍后我从数据库中提取这条记录,并访问查询。我尝试通过将查询传递给 ransack 来重新创建搜索,但它似乎不起作用。搜索会提取该模型的所有记录,而不仅仅是那些适合查询的记录。知道为什么吗?我在想,在将搜索参数传回搜查之前,可能需要将搜索参数修改为不同的格式?这是我的代码:

这是来自我的控制器模型的代码(advanced_search 操作完美无缺,但 saved_search 在回收查询时没有正确过滤):

  def advanced_search
    @query = params[:q]
    @saved_search = SavedSearch.new
    @q = Variant.search(params[:q])
    @q.build_grouping unless @q.groupings.any?
    @variants  = params[:distinct].to_i.zero? ?
      @q.result.paginate(per_page: 100, page: params[:page]) :
      @q.result.includes(:supplier).paginate(per_page: 100, page: params[:page])

    respond_with @variants
  end

  def saved_search
    @id = params[:id]
    @saved_search = SavedSearch.find(@id)
    @query = @saved_search.query_parameters
    @distinct = @saved_search.distinct

    @q = Variant.search(@saved_search.query_parameters)
    @q.build_grouping unless @q.groupings.any?
    @variants  = @distinct.to_i.zero? ?
      @q.result.paginate(per_page: 100, page: params[:page]) :
      @q.result.includes(:supplier).paginate(per_page: 100, page: params[:page])

    render 'advanced_search'
  end

以下是成功查询的搜索参数存储在数据库中时的样子:

{"g"=>{"0"=>{"m"=>"and", "c"=>{"0"=>{"a"=>{"0"=>{"name"=>"total_revenue"}}, "p"=>"gt", "v"=>{"0"=>{"value"=>"1000"}}}}}}, "s"=>{"0"=>{"name"=>"stock_health", "dir"=>"asc"}}}

我认为在数据库中您将查询存储为 String.While 您正在从数据库中提取它 @saved_search.query_parameters 返回给您 string.But 搜查需要它是 Hash.This 是我猜的主要问题。

当您通过参数传递时,它会得到一个哈希,但从数据库中得到的 String.You 需要解析您从 @query 变量中获取的字符串,然后将其传递给搜索。

对于字符串到哈希的转换,您可以查看 How do I convert a String object into a Hash object? 问题的答案。

根据你的问题:

{"g"=>{"0"=>{"m"=>"and", "c"=>{"0"=>{"a"=>{"0"=>{"name"=>"total_revenue"}}, "p"=>"gt", "v"=>{"0"=>{"value"=>"1000"}}}}}}, "s"=>{"0"=>{"name"=>"stock_health", "dir"=>"asc"}}}

这就是您的参数 HASH 的样子,您正在存储它以备将来使用(书签)。这里的问题是,这些在您的数据库中存储为字符串。

我可以建议的两个解决方案是:

1.使用 HStore (http://www.postgresql.org/docs/9.0/static/hstore.html)

您可以在 postgresql 数据库中使用 HStore 类型的列来存储那些您可以在需要时按原样调用的参数哈希。注意:PostgreSQL 数据库。

2。 STRING 到 HASH 的转换:

How do I convert a String object into a Hash object?

NOTE I do not recommend using eval() function, coz eval is not safe and we can't trust params

建议:

我发现的另一个解决您问题的方法是:

1) 在保存书签参数之前,将它们转换为 json

# suppose bookmark is a column you are using in SavedSearch table to store those ransack search params[:q] then

bookmark = {"g"=>{"0"=>{"m"=>"and", "c"=>{"0"=>{"a"=>{"0"=>{"name"=>"total_revenue"}}, "p"=>"gt", "v"=>{"0"=>{"value"=>"1000"}}}}}}, "s"=>{"0"=>{"name"=>"stock_health", "dir"=>"asc"}}}

@saved_search = SavedSearch.new(save_search_params)
@saved_search.bookmark = bookmark.to_json
@saved_search.save

2) 现在,在将这些值传递给 ransack search 之前,通过以下方式将它们转换为原始哈希:

require 'json'
@saved_search = SavedSearch.find(id)
original_bookmark = JSON.parse(@saved_search.bookmark)

希望这能帮助您解决问题....

试试这个 gem:https://rubygems.org/gems/ransack_advanced_search 它为构建查询提供了一个很好的界面,还允许您命名和存储搜索供以后使用。是使用 active_record 的序列化方法从数据库

保存查询参数
class SavedSearch < ActiveRecord::Base
  validates_presence_of :context, :description, :search_params

  serialize :search_params
end

当您从数据库中读取它时,它会自动将 search_params 转换回哈希值