将哈希作为值传递到hidden_​​field_tag

发布于 2024-08-27 02:05:20 字数 440 浏览 6 评论 0原文

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

hidden_​​field_tag "filters", params[:filters]

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

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

...它会改变...

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

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

有什么想法吗?我试图将其与 searchlogic 一起使用进行一些过滤,但当我更改表单中的更改对象时,我需要它保留下来。我不想将其存储在会话中。

I am trying to pass some filters in my params through a form like so:

hidden_field_tag "filters", params[:filters]

For some reason the params get changed in the next page. For example, if params[:filters] used to be...

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

...it gets changed to...

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

note the extra quotations and backslashes in [2] when compared to [1].

Any ideas? I'm attempting to use this with searchlogic for some filtering, but I need it to persist when I change change objects in forms. I would prefer not to have to store it in session.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

池予 2024-09-03 02:05:20

我的解决方案只是用键值对重新创建每个参数:

<% params[:filters].each do |key,value| %>
<%= hidden_field_tag "filters[#{key}]",value %> 
<% end %>

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 %>
柠栀 2024-09-03 02:05:20

您实际上想要/需要使用隐藏字段“序列化”哈希。

将其添加到您的 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

You actually want/need to 'serialize' a hash using hidden fields.

Add this to your 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

Then, in view:

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

This should do the trick, even if you have a multilevel hash/array in your filters.

Solution taken http://marklunds.com/articles/one/314

羁客 2024-09-03 02:05:20

我刚刚编写了一个名为 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

I just wrote a gem to do this called HashToHiddenFields.

The core of the gem is this code:

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
夜无邪 2024-09-03 02:05:20

以下是我如何设法通过我的视图传递参数值 - 即从视图 A 到视图 B 再到控制器:

在视图 A(索引)中:

<%= link_to 'LinkName', {:action =>; “run_script”,:id =>对象.id} %>

在视图 B (run_script) 中:

<%= form_tag :action =>; '索引', :id => @对象%>
<%=hidden_​​field_tag(:param_name, params[:id]) %>

在控制器中:

只需引用 params[:param_name] 即可使用该值。

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

我没有在任何地方看到这个记录,但在仔细阅读了包括这篇文章在内的多个网站上的几篇文章(其语法提供了关键灵感)后,解决方案最终得到了解决。我已经看到了与安全相关的隐藏字段的警告,但鉴于我当前的设计,没有找到其他方法来做到这一点。

Here's how I managed to pass a parameter value through my view - that is, from View A through View B and on to the controller:

In View A (index):

<%= link_to 'LinkName', {:action => "run_script", :id => object.id} %>

In View B (run_script):

<%= form_tag :action => 'index', :id => @object %>
<%= hidden_field_tag(:param_name, params[:id]) %>

In the controller:

Just reference params[:param_name] to make use of the value.

The key transition that wasn't documented anywhere I could find is where {... :id => object.id} from View A is passed on to View B as <%... :id => @object %>, which View B then passes on to the controller as (:param_name, params[:id]) through the hidden_field_tag construct.

I didn't see this documented anywhere but after perusing several posts across several sites including this post (whose syntax provided the key inspiration), the solution finally gelled. I've seen the caveats on hidden fields pertaining to security but have found no other way to do this given my current design, such as it is.

随遇而安 2024-09-03 02:05:20

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

Hash 类型不能存在于 HTML 中。你只有字符串。因此,如果您想传递哈希值(我不推荐),则需要在收到哈希值时对其进行评估。但这可能对您的应用程序来说是一个很大的安全问题。

it's because when you convert in HTML with your hidden_field_tag, the backquote is add. After when you received it like a string not a Hash.

The Hash type can't exist in HTML. You have only string. So if you want pass your hash (not recommend by me), you need eval it when you received it. But can be a big security issue on your application.

可是我不能没有你 2024-09-03 02:05:20

作为对 Vlad 答案的警告,我必须使用 raw:

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

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

As a caveat to Vlad's answer, I had to use raw:

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

to get it to work in Rails 3.1.1. Essentially, the text being output was being escaped, eg., "<" becoming "<".

A君 2024-09-03 02:05:20

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

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

感谢以下文章帮助为我的案例确定了这个简单的解决方案:

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

请记住,参数的内容应使用 .require 进行清理和.许可。

Assuming the hash is strings, symbols, numbers, and arrays, you can call eval to convert the params string of the hash from the hidden_fields form back into a hash in the controller. Then the backslash escape characters for the quotes added are no longer an issue:

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

Credit to the following article for helping identify this simple solution for my case:

How do I convert a String object into a Hash object?

Keep in mind the contents of the params should be cleaned with .require and .permit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文