Подтвердить что ты не робот

Сильные параметры JSON API-рельсы

Я работаю над REST API в 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 [Моя модель статьи имеет название и описание]. Можете ли вы мне помочь?

4b9b3361

Ответ 1

Работа с параметрами JSONAPI немного отличается от обычных хэшей параметров Rails:

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

Первое, что вы должны заметить здесь, это то, что мы даже не используем ключ params[:data][:id] из данных JSON, поскольку идентификатор доступен из URL-адреса запроса (params[:id]). Если вы следуете шаблонам RESTful, возможно, вам не понадобится использовать параметр params[:data][:id].

В article_attributes мы используем вложенные вызовы, потому что мы хотим, чтобы Rails повышал ошибку ActionController::ParameterMissing, если предоставленные данные JSON не подтверждают спецификацию JSON API. Валильный Rails по умолчанию - это спасение с ответом 400 Bad Request - RailsAPI вернет 422 и объект ошибки JSON, если он правильно настроен для JSONAPI что мы и хотим.

Ответ 2

Я думаю, что лучший способ достичь этого теперь:

добавил

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"}

Ответ 3

Вы также можете использовать библиотеку json: api, которая предоставляет возможности десериализации, такие как http://jsonapi-rb.org, так что вам не нужно напрямую обрабатывайте формат json: api. В этом контексте ваш пример будет читать:

 class ArticlesController < ApiController
   deserializable_resource :article, only: [:create, :update]

   def article_params
     params.require(:article).permit(:title, :description)
   end

   # ...
 end