如何在Rails Active Model Serializer v0.8中有条件地包含关联

tim*_*one 7 ruby-on-rails active-model-serializers

我已经将AMS(0.8)与Rails 3.2.19一起使用,但我真正为它们努力的一个地方是如何控制序列化器是否包含它们的关联.我显然使用AMS来构建JSON Api.有时,序列化程序是叶子或最远的元素,有时它是顶级的,需要包含关联.我的问题是这样做的最佳方式是什么,或者是我在下面工作的解决方案(或者是最佳解决方案).

我已经看到了一些讨论,但我发现它们非常令人困惑(并且基于版本).很明显,对于Serializer属性或关联,有一个include_XXX?每个方法,你可以在这里返回truthy或falsey语句.

这是我提出的代码 - 它是一个拥有许多wine_items的酿酒师.这是你怎么做的?

模型类:

class WineItem < ActiveRecord::Base
  attr_accessible :name, :winemaker_id
  belongs_to :winemaker

end

class Winemaker < ActiveRecord::Base
  attr_accessible :name
  has_many :wine_items
  attr_accessor :show_items
end
Run Code Online (Sandbox Code Playgroud)

串行器:

class WinemakerSerializer < ActiveModel::Serializer
  attributes :id, :name
  has_many :wine_items 

  def include_wine_items?
    object.show_items
  end
end

class WineItemSerializer < ActiveModel::Serializer
  attributes :id, :name
end
Run Code Online (Sandbox Code Playgroud)

在我的控制器中:

class ApiWinemakersController < ApplicationController
  def index
    @winemakers=Winemaker.all
    @winemakers.each { |wm| wm.show_items=true }
    render json: @winemakers, each_serializer: WinemakerSerializer, root: "data"
  end
end
Run Code Online (Sandbox Code Playgroud)

Dan*_*n L 1

我自己遇到了这个问题,这是迄今为止最干净的解决方案(但我不喜欢它)。

此方法允许您执行以下操作:

/parents/1?include_children=true

或者使用更简洁的语法,例如:

/parents/1?include=[children], ETC...

# app/controllers/application_controller.rb
class ApplicationController
  # Override scope for ActiveModel-Serializer (method defined below)
  # See: https://github.com/rails-api/active_model_serializers/tree/0-8-stable#customizing-scope
  serialization_scope(:serializer_scope)

  private

  # Whatever is in this method is accessible in the serializer classes.
  # Pass in params for conditional includes.
  def serializer_scope
    OpenStruct.new(params: params, current_user: current_user)
  end
end

# app/serializers/parent_serializer.rb
class ParentSerializer < ActiveModel::Serializer
  has_many :children

  def include_children?
    params[:include_children] == true
    # or if using other syntax:
    # params[:includes].include?("children")
  end
end
Run Code Online (Sandbox Code Playgroud)

对我来说有点黑客,但它有效。希望你觉得它有用!