Rails 4-強力なパラメーター-ネストされたオブジェクト


144

かなり簡単な質問があります。しかし、これまでのところ解決策を見つけていません。

これがサーバーに送信するJSON文字列です。

{
  "name" : "abc",
  "groundtruth" : {
    "type" : "Point",
    "coordinates" : [ 2.4, 6 ]
  }
}

新しい許可方法を使用して、私は持っています:

params.require(:measurement).permit(:name, :groundtruth)

これはエラーをスローしませんが、作成されたデータベースエントリnullにはGroundtruth値の代わりに含まれます。

設定しただけの場合:

params.require(:measurement).permit!

すべてが期待どおりに保存されますが、もちろん、これは強力なパラメーターによって提供されるセキュリティを無効にします。

解決策、配列を許可する方法は見つかりましたが、ネストされたオブジェクトを使用する単一の例ではありません。これはかなり一般的なユースケースであるため、何らかの形で可能でなければなりません。それで、それはどのように機能しますか?



1
@vinodadhikaryそれは正しかった…私はOPが混乱していると思います。ネストされた属性を許可したいときに奇妙なことに、配列内のネストされたオブジェクトの属性を指定します。一方、複数のオブジェクトを入れ子にしたい場合は、ハッシュ内にラップします… api.rubyonrails.org / classes
j03w

@ j03w、ソースへのリンクをありがとう。はっきりしている。他の多くの人の役に立つと思うので、ここに回答を追加してください。
2013

回答:


181

ネストされた属性を許可したいときは奇妙なことに、配列内のネストされたオブジェクトの属性を指定します。あなたの場合、それは

@RafaelOliveiraの提案に従って更新

params.require(:measurement)
      .permit(:name, :groundtruth => [:type, :coordinates => []])

一方、複数のオブジェクトを入れ子にしたい場合は、次のようにハッシュ内にラップします。

params.require(:foo).permit(:bar, {:baz => [:x, :y]})


Railsには、これに関するかなり優れたドキュメントがあります。http//api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

さらに明確にするために、あなたはの実装を見ることができるpermitstrong_parameters自分自身:https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247


5
この回答ではどちらの場合も同じですが、実際には、{:groundtruth => [...]}の前後にある中括弧は省略可能です。これはハッシュですが、インタープリターは明示的な中括弧なしでハッシュの開始と終了を判別できます。
スピーキング

属性のネストされた配列は、ネストされた属性を許可しません。ネストされた属性とattr_accessorが「許可されていないパラメーター」としてアプリケーションにリストされています。まだ安全な解決策を探しています。
カタジナ

複数のネストされたオブジェクトの場合、これが機能するためのIDも許可する必要があります。詳細:stackoverflow.com/questions/18308714/...
ファブリスCarrega

1
これは、ネストされた属性の1つのセットのみを許可します。これは1対多の場合には機能しません。
AKWF 2018年

23

私の場合、この提案は役に立ちました:

  def product_params
    params.require(:product).permit(:name).tap do |whitelisted|
      whitelisted[:data] = params[:product][:data]
    end
  end

githubでのXavierのコメントのこのリンクを確認してください。

このアプローチは、params [:measurement] [:groundtruth]オブジェクト全体をホワイトリストに登録します。

元の質問属性を使用する:

  def product_params
    params.require(:measurement).permit(:name, :groundtruth).tap do |whitelisted|
      whitelisted[:groundtruth] = params[:measurement][:groundtruth]
    end
  end

4
余談ですが、これは依然として許可されていないパラメーターとしてログに表示されますが、モデルはとにかくそれらを受け入れます。
Weston Ganger、2016年

5
Rails 4はわかりませんが、私のRails 5プロジェクトでは、permit!ホワイトリストに登録するように呼び出す必要があります。そうしないと、タップしても許可されません。この場合、それはparams[:measurement][:groundtruth].permit!
nayiaw 2017

@nayiaw私も許可されていないメッセージを受け取りますが、追加permit!するとこのエラーNoMethodError (undefined method 許可が発生します!#<Array:0x007f80cb71ea00>): `の場合
wuliwong

@wuliwong permit!メソッドは、では使用できませんArray。アクセスするには、それぞれのクラスインスタンスにアクセスする必要がありますpermit!(久しぶりにクラス名を忘れましたが、このページにActionController::Parameters基づくようなものです)。
nayiaw

8

ネストされたオブジェクトを許可する:

params.permit( {:school => [:id , :name]}, 
               {:student => [:id, 
                            :name, 
                            :address, 
                            :city]},
                {:records => [:marks, :subject]})

0

新しいハッシュ表記のため、それがRails 5の場合: params.permit(:name, groundtruth: [:type, coordinates:[]])正常に動作します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.