2015-07-23 11 views
13

Я работаю над REST API в Rails 4.2, и я хочу уважать формат JSON API. Мои Титулы, как это:Сильные параметры JSON API rails

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

Я попытался написать метод для сильного Params, как это:

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

, но когда я пытаюсь сделать Article.update_attributes(article_params) это говорит title and description parameters not permitted [моя статья модель имеет название и описание ]. Вы можете мне помочь?

+0

Попробуйте 'params.require (данные): .permit (: идентификатор,: название, описание:)' – Pavan

+0

я попробовал прямо сейчас. Такая же ошибка :(Я не могу понять, где проблема ... – kitz

+0

@Паван проверяет атрибуты [JSONAPI spec] (http://jsonapi.org/), которые должны быть завернуты в хэш-файл attriubtes. – max

ответ

14

Работа с JSONAPI PARAMS лишь незначительно отличается от работы с обычными Rails Params хэшей:

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, который мы хотим.

+1

В проекте, над которым я сейчас работаю, я также проверяю перед действием, что параметр data [: type] соответствует правильному типу и возвращает 422, если это не так. – max

+0

Должно ли это «разрешить» или «разрешить»? Я попробовал разрешить, и рельсы сказали, что такого метода не разрешено. – Zhang

+0

Это должно быть «разрешить», это была ошибка с моей стороны. – max

0

Вы также можете использовать библиотеку 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 
+0

Можете ли вы получить ссылку на документацию или онлайн-код, откуда именно появился ApiController? –

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

Да, но это не белый список параметров. Это тема вопроса. – max