串行器加载ActiveModel:用的has_many在运行时的条件?

问题描述 投票:6回答:3

我用导轨(5.0.1)和active_model_serializers(0.10.2)。我想以某种有条件序列化has_many协会:

class Question < ApplicationRecord
    has_many :responses, :inverse_of => :question
end

class Response < ApplicationRecord
    belongs_to :question, :inverse_of => :responses
end

class QuestionSerializer < ActiveModel::Serializer
  attributes :id, :title, :created_at, :updated_at
  has_many :responses
end

class ResponseSerializer < ActiveModel::Serializer
  attributes :id, :title
end

我用jsonapi和查询http://localhost:3000/api/questions/1我得到这样的响应:

回应1:

{
  "data": {
    "id": "1",
    "type": "questions",
    "attributes": {
      "title": "First",
      "created-at": "2017-02-14T09:49:20.148Z",
      "updated-at": "2017-02-14T13:55:37.365Z"
    },
    "relationships": {
      "responses": {
        "data": [
          {
            "id": "1",
            "type": "responses"
          }
        ]
      }
    }
  }
}

如果我从has_many :responses删除QuestionSerializer我得到这样的:

响应2:

{
  "data": {
    "id": "1",
    "type": "questions",
    "attributes": {
      "title": "First",
      "created-at": "2017-02-14T09:49:20.148Z",
      "updated-at": "2017-02-14T13:55:37.365Z"
    }
  }
}

如何有条件地获得在运行时无论是反应-1或响应-2?我试图找到的所有建议 - 既不符合AMS 0.10.2工作。目前,条件只能是这样的:

class QuestionSerializer < ActiveModel::Serializer
  attributes :id, :title, :created_at, :updated_at
  has_many :responses if true
end

要么:

class QuestionSerializer < ActiveModel::Serializer
  attributes :id, :title, :created_at, :updated_at
  has_many :responses if false
end

在这两个情况下,我真的得到任何回应-1或响应-2。但是,这是硬编码,我想设置了一个param也许通过串行化器或做一些类似的事情。

我该怎么办?

ruby-on-rails active-model-serializers
3个回答
3
投票

我想你已经有种回答了自己的问题。如果你看看AMS documentation for associations它说,条件语句的支持。

从我可以告诉你只是一个错字远

class QuestionSerializer < ActiveModel::Serializer
   has_many :responses, if: false
end

该方法attributes还支持if选项,如所描述here

什么是你的active_model_serializers版本?

编辑:我有我的回答错误了。我使用active_model_serializers (0.10.3),我能够做到

class QuestionSerializer < ActiveModel::Serializer
   has_many :responses, if: -> { false }
end

if选项与任一方法,特效或字符串。我想你可以通过提供一种方法来作为条件在运行时决定。

class QuestionSerializer < ActiveModel::Serializer
  attr_writer :should_render_association
  has_many :responses, if: -> { should_render_association }
end
# Usage: 
serializer = QuestionSerializer.new(question)
serializer.should_render_association = false
serializer.to_json
# => no "responses" key

3
投票

由于@gkats,我找到了答案(AMS 0.10.2):

class QuestionSerializer < ActiveModel::Serializer
  attributes :id, :title, :created_at, :updated_at
  has_many :responses, if: -> { should_render_association }

  def should_render_association
    @instance_options[:show_children]
  end
end

class Api::ResponsesController < Api::ApplicationController
  def show
    render json: @response, show_children: param[:include_children]
  end
end

问题是所有关于语法:if:在串行应适用于块,而不是给一个函数。


0
投票

我挣扎了很多有同样的问题。这里是工作的解决方案我想通。

except: [:key_one, :key_two]作为参数初始化。

class QuestionsController
    def index
        @questions = Question.all
        render(json: ActiveModel::ArraySerializer.new(@questions,
                                                      each_serializer: QuestionSerializer,
                                                      root: 'questions',
                                                      except: [:responses])
        )
    end

    def show 
        # you can also pass the :except arguments here
        # render(json: QuestionSerializer.new(@question, except: [:responses]).to_json)
        render(json: QuestionSerializer.new(@question).to_json)
    end
end

https://www.rubydoc.info/gems/active_model_serializers/0.9.3/ActiveModel%2FArraySerializer:initialize

https://www.rubydoc.info/gems/active_model_serializers/0.9.1/ActiveModel%2FSerializer:initialize

© www.soinside.com 2019 - 2024. All rights reserved.