web-dev-qa-db-ja.com

強力なパラメーターJSONAPI rails

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_ [私の記事モデルにはタイトルと説明があります]と表示されます。手伝って頂けますか?

14
kitz

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エラーオブジェクトを返します。

18
max

私は今それを達成するための最良の方法は:

追加

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"}
2
Joel AZEMAR

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
0
beauby