我试图通过类似的形式在我的参数中传递一些过滤器:
hidden_field_tag "filters", params[:filters]
由于某种原因,下一页中的参数更改了。例如,如果params [:filters]曾经是......
"filters"=>{"name_like_any"=>["apple"]} [1]
......它变成了......
"filters"=>"{\"name_like_any\"=>[\"apple\"]}" [2]
与[1]相比,注意[2]中的额外引号和反斜杠。
有什么想法吗?我试图将它与searchlogic一起用于某些过滤,但是当我在表单中更改更改对象时,我需要它继续存在。我宁愿不把它存放在会话中。
答案 0 :(得分:16)
我的解决方案只是用键值对重新创建每个参数:
<% params[:filters].each do |key,value| %>
<%= hidden_field_tag "filters[#{key}]",value %>
<% end %>
答案 1 :(得分:12)
您实际上想要/需要使用隐藏字段“序列化”哈希。
将此添加到 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]) %>
即使你的过滤器中有多级散列/数组,这也应该可以解决问题。
答案 2 :(得分:8)
我刚刚写了一个名为HashToHiddenFields的宝石。
gem的核心是this代码:
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
答案 3 :(得分:1)
以下是我设法传递参数值到我的视图 - 即从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 =&gt;来自View A的object.id}作为&lt;%...:id =&gt;传递给View B. @object%&gt;,然后View B通过hidden_field_tag构造传递给控制器(:param_name,params [:id])。
我没有在任何地方看到这个记录,但是在几个网站上仔细阅读了几篇帖子后,包括这篇文章(其语法提供了关键灵感),解决方案终于凝聚了。我已经看到了关于安全性的隐藏字段的注意事项,但鉴于我目前的设计,没有找到其他方法来做到这一点,例如它。
答案 4 :(得分:0)
这是因为当您使用您的hidden_field_tag转换HTML时,会添加反引号。当你收到它之后就像字符串而不是哈希。
Hash类型不能存在于HTML中。你只有字符串。所以如果你想传递你的哈希(不是我推荐的),你需要在收到它时进行评估。但对您的应用程序来说可能是一个很大的安全问题。
答案 5 :(得分:0)
作为弗拉德回答的一个警告,我不得不使用原始:
<%= raw hash_as_hidden_fields(:filter => params[:filter]) %>
让它在Rails 3.1.1中运行。基本上,正在输出的文本正在被转义,例如,“&lt;”成为“&amp; lt”。
答案 6 :(得分:0)
假设哈希是字符串,符号,数字和数组,则可以调用eval将哈希的params字符串从hidden_fields形式转换回控制器中的哈希。然后,添加引号的反斜杠转义字符不再是问题:
hash = eval(params["hash_string"].to_s)
请信任以下文章,以帮助确定适合我的情况的简单解决方案:
How do I convert a String object into a Hash object?
请记住,应使用.require和.permit清除参数的内容。