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

私の解決策は、キーと値のペアを使用して各paramを再作成することでした。

<% 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を作成しました。

宝石の中核はこのコードです:

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

これは、hidden_​​field_tagを使用してHTMLに変換すると、バッククォートが追加されるためです。ハッシュではなく文字列のように受け取った後。

ハッシュタイプはHTMLに存在できません。文字列しかありません。したがって、ハッシュを渡したい場合(私は推奨しません)、受け取ったときに評価する必要があります。ただし、アプリケーションのセキュリティ上の大きな問題になる可能性があります。

于 2010-03-24T08:00:31.570 に答える
0

ウラドの答えへの警告として、私はを使わなければなりませんでした:

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

Rails3.1.1で動作させるため。基本的に、出力されるテキストはエスケープされていました。たとえば、「<」は「&lt」になります。

于 2011-11-05T21:41:37.307 に答える
0

ハッシュが文字列、記号、数値、および配列であると仮定すると、evalを呼び出して、ハッシュのparams文字列をhidden_​​fieldsフォームからコントローラーのハッシュに変換し直すことができます。その後、追加された引用符のバックスラッシュエスケープ文字は問題ではなくなります。

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

私の場合、この単純な解決策を特定するのに役立つ次の記事の功績です。

StringオブジェクトをHashオブジェクトに変換するにはどうすればよいですか?

パラメータの内容は.requireと.permitでクリーンアップする必要があることに注意してください。

于 2019-12-11T04:28:33.087 に答える