【问题标题】:ActiveModel::Serializers JSON API nested associations include?ActiveModel::Serializers JSON API 嵌套关联包括?
【发布时间】:2017-11-01 01:14:45
【问题描述】:

我在 Stackoverflow 上没有找到完全相同的问题。除了 AMS 变化如此之快,甚至 2 年前的答案也经常过时。

我只使用 Rails 5 API 和 gem 'active_model_serializers' (AMS)(版本 0.10.6)。

我也使用 JSONAPI 响应格式 - 而不仅仅是 JSON。

我需要渲染一个嵌套的包含——现在不仅仅是嵌套关系。

代码示例:

序列化器1:

class QuestionSerializer < ActiveModel::Serializer
  attributes :id, :title, :created_at, :updated_at
  belongs_to :user
end

序列化器2:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email
  has_many :cities
end

序列化器3:

class CitySerializer < ActiveModel::Serializer
  attributes :id, :name
end

控制器:

def index
  @questions = Question.all
  render json: @questions, include: [:user, 'user.city']
end

我收到此回复:

{
  "data": [
    {
      "id": "1",
      "type": "questions",
      "attributes": {
        "title": "First",
        "created-at": "2017-03-27T13:22:15.548Z",
        "updated-at": "2017-03-27T13:22:16.463Z"
      },
      "relationships": {
        "user": {
          "data": {
            "id": "3",
            "type": "users"
          }
        }
      }
    }
  ],
  "included": [
    {
      "id": "3",
      "type": "users",
      "attributes": {
        "email": "client2@example.com"   
      },
      "relationships": {
        "cities": {
          "data": [
            {
              "id": "75",
              "type": "cities"
            }
          ]
        }
      }
    }
  ]
}

我确实得到了一个嵌套关系city。我什至得到了城市id

但问题是 - 我如何获得其他 city 属性,例如 name?我需要另一个 include 部分 - 可能在当前 include 部分内(嵌套?)。

如何做到这一点? (没有任何额外的宝石)

【问题讨论】:

    标签: ruby-on-rails active-model-serializers json-api


    【解决方案1】:

    您还应该在参数“字段”中包含用户,并在参数包含中使用字符串而不是符号

    render json: @questions, fields: [:title, :user], include: ['user', 'user.cities']
    

    【讨论】:

      【解决方案2】:

      我找到了一些解决方案。我不知道它有多干净。它基于两个先决条件:

      1. https://github.com/rails-api/active_model_serializers/blob/db6083af2fb9932f9e8591e1d964f1787aacdb37/docs/general/adapters.md#included

      2. ActiveModel Serializers: has_many with condition at run-time?

      我应用了条件关系和user-all-permissive include

      控制器:

      @questions = Question.all
      
      render json: @questions,
      
      show_user: (param? params[:user]),
      
      show_cities: (param? params[:city]),
      
      include: [:user, "user.**"]
      

      序列化器1:

      class QuestionSerializer < ActiveModel::Serializer
        attributes :id, :title, :created_at, :updated_at
        belongs_to :user, if: -> { should_render_user }
      
        def should_render_user
          @instance_options[:show_user]
        end   
      end
      

      序列化器2:

      class UserSerializer < ActiveModel::Serializer
        attributes :id, :email
        has_many :cities, if: -> { should_render_cities }
      
        def should_render_cities
          @instance_options[:show_cities]
        end    
      end
      

      序列化器3:

      class CitySerializer < ActiveModel::Serializer
        attributes :id, :name
      end
      

      帮手:

      def param? param
      
        param && param != "false" && param != "nil"
      
      end
      

      条件关系允许控制实际渲染哪个include

      【讨论】:

        【解决方案3】:

        以下应该做到这一点

        render json: @questions, include: [:categories, user: :city]
        

        【讨论】:

        • 不,它没有。结果是一样的。
        • 你必须从某处为城市模型设置属性
        • 通常您将获得所有属性,除非您允许某些特定属性
        • 我不懂你。
        猜你喜欢
        • 1970-01-01
        • 2019-02-05
        • 2014-06-19
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多