2013-08-21 28 views
27

我可通過以下參數的HTTP PUT請求:Rails4:如何在params中允許使用動態鍵的散列?

{ 「後」=> { 「文件」=> { 「文件1」=> 「file_content_1」, 「文件2」=> 「file_content_2」} },「id」=>「4」}

我需要在我的代碼中允許散列數組。 基於manuals我已經試過這樣的:

> params.require(:post).permit(:files) # does not work 
> params.require(:post).permit(:files => {}) # does not work, empty hash as result 
> params.require(:post).permit! # works, but all params are enabled 

如何正確做呢?

UPD1:文件1,文件2 - 是動態密鑰

+0

嘗試params.require(:柱).permit(:文件=> [:文件1,:文件2]) – user2801

+2

這不是一個選項:file1,file2是動態密鑰。 – rdo

+0

For Rails 5.1請參閱https://stackoverflow.com/a/44891190/1414100 –

回答

39

設計強PARAMS不允許使用動態密鑰的哈希值,所以..在這種情況下,你需要手動白名單files

params.require(:post).tap do |whitelisted| 
    whitelisted[:files] = params[:post][:files] 
end 
+0

謝謝!有用。 – rdo

+3

以下是tap的工作方式:http://ruby-doc.org/core-2.1.1/Object.html#method-i-tap – amoebe

5

奧蘭多的答覆工作,但得到的參數集從permitted?方法返回false。如果您稍後在結果中包含post哈希中的其他參數,您也不清楚如何繼續。

這裏的另一種方式

permitted_params = params.require(:post).permit(:other, :parameters) 
permitted_params.merge(params[:post][:files]) 
1

這裏是另一種方式來解決這個問題:

def post_params 
    permit_key_params(params[:post]) do 
     params.require(:post) 
    end 
    end 

    def permit_key_params(hash) 
    permitted_params = yield 
    dynamic_keys = hash.keys 
    dynamic_keys.each do |key| 
     values = hash.delete(key) 
     permitted_params[key] = values if values 
    end 
    permitted_params 
    end 

這應該post: { something: {...}, something_else: {...} }

14

我明白,這是一個古老的崗位工作。然而,谷歌搜索給我帶來了這樣的結果,我想分享我的發現:

這裏是一個替代的解決方案,我發現工程(軌道4):

params = ActionController::Parameters.new({"post"=>{"files"=>{"file1"=>"file_content_1", "file2"=>"file_content_2"}}, "id"=>"4"}) 
params.require(:post).permit(files: params[:post][:files].keys) 
# Returns: {"files"=>{"file1"=>"file_content_1", "file2"=>"file_content_2"}} 

這之間的差異答案和接受的答案是,這種解決方案將參數限制爲只有1級動態密鑰。接受的答案允許多個深度。

[編輯]從評論有用的提示

「哦,你需要驗證PARAMS [:帖] [文件]存在,否則鍵會失敗」

+0

是的,這對我也有效 –

+4

哦,你需要驗證params [:post] [。files]存在,否則密鑰將失敗 –

+0

實際上一個整潔的想法(有注意事項) – prusswan

0

您可以使用臨時變量來建立你的允許的列表,像這樣:

permitted = params.require(:post).permit(:id) 
permitted[:post][:files] = params[:post][:files].permit! 
0
Send params as array type like name=date[]**strong text** 
     def user_post 
     dates = params[:date] 
     #render json: { 'response' => params } 
     i = 0 
     dates.each do |date| 
      locations = params['location_'+"#{i}"] 
      user_names = params['user_'+"#{i}"] 
      currency_rates = params['currency_'+"#{i}"] 
      flags = params['flag_'+"#{i}"] 
      j = 0 
      locations.each do |location| 
      User.new(user_name: user_names[j], currency_name: flags[j], 
      currency_rate: currency_rates[j], currency_flag: flags[j], location: location).save 
      j =+ 1 
      end 
      i =+ 1 
     end 
    def 
3

以下是我們在Rails的5.0.0做的,希望這可以幫助別人。

files = params[:post].delete(:files) if params[:post][:files] 
params.require(:post).permit(:id).tap do |whitelisted| 
    whitelisted[:files] = files.permit! 
end 
+0

不錯的做法。真的幫助了我。謝謝@加里! – mikej

0

這裏有一個簡單的方法來做到這一點(適用於軌道5):

def my_params 
    data_params = preset_data_params 

    params.require(:my_stuff).permit(
     :some, 
     :stuff, 
     data: data_params 
    ) 
    end 

    def preset_data_params 
    return {} unless params[:my_stuff] 
    return {} unless params[:my_stuff][:data] 

    params[:my_stuff][:data].keys 
    end 
0

我無法獲得許多建議的答案(Rails 5):

  1. 事先知道所有的散列鍵,或者
  2. 通過允許任意參數幾乎否定強參數的值。

我正在使用此解決方案。
它使用標準強參數鑽機來清理大部分參數, 並且明確地添加了哈希屬性。

# Assuming: 
class MyObject < ApplicationRecord 
    serialize :hash_attr as: Hash 
    #... 
end 

# MyObjectsController method to filter params: 
def my_object_params 
    # capture the hashed attribute value, as a Hash 
    hash_attr = params[:my_object] && params[:my_object][:hash_attr] ? 
     params[my_object][:hash_attr].to_unsafe_h : {} 
    # clean up the params 
    safe_params = params.require(:my_object).permit(:attr1, :attr2) # ... etc 
    # and add the hashed value back in 
    safe_params.to_unsafe_h.merge hash_attr: hash_attr 
end 
0

在我的情況,只是有一個屬性其具有動態密鑰,

def post_params 
    marking_keys = Set.new 
    params[:post][:marking].keys.collect {|ii| marking_keys.add(ii)} 
    params.require(:post).permit(:name, marking: marking_keys.to_a) 
end 
相關問題