强参数JSON API rails

时间:2015-07-23 17:44:24

标签: ruby-on-rails json api rest ruby-on-rails-4

我正在使用Rails 4.2中的REST API,我想尊重JSON API格式。我的参数是这样的:

<li>2</li>

我试着为这样的强对数写一个方法:

{
  "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) [我的文章模型有标题和说明]。你能救我吗?

3 个答案:

答案 0 :(得分:17)

处理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

首先要注意的是,我们甚至根本没有使用JSON数据中的params[:data][:id]密钥,因为ID可以从请求URL(params[:id])获得。如果你遵循RESTful模式,你可能永远不需要使用params[:data][:id]参数。

article_attributes中,我们使用嵌套的require调用,因为除非提供的JSON数据符合JSON API规范,否则我们希望Rails引发ActionController::ParameterMissing错误。 vanilla Rails的默认设置是使用400 Bad Request响应进行救援 - 如果为JSONAPI正确设置了JSON错误,RailsAPI将返回422和JSON错误对象。

答案 1 :(得分: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"}

答案 2 :(得分: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