Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strong parameters JSON API rails

I am working to an REST API in Rails 4.2 and I want to respect JSON API format. My params are like this:

{
  "data":{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "this is title",
      "description": "This is description"
    }
}

I tried to write a method for strong params like this:

def article_params
    params.require(:data).permit(:id, attributes: [:title, :description])
end

but when I try to do Article.update_attributes(article_params) it says title and description parameters not permitted [My Article model has title and description]. Can you help me?

like image 819
kitz Avatar asked Jul 23 '15 17:07

kitz


2 Answers

Dealing with JSONAPI params is only slightly different than dealing with the usual Rails params hashes:

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

First thing you should notice here is that we are not even using params[:data][:id] key from the JSON data at all since the ID is available from the request url (params[:id]). If you follow RESTful patterns chances are that you never will need to use the params[:data][:id] parameter.

In article_attributes we are using nested require calls because we want Rails to raise an ActionController::ParameterMissing error unless the provided JSON data confirms to the JSON API spec. The vanilla Rails default is to rescue with a 400 Bad Request response - RailsAPI will return 422 and an JSON error object if it is properly set up for JSONAPI which is what we want.

like image 162
max Avatar answered Sep 29 '22 12:09

max


I guess the best way to achieve that now is :

added

gem 'active_model_serializers' 

to your Gemfile

and this on your controller

ActiveModelSerializers::Deserialization.jsonapi_parse(params)

bonus handle dash for you.

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"}
like image 38
Joel AZEMAR Avatar answered Sep 29 '22 12:09

Joel AZEMAR