Rails - Сохранение Ransack Query для последующего использования

Я успешно установил драгоценный камень Ransack, и он работает в моем приложении как для простого, так и для расширенного поиска. Я пытаюсь добавить для пользователей функцию «Сохранить поиск». По сути, идея заключается в том, что они могут добавить поисковый запрос в закладки и получить к нему доступ позже в любое время.

Я настроил его, создав модель SavedSearch. Когда пользователь сохраняет поиск, он берет params[:q] из своего поиска и сохраняет его в базе данных.

Позже я извлекаю эту запись из базы данных и получаю доступ к запросу. Я пытаюсь воссоздать поиск, передав запрос в ransack, но, похоже, он не работает. Поиск извлекает ВСЕ ЗАПИСИ для этой модели, а не только те, которые соответствуют запросу. Есть идеи, почему? Я думаю, что, возможно, параметры поиска нужно изменить на другой формат, прежде чем передавать их обратно в разыск? Вот мой код:

Вот код из моей модели контроллера (действие advanced_search работает без нареканий, но save_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"}}}

person Isaac Y    schedule 10.10.2015    source источник


Ответы (3)


Я думаю, что в базе данных вы храните запрос как строку. Пока вы извлекаете его из базы данных, @saved_search.query_parameters возвращает вам строку. Но для вымогательства требуется, чтобы это был хэш. Я думаю, это основная проблема.

Пока вы проходите через params, он получает Hash, но из базы данных он получает String. Вам нужно проанализировать строку, которую вы получаете из переменной @query, а затем передать ее в поиск.

Для преобразования строки в хэш вы можете посмотреть Как преобразовать объект String в объект Hash? ответы на вопрос.

person iubbba08    schedule 11.10.2015

По вашему вопросу:

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

вы можете использовать столбец типа HStore в своей базе данных postgresql для хранения тех хэшей параметров, которые вы можете вызывать как есть, когда это необходимо. ПРИМЕЧАНИЕ. База данных PostgreSQL.

2. Преобразование STRING в HASH:

Как преобразовать объект String в Hash объект?

ПРИМЕЧАНИЕ. Я не рекомендую использовать функцию 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) Теперь, прежде чем передавать эти значения в поисковый поиск, преобразуйте их в исходный хеш:

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

Надеюсь, это поможет вам решить вашу проблему....

person przbadu    schedule 12.10.2015

Попробуйте этот гем: https://rubygems.org/gems/ransack_advanced_search предоставляет удобный интерфейс для построения запросов. а также позволяет вам назвать и сохранить поиск для последующего использования. Is использует метод сериализации из active_record для сохранения параметров запроса из базы данных.

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

  serialize :search_params
end

Он автоматически преобразует search_params обратно в хэш, когда вы читаете его из базы данных.

person Jose Neto    schedule 17.05.2016