Передача хеша в качестве значений в hidden_field_tag - PullRequest
16 голосов
/ 24 марта 2010

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

hidden_field_tag "filters", params[:filters]

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

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

... меняется на ...

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

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

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

Ответы [ 6 ]

16 голосов
/ 10 ноября 2011

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

<% params[:filters].each do |key,value| %>
<%= hidden_field_tag "filters[#{key}]",value %> 
<% end %>
12 голосов
/ 24 марта 2010

Вы действительно хотите / должны 'сериализовать' хеш, используя скрытые поля.

Добавьте это в 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

8 голосов
/ 28 февраля 2012

Я только что написал гем для этого под названием 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
1 голос
/ 07 марта 2012

Вот как мне удалось передать значение параметра через моего представления, то есть из представления A в представление 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} из представления A передается представлению B как <% ...: id => @object %>, который представление B затем передает контроллеру как (: param_name, params [: id]) через конструкцию hidden_field_tag.

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

0 голосов
/ 06 ноября 2011

В качестве ответа на ответ Влада мне пришлось использовать raw :

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

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

0 голосов
/ 24 марта 2010

потому что когда вы конвертируете в HTML с помощью hidden_field_tag, обратная цитата будет add. После того, как вы получили его как строку, а не хэш.

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

...