Передача хэша как значений в теге скрытого поля
Я пытаюсь передать некоторые фильтры в моих парамах через такую форму:
hidden_field_tag "filters", params[:filters]
по какой-то причине параметры изменяются на следующей странице. Например, если раньше были params [: filters]...
"filters"=>{"name_like_any"=>["apple"]} [1]
...он заменяется...
"filters"=>"{"name_like_any"=>["apple"]}" [2]
обратите внимание на дополнительные цитаты и обратные косые черты в [2] по сравнению с [1].
какие идеи? Я пытаюсь использовать это с searchlogic для некоторых фильтрация, но мне нужно, чтобы она сохранялась, когда я изменяю объекты изменения в формах. Я бы предпочел не хранить его во время сеанса.
6 ответов
вы действительно хотите / должны "сериализовать" хэш, используя скрытые поля.
добавьте это в ваш 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
моим решением было просто воссоздать каждый из param с парой ключ-значение:
<% params[:filters].each do |key,value| %>
<%= hidden_field_tag "filters[#{key}]",value %>
<% end %>
Я просто написал драгоценный камень, чтобы сделать это под названием 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
вот как мне удалось передать значение параметра через мой вид-то есть из вида A через вид B и на контроллер:
in View A (index):
<%= 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 => объект.id} из представления A передается в представление B как @object % > , которое представление B затем передается контроллеру как (: param_name, params [: id]) через конструкцию hidden_field_tag.
Я не видел этого документированного нигде, но после просмотра нескольких сообщений на нескольких сайтах, включая этот пост (синтаксис которого обеспечивал ключевое вдохновение), решение наконец сгустилось. Я видел предостережения о скрытых полях, относящихся к безопасности, но не нашел другого способа сделать это, учитывая мой текущий дизайн, такой, как он есть.
Это потому, что когда вы конвертируете в HTML с помощью hidden_field_tag, backquote-add. После того, как вы получили его как строку, а не хэш.
тип хэша не может существовать в HTML. У вас есть только строка. Поэтому, если вы хотите передать свой хэш (не рекомендую мне), вам нужно оценить его, когда вы его получили. Но может быть большой проблемой безопасности в приложении.
в качестве предостережения к ответу Влада я должен был использовать raw:
<%= raw hash_as_hidden_fields(:filter => params[:filter]) %>
чтобы заставить его работать в Rails 3.1.1. По сути, выводимый текст был экранирован, например., "