17

我试图通过如下形式在我的参数中传递一些过滤器:

hidden_field_tag "filters", params[:filters]

由于某种原因,参数在下一页中被更改。例如,如果 params[:filters] 曾经是...

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

......它变成......

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

与 [1] 相比,请注意 [2] 中的额外引号和反斜杠。

有任何想法吗?我正在尝试将它与 searchlogic 一起使用以进行一些过滤,但是当我更改表单中的更改对象时,我需要它保持不变。我宁愿不必将其存储在会话中。

4

7 回答 7

18

My solution was just to re-create each of param with key-value pair:

<% params[:filters].each do |key,value| %>
<%= hidden_field_tag "filters[#{key}]",value %> 
<% end %>
于 2011-11-10T13:46:50.313 回答
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]) %>

这应该可以解决问题,即使您的过滤器中有一个多级哈希/数组。

解决方案 http://marklunds.com/articles/one/314

于 2010-03-24T11:01:00.200 回答
8

我刚刚编写了一个名为HashToHiddenFields的 gem 来执行此操作。

gem的核心是这段代码:

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
于 2012-02-28T19:18:12.883 回答
1

以下是我设法通过视图传递参数值的方法 - 即从视图 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.

我能找到的任何地方都没有记录的关键转换是视图 A 中的 {... :id => object.id} 以 <%... :id => @object %> 的形式传递给视图 B,然后视图 B 通过 hidden_​​field_tag 构造作为 (:param_name, params[:id]) 传递给控制器​​。

我没有在任何地方看到这个文档,但是在阅读了包括这篇文章(其语法提供了关键灵感)在内的几个网站上的几篇文章之后,解决方案终于凝固了。我已经看到了有关安全性的隐藏字段的警告,但鉴于我目前的设计,我没有找到其他方法来做到这一点,例如它。

于 2012-03-06T23:38:40.860 回答
0

作为对弗拉德回答的警告,我不得不使用raw

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

让它在 Rails 3.1.1 中工作。本质上,正在输出的文本被转义了,例如,“<”变成了“<”。

于 2011-11-05T21:41:37.307 回答
0

这是因为当您使用 hidden_​​field_tag 转换 HTML 时,会添加反引号。当你收到它就像一个字符串而不是一个哈希之后。

HTML 中不能存在 Hash 类型。你只有字符串。所以如果你想传递你的散列(我不推荐),你需要在收到它时评估它。但可能是您的应用程序的一个大安全问题。

于 2010-03-24T08:00:31.570 回答
0

假设散列是字符串、符号、数字和数组,您可以调用 eval 将散列的 params 字符串从 hidden_​​fields 形式转换回控制器中的散列。然后添加引号的反斜杠转义字符不再是问题:

hash = eval(params["hash_string"].to_s)

归功于以下文章,它帮助我为我的案例确定了这个简单的解决方案:

如何将 String 对象转换为 Hash 对象?

请记住,应使用 .require 和 .permit 清除参数的内容。

于 2019-12-11T04:28:33.087 回答