【问题标题】:Rails - Saving Ransack Query for later useRails - 保存 Ransack 查询供以后使用
【发布时间】:2015-10-10 16:19:25
【问题描述】:

我已成功安装 Ransack gem,并让它在我的应用程序中用于简单和高级搜索。我正在尝试为用户添加一项功能以“保存搜索”。本质上,他们的想法是他们可以为搜索查询添加书签,并在以后随时访问它。

我通过创建 SavedSearch 模型来设置它。当用户保存搜索时,它会从他们的 ransack 搜索中获取 params[: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"}}}

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 ransack


    【解决方案1】:

    根据你的问题:

    {"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?

    注意我不建议使用 eval() 函数,因为 eval 不安全,我们不能信任参数

    建议:

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

    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 搜索之前,通过以下方式将它们转换为原始哈希:

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

    我希望,这将帮助您解决您的问题....

    【讨论】:

      【解决方案2】:

      我认为在数据库中,您将查询存储为字符串。当您从数据库@saved_search.query_parameters 中提取查询时,正在返回字符串。但是洗劫需要它是一个哈希。这是我猜的主要问题。

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

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

      【讨论】:

        【解决方案3】:

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

        class SavedSearch < ActiveRecord::Base
          validates_presence_of :context, :description, :search_params
        
          serialize :search_params
        end
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-14
          • 1970-01-01
          相关资源
          最近更新 更多