Передача хеша в качестве значений в hidden_field_tag

Я пытаюсь передать некоторые фильтры в своих параметрах через такую ​​форму:

hidden_field_tag "filters", params[:filters]

По какой-то причине параметры меняются на следующей странице. Например, если params [: filters] раньше...

"filters"=>{"name_like_any"=>["apple"]} [1]

... он изменяется на...

"filters"=>"{\"name_like_any\"=>[\"apple\"]}" [2]

обратите внимание на дополнительные цитаты и обратную косую черту в [2] по сравнению с [1].

Любые идеи? Я пытаюсь использовать это с searchlogic для некоторой фильтрации, но мне нужно, чтобы он сохранялся при изменении объектов изменений в формах. Я бы предпочел не хранить его в сеансе.

Ответы

Ответ 1

Вы действительно хотите/нужно "сериализовать" хеш с помощью скрытых полей.

Добавьте это в свой ApplicationHelper:

  def flatten_hash(hash = params, ancestor_names = [])
    flat_hash = {}
    hash.each do |k, v|
      names = Array.new(ancestor_names)
      names << k
      if v.is_a?(Hash)
        flat_hash.merge!(flatten_hash(v, names))
      else
        key = flat_hash_key(names)
        key += "[]" if v.is_a?(Array)
        flat_hash[key] = v
      end
    end

    flat_hash
  end

  def flat_hash_key(names)
    names = Array.new(names)
    name = names.shift.to_s.dup 
    names.each do |n|
      name << "[#{n}]"
    end
    name
  end

  def hash_as_hidden_fields(hash = params)
    hidden_fields = []
    flatten_hash(hash).each do |name, value|
      value = [value] if !value.is_a?(Array)
      value.each do |v|
        hidden_fields << hidden_field_tag(name, v.to_s, :id => nil)          
      end
    end

    hidden_fields.join("\n")
  end

Затем, в поле зрения:

<%= hash_as_hidden_fields(:filter => params[:filter]) %>

Это должно сделать трюк, даже если у вас многоуровневый хэш/массив в ваших фильтрах.

Решение принято http://marklunds.com/articles/one/314

Ответ 2

Мое решение состояло только в том, чтобы воссоздать каждый из параметров с помощью пары ключ-значение:

<% params[:filters].each do |key,value| %>
<%= hidden_field_tag "filters[#{key}]",value %> 
<% end %>

Ответ 3

Я просто написал жемчужину, чтобы сделать это под названием HashToHiddenFields.

Ядром драгоценного камня является этот код:

def hash_to_hidden_fields(hash)
  query_string = Rack::Utils.build_nested_query(hash)
  pairs        = query_string.split(Rack::Utils::DEFAULT_SEP)

  tags = pairs.map do |pair|
    key, value = pair.split('=', 2).map { |str| Rack::Utils.unescape(str) }
    hidden_field_tag(key, value)
  end

  tags.join("\n").html_safe
end

Ответ 4

Вот как мне удалось передать значение параметра через мое представление, то есть от View A до View B и от контроллера:

В представлении A (индекс):

<%= link_to 'LinkName', {:action => "run_script", :id => object.id} %>

В представлении B (run_script):

<%= form_tag :action => 'index', :id => @object %>
<%= hidden_field_tag(:param_name, params[:id]) %>

В контроллере:

Just reference params[:param_name] to make use of the value.

Ключевой переход, который не был зарегистрирован нигде, где я мог найти, - это где {...: id = > object.id} из View A передается в View B как <%...: id = > @object% > , который View B затем переходит к контроллеру как (: param_name, params [: id]) через конструкцию hidden_field_tag.

Я не видел этого документально, но после просмотра нескольких сообщений на нескольких сайтах, включая этот пост (синтаксис которого обеспечил ключевое вдохновение), решение, наконец, заглохло. Я видел предостережения о скрытых полях, относящихся к безопасности, но не нашел другого способа сделать это, учитывая мой текущий дизайн, например.

Ответ 5

потому что, когда вы конвертируете в HTML с вашим hidden_field_tag, backquote добавляется. После того, как вы получили его как строку, а не Hash.

Тип Hash не может существовать в HTML. У вас есть только строка. Поэтому, если вы хотите передать свой хэш (не рекомендую меня), вам нужно его оценить, когда вы его получили. Но может быть большой проблемой безопасности в вашем приложении.

Ответ 6

Как предостережение Влада, я должен был использовать raw:

<%= raw hash_as_hidden_fields(:filter => params[:filter]) %>

чтобы заставить его работать в Rails 3.1.1. По существу, выводимый текст был экранирован, например, "<" становясь "& lt".