我已经成功安装了Ransack gem,并在我的应用程序中使用它进行简单和高级搜索。我正在尝试为用户添加一项功能,以便"保存搜索"。基本上这个想法是他们可以为搜索查询加书签,并在以后随时访问它。
我通过创建SavedSearch模型进行设置。当用户保存搜索时,它从搜索搜索中获取params [:q]并将其存储在数据库中。
稍后我从数据库中提取此记录,并访问该查询。我尝试通过将查询传递给ransack来重新创建搜索,但它似乎没有工作。搜索会为该模型提取所有记录,而不仅仅是那些符合查询的记录。知道为什么吗?我想也许在将搜索参数传回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"}}}
答案 0 :(得分:2)
根据你的问题:
{"g"=>{"0"=>{"m"=>"and", "c"=>{"0"=>{"a"=>{"0"=>{"name"=>"total_revenue"}}, "p"=>"gt", "v"=>{"0"=>{"value"=>"1000"}}}}}}, "s"=>{"0"=>{"name"=>"stock_health", "dir"=>"asc"}}}
这就是你的param HASH的样子,你将它存储起来以备将来使用(书签)。这里的问题是,这些是在数据库中存储为字符串。
我建议的两个解决方案是:
<强> 1。使用HStore(http://www.postgresql.org/docs/9.0/static/hstore.html)
您可以在postgresql数据库中使用HStore类型列来存储那些您可以在需要时调用的param哈希。注意:PostgreSQL数据库。
<强> 2。 STRING到HASH转换:
How do I convert a String object into a Hash object?
注意我不建议使用eval()函数,因为
eval
不安全且我们不能信任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搜索之前,请将它们转换为原始哈希:
require 'json'
@saved_search = SavedSearch.find(id)
original_bookmark = JSON.parse(@saved_search.bookmark)
我希望,这会帮助您解决问题....
答案 1 :(得分:1)
我认为在数据库中你将查询存储为String.While你从数据库中提取它@saved_search.query_parameters
返回你的字符串。但是ransack需要它成为一个Hash。这是我的主要问题猜测。
当你通过params时,它会得到一个Hash,但是从数据库获取String。你需要解析你从@query
变量得到的字符串,然后将它传递给搜索。
对于String to Hash转换,您可以查看How do I convert a String object into a Hash object?个问题的答案。
答案 2 :(得分:1)
试试这个宝石: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转换回哈希值