4

Rails 5 を使用して JSON API を作成しています。

私のコントローラーは、次のような 1 つのrequire属性を持つ強力なパラメーターを使用します。

params.require(:require_attribute).permit(:permit_attribute1,:permit_attribute2)

通常、次のように JSON を送信する必要があります。

{
    "require_attribute":{
        "permit_attribute1": "data",
        "permit_attribute2": "data"
    }
}

必要な属性が欠落している場合、次のメッセージを取得する必要があります。

"ActionController::ParameterMissing: param is missing or the value is empty: require_attribute"

私の問題は、JSON から必要な属性を削除し、permit強力なパラメーターと共通する属性が 1 つある場合、それが機能することです。

私が送信するJSON:

{
    "permit_attribute1": "data",
}

paramsを取得すると、次のようになりlogます。

{"permit1"=>data, "controller"=>"mycontroller", "action"=>"create", "require_attribute"=>{"permit1"=>1} }

Rails は、エラーを発生させる代わりに、必要なキーでハッシュを作成するようです。しかし、JSON を受け取ったときに必須の属性を強制したいと考えています。

誰にもアイデアがありますか?

4

2 に答える 2

4

強力なパラメーター API は、最も一般的なユース ケースを念頭に置いて設計されています。これは、すべてのホワイトリストの問題を処理するための特効薬として意図されたものではありません。

http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters

require(key)

パラメータが存在することを確認します。存在する場合は、指定されたキーのパラメーターを返します。存在しない場合は ActionController::ParameterMissingエラーが発生します。

http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-require

上記からわかるように、「フラット」ハッシュで必須パラメーターを設定することは、実際には強力なパラメーター API が構築されている目的ではありません。むしろ、パラメーターが単一のキーの下にネストされているレールの規則に基づいて構築されています。

「.require」を使用して一度に 1 つのキーを取得することもできますが、それはかなり面倒です。

代わりに、キーが存在しない限り例外を発生させることで、それが何をするかをシミュレートできます。

def something_params
  req = [:required_attribute1, :required_attribute2]
  req.each do |k|
    raise ActionController::ParameterMissing.new(k) unless params[k].present?
  end
  whitelisted = params.permit(:permit_attribute1, :permit_attribute2)
end

ただし、より良い方法は、モデル レベルの検証を使用するActionController::ParameterMissingことです。これは、要求の一般的な書式設定がオフであることを示すものであり、必要な属性が欠落していることではありません。たとえば、JSONAPI.org 形式のリクエストの場合、次のようにします。

params.require(:data).require(:attributes).permit(:email, :username)

これにより、リクエストが標準に準拠することが保証されます。ただし、メールなしでユーザーを作成できないようにすることは、モデル レベルの問題です。

于 2016-02-02T13:18:00.357 に答える
2

はい、デフォルトでは API モードの Rails は JSON リクエスト パラメータをコントローラ クラスからその名前を推測するハッシュにラップします。詳細はこちらでご覧いただけます。

アプリでこの機能が必要ない場合は、配列:jsonから削除するだけです。または、上記のように、コントローラー レベルできめ細かい制御を使用することもできます。:formatconfig\initializers\wrap_parameters.rb

これにより、必要なキーが存在しない場合に例外が発生します。

于 2019-07-18T07:42:05.980 に答える