2010-03-24 34 views
14

我試圖通過一些過濾器在我的PARAMS像這樣:通過表單傳遞的哈希值作爲在hidden_​​field_tag

hidden_field_tag "filters", params[:filters]

出於某種原因,PARAMS獲得在接下來的頁面改變。例如,如果PARAMS [:過濾器]曾經是...

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

...它被改爲...

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

注意額外的報價和反斜槓[2]與[1]相比時。

任何想法?我試圖用searchlogic來進行一些過濾,但我需要它在我更改表單中的更改對象時保留。我寧願不必將它存儲在會話中。

回答

11

你實際上需要/需要使用隱藏字段'序列化'散列。

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

+0

這做到了感謝。這個解決方案應該包含在Rails或其他東西中。 – funkymunky 2010-03-25 18:06:27

+0

不客氣:)。不,我相信這不是一個核心功能,但如果它被包含在插件中,它會很好。 – 2010-03-25 21:43:44

+0

太棒了!應該肯定是Rails的一部分。 Btw必須在Rails 5中將'hidden_​​fields.join(「\ n」)'改爲'hidden_​​fields.join(「\ n」)。html_safe',這樣HTML就不會被轉義出來 – elsurudo 2017-09-07 10:08:03

0

這是因爲當您使用hidden_​​field_tag轉換HTML時,反引用是添加的。當你收到它像一個字符串不是哈希。

哈希類型不能存在於HTML中。你只有字符串。所以,如果你想通過你的哈希(不推薦我),你需要評估它,當你收到它。但是可能是您的應用程序中的一個重大安全問題。

0

一個簡單的警告弗拉德的回答,我只好用原料

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

得到它在Rails的3.1.1工作。實質上,正在輸出的文本正在被轉義,例如,「<」變爲「& lt」。

12

我的解決辦法只是爲了鍵值對重新創建的每個特性參數的:

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

這麼簡單。奇蹟般有效。謝謝okliv! – 2012-03-09 21:14:04

+4

像這些解決方案不處理更深的哈希嵌套... – vemv 2013-11-26 09:24:14

7

我只是寫了寶石做這個叫HashToHiddenFields

創業板的核心是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 
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. 

,這不是任何地方記錄鍵轉換我能找到的就是{...:ID => object.id}從視圖A上到視圖B通過作爲<%...:ID => @object%>,它視圖B然後傳遞給控制器​​作爲通過hidden_​​field_tag構建體(:PARAM_NAME,則params [ID])。

我沒有看到這個記錄的任何地方,但細讀跨越多個網站,包括這篇文章(它的語法提供的關鍵靈感)幾個職位後,溶液最後膠凝。我已經看到了有關安全隱患領域告誡,但沒有發現任何其他方式做到這一點給我的當前設計,比如它。

相關問題