2013-08-21 42 views
27

は、私は次のパラメータを使用して、HTTP PUTリクエストますRails4:paramsの動的キーを持つハッシュを許可する方法は?

{ "ポスト" => { "ファイルを" => { "ファイル1" => "file_content_1"、 "FILE2" => "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:FILE1、FILE2は - 設計強いのparamsによって

+0

するTry params.requireがあった(:ポスト).permit(:ファイル=> [:FILE1、:FILE2]は) – user2801

+2

これはオプションではありません:file1、file2は動的キーです。 – rdo

+0

Rails 5.1の場合はhttps://stackoverflow.com/a/44891190/1414100 –

答えて

39

が値として動的なキーでハッシュを許可していませんので...この場合は手動でfilesをホワイトリストに登録する必要がダイナミックキーです。

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

をご覧くださいありがとうございます!できます。 – rdo

+3

「タップ」の仕組みは次のとおりです: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

のために働く必要があります。しかし、Googleの検索は、この結果に私をもたらした、と私は私の調査結果を共有したいと思った。この間

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"}} 

違い:ここ

は、私は(Railsの4)働くことを発見した代替ソリューションです。この解決策がパラメータを1つのレベルの動的キーに制限するということである。受け入れられた答えは複数の深さを許す。

[編集]

コメントからの有用なヒント:

+0

はい、これは私にとっても役に立ちます –

+4

ああ、あなたはそれを確認する必要がありますparams [:post] [。files]が存在しなければ、キーは失敗します。 –

+0

実際には(注意が必要です) – prusswan

0

あなたは一時的に使用することができます「ああ、あなたはそれがparamsは確認する必要があります[ポスト] [。ファイル]が存在するが、それ以外のキーが失敗します」そのようなあなたの許可リストを構築するための変数:

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レールのために働く)それを行うための簡単な方法です:レール5.1.2で

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. 事実上任意のparamsを可能にすることにより、強力なパラメータの値を否定します。

私はこの解決方法を使用しています。
標準的な強力なパラメータリグを使用して、ほとんどのパラメータ( )をクリーンアップし、Hash属性が明示的に追加されます。私の場合は

# 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 
関連する問題