ruby-on-rails - form_for - select ruby on rails example
Pasando hash como valores en hidden_field_tag (6)
Estoy tratando de pasar algunos filtros en mis parámetros a través de un formulario como este:
hidden_field_tag "filters", params[:filters]
Por alguna razón, los parámetros se modifican en la página siguiente. Por ejemplo, si params [: filters] solía ser ...
"filters"=>{"name_like_any"=>["apple"]} [1]
... se cambia a ...
"filters"=>"{/"name_like_any/"=>[/"apple/"]}" [2]
tenga en cuenta las citas adicionales y las barras invertidas en [2] en comparación con [1].
¿Algunas ideas? Estoy intentando usar esto con searchlogic para algunos filtros, pero necesito que persista cuando cambio los objetos de cambio en los formularios. Preferiría no tener que almacenarlo en sesión.
Acabo de escribir una gema para hacer esto llamada HashToHiddenFields .
El núcleo de la gema es this código:
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
Así es como logré pasar un valor de parámetro a través de mi vista, es decir, de la Vista A a la Vista B y al controlador:
En la Vista A (índice):
<%= link_to ''LinkName'', {:action => "run_script", :id => object.id} %>
En la Vista B (run_script):
<%= form_tag :action => ''index'', :id => @object %> <%= hidden_field_tag(:param_name, params[:id]) %>
En el controlador:
Just reference params[:param_name] to make use of the value.
La transición clave que no se documentó en cualquier lugar que pudiera encontrar es donde {...: id => object.id} de la Vista A se pasa a la Vista B como <% ...: id => @object%>, la Vista B luego pasa al controlador como (: param_name, params [: id]) a través de la construcción hidden_field_tag.
No vi esto documentado en ninguna parte, pero después de leer varias publicaciones en varios sitios, incluida esta publicación (cuya sintaxis fue la inspiración clave), la solución finalmente se impuso. He visto las advertencias en campos ocultos relacionados con la seguridad, pero no he encontrado otra forma de hacerlo dado mi diseño actual, tal como es.
Como una advertencia a la respuesta de Vlad, tuve que usar raw :
<%= raw hash_as_hidden_fields(:filter => params[:filter]) %>
Para que funcione en Rails 3.1.1. Esencialmente, se escapó el texto que se estaba imprimiendo, por ejemplo, "<" se convierte en "& lt".
Mi solución fue simplemente recrear cada uno de param con par clave-valor:
<% params[:filters].each do |key,value| %>
<%= hidden_field_tag "filters[#{key}]",value %>
<% end %>
Usted realmente quiere / necesita ''serializar'' un hash usando campos ocultos.
Agregue esto a su 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
Luego, a la vista:
<%= hash_as_hidden_fields(:filter => params[:filter]) %>
Esto debería hacer el truco, incluso si tiene un hash / array multinivel en sus filtros.
Solución tomada http://marklunds.com/articles/one/314
es porque cuando usted convierte en HTML con su hidden_field_tag, el backquote es agregar. Después de cuando lo recibiste como una cadena no un hash.
El tipo Hash no puede existir en HTML. Sólo tienes una cuerda. Así que si quieres pasar tu hash (no lo recomiendo por mí), necesitas evaluarlo cuando lo recibas. Pero puede ser un gran problema de seguridad en su aplicación.