Post 请求上的 FastJsonapi ID 必填字段,无法处理的实体?

FastJsonapi ID Mandatory Field on Post Request, Unprocessable Entity?

我在我的项目中添加了这个 gem 用于 json 序列化:gem 'jsonapi-serializer'

在 post 请求中,我在创建时收到以下错误:
FastJsonapi::MandatoryField (id is a mandatory field in the jsonapi spec)

我的模型很简单:

class Post < ApplicationRecord
    belongs_to :profile
    belongs_to :category
    validates :title, presence: true
    validates :content, presence: true
    validates :category_id, presence: true
    validates :profile_id, presence: true
end

post 控制器中此方法的保存部分是出现问题的地方:

    def create
            @post = Post.new(post_params)
 
            if @post.save
                render json: PostSerializer.new(@post).serializable_hash.as_json, status: :created
            else
                render json: PostSerializer.new(@post.errors).serializable_hash.as_json, status: :unprocessable_entity
            end
    end

在我的 post 请求中,我使用 JSON.Stringify() 控制台日志打印:
{"title":"Hello","content":"Hello World","category_id":"1","profile_id":"1"}

Rails' 打印参数:

Parameters: {"title"=>"Hello", "content"=>"Hello World", "category_id"=>"1", "profile_id"=>"1", "post"=>{"title"=>"Hello", "content"=>"Hello World", "category_id"=>"1", "profile_id"=>1}}

我之前尝试的格式是将数据包裹在一个Post对象中,也是同样的错误。

我已经尝试模拟 id 但我仍然收到错误。我还尝试删除序列化程序,但出现了一个普通的无法处理的实体错误。不过,通过控制台直接创建 post 是可行的。
在另一个项目上测试,我没有收到任何错误,所以这可能不是序列化程序的错误。但是,我不确定在这种情况下还能在哪里查看。提前致谢!

编辑:Post请求的序列化程序代码

class PostSerializer
  include FastJsonapi::ObjectSerializer
  belongs_to :profile
  attributes :id, :category_id, :title, :content
end

这里的问题是您将 @post.errors 返回的 ActiveModel::Errors 对象传递给需要模型实例的 PostSerializer。据我所知,jsonapi-serializer 没有内置的验证错误处理。

相反,您想为错误创建一个特殊的序列化程序,或者只是从 ActiveModel::Errors 对象手动创建 JSON 响应。这是 json:api docs:

中给出的示例
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/vnd.api+json

{
  "errors": [
    {
      "source": { "pointer": "/data/attributes/firstName" },
      "title": "Invalid Attribute",
      "detail": "First name must contain at least three characters."
    },
    {
      "source": { "pointer": "/data/attributes/firstName" },
      "title": "Invalid Attribute",
      "detail": "First name must contain an emoji."
    }
  ]
}

问题已解决。

问题出在以下行:

@post = Post.new(post_params)

在我的问题中,我忘了提到我已经尝试过以下方法:

@profile = current_user.profile
@post = @profile.post.new(post_params)

我把它和我使用的测试项目混淆了,对于给您带来的不便,我们深表歉意。 出于某种原因,以下工作:

@post = current_user.profile.post.build(post_params)

据我所知,理论上这两种方法没有区别,所以我不确定为什么这样可以解决问题。我希望有人能解释一下。谢谢:)