REST API in Rails 4.2で、尊重したい JSON API 形式です。私のパラメーターは次のようになります。
_{
"data":{
"type": "articles",
"id": "1",
"attributes": {
"title": "this is title",
"description": "This is description"
}
}
_
私はこのような強力なパラメータのメソッドを書こうとしました:
_def article_params
params.require(:data).permit(:id, attributes: [:title, :description])
end
_
しかし、Article.update_attributes(article_params)
を実行しようとすると、_title and description parameters not permitted
_ [私の記事モデルにはタイトルと説明があります]と表示されます。手伝って頂けますか?
JSONAPI paramsの処理は、通常のRailsparamsハッシュの処理とわずかに異なります。
class ArticlesController < ApiController
before_filter :set_article, only: [:show, :edit, :update, :destroy]
# POST /api/v1/articles
def create
@article = Article.new(article_attributes)
# ...
end
# PATCH /api/v1/articles/:id
def update
@article.update(article_attributes)
# ...
end
# ...
private
def set_article
@article = Article.find(params[:id])
end
def article_attributes
params.require(:data)
.require(:attributes)
.permit(:title, :description)
end
end
ここで最初に注意する必要があるのは、IDがリクエストURL(params[:data][:id]
)から入手できるため、JSONデータのparams[:id]
キーをまったく使用していないことです。 RESTfulパターンに従う場合、params[:data][:id]
パラメーターを使用する必要がない可能性があります。
article_attributes
では、ネストされたrequire呼び出しを使用しています。これは、提供されたJSONデータがJSON API仕様を確認しない限り、RailsでActionController::ParameterMissing
エラーを発生させるためです。 Vanilla Railsのデフォルトは、400 Bad Request応答でレスキューすることです- RailsAPI は、必要なJSONAPI用に適切に設定されている場合、422とJSONエラーオブジェクトを返します。
私は今それを達成するための最良の方法は:
追加
gem 'active_model_serializers'
あなたのGemfileに
そしてこれはあなたのコントローラーに
ActiveModelSerializers::Deserialization.jsonapi_parse(params)
あなたのためのボーナスハンドルダッシュ。
params = { "data": {
"attributes": {
"title": "Bucket List",
"created-by": "John Doe"
},
"type": "todos"
}
}
params = ActionController::Parameters.new(params)
ActiveModelSerializers::Deserialization.jsonapi_parse(params)
=> {:title=>"Bucket List", :created_by=>"John Doe"}
http://jsonapi-rb.org などの逆シリアル化機能を提供するjson:apiライブラリを使用して、json:api形式を直接処理する必要がないようにすることもできます。その文脈では、あなたの例は次のようになります。
class ArticlesController < ApiController
deserializable_resource :article, only: [:create, :update]
def article_params
params.require(:article).permit(:title, :description)
end
# ...
end