【问题标题】:ActiveModel::Serializer returns null for empty has_one relationship (instead of JSON)ActiveModel::Serializer 为空的 has_one 关系返回 null(而不是 JSON)
【发布时间】:2020-03-11 10:08:23
【问题描述】:

问题

我们的 API 应返回 JSON 对象(但不是 JSON API)。 我们如何更改 ActiveModel::Serializer 以创建数据属性设置为 null 的 JSON 对象?

我们对空(has_one 关系)资源的响应是 NULL,但我们希望它是 JSON 格式 {data: NULL},就像我们收到的非空资源 {data: {... }},或者对于列表(has_many 关系)资源 {data: []}。

我们尝试过的

我们使用 ActiveModel::Serializer 并指定要命名为“数据”的键而不是资源名称(类似于 JSON API,但数据的内容是实体的直接 JSON 表示)。

模型

class User < ApplicationRecord
  has_one :profile

  def serializer_class
    V1::UserSerializer
  end
end

class Profile < ApplicationRecord
  belongs_to :user

  def serializer_class
    V1::ProfileSerializer
  end
end

序列化器

class ApplicationSerializer < ActiveModel::Serializer
  def json_key
    'data'
  end
end

class UserSerializer < ApplicationSerializer
  attributes :id, :created_at, :updated_at #we do not include the profile here
end

class ProfileSerializer < ApplicationSerializer
  attributes :id, :created_at, :updated_at
end

控制器

class ProfilesController < ::ApplicationController
  before_action :authenticate_user!
  def show
    @profile = current_user.profile
    render json: @profile
  end
end

回复

我们得到一个空资源(GET /profile)的响应(对我们来说是错误的):

NULL

我们正确地得到了一个非空资源的响应,它看起来像这样(不是 JSON API):

{
  data: {
    id: ...,
    createdAt: ...,
    updatedAt: ...
  }
}

我们想要什么

我们希望响应格式如下,以防(还)没有关联实体:

{
  data: null
}

【问题讨论】:

    标签: ruby-on-rails json serialization


    【解决方案1】:

    我们决定采用这种更严格的解决方案,在该解决方案中,我们以 404 响应空资源。

    def show
      @profile = current_user.profile
      raise ActiveRecord::RecordNotFound unless @profile
      render json: @profile
    end
    

    我们在 ApplicationController 中添加这个来处理异常:

    rescue_from ActiveRecord::RecordNotFound do |exception|
      render json: Api::ErrorSerializer.serialize(:not_found, 'Not Found'),
             status: :not_found
    end
    

    【讨论】:

      【解决方案2】:

      我发现这个(解决方法)解决了这个问题:

        def show
          @profile = current_user.profile
          if @profile
            render json: @profile
          else
            render json: { data: nil }
          end
        end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-24
        • 2014-08-15
        • 1970-01-01
        相关资源
        最近更新 更多