【问题标题】:how to dynamic add attributes on Active Model Serializers如何在活动模型序列化器上动态添加属性
【发布时间】:2014-11-15 00:59:33
【问题描述】:

我想决定在我的控制器中输出的属性数量。

但我不知道必须这样做吗?

controller.rb

  respond_to do |format|
    if fields
      # less attributes : only a,c
    elsif xxx
      # default attributes
    else
      # all attributes : a,c,b,d,...
    end
  end

serializer.rb

class WeatherLogSerializer < ActiveModel::Serializer
  attributes :id, :temperature
  def temperature
    "Celsius: #{object.air_temperature.to_f}"
  end
end

【问题讨论】:

    标签: ruby-on-rails-4 active-model-serializers


    【解决方案1】:

    我可能会为所有人使用不同的端点,但您也可以传入不同的 url 参数或类似的东西。通常情况下,我认为您希望默认设置更加有限。

    我建议这样做:

    控制器

    所有人的不同端点

    render json: objects, each_serializer: WeatherLogAllSerializer
    

    允许自定义字段

    fields = params[:fields] # Csv string of specified fields.
    
    # pass the fields into the scope
    if fields.present?
      render json: objects, each_serializer: WeatherLogCustomSerializer, scope: fields
    else
      render json: objects, each_serializer: WeatherLogSerializer
    end
    

    三种不同的序列化器:all、default、custom

    全部

    class WeatherLogAllSerializer < ActiveModel::Serializer
      attributes :id, :temperature, :precipitation, :precipitation
      has_many :measurements
    
      def temperature
        "Celsius: #{object.air_temperature.to_f}"
      end
    end
    

    默认

    class WeatherLogSerializer < ActiveModel::Serializer
      attributes :id, :temperature
      def temperature
        "Celsius: #{object.air_temperature.to_f}"
      end
    end
    

    自定义

    class WeatherLogCustomSerializer < WeatherLogSerializer
    
      def attributes
        data = super
        if scope
          scope.split(",").each do |field|
            if field == 'precipitation'
              data[:precipitation] = object.precipitation
            elsif field == 'humidity'
              data[:humidity] = object.humidity
            elsif field == 'measurements'
              data[:measurements] = ActiveModel::ArraySerializer.new(object.measurements)
            end
          end
        end
        data
      end
    end
    

    【讨论】:

    • 这对我有帮助,但是对于 AMS 版本 0.10.0,我必须在 attributes 定义中添加一个参数。所以唯一的区别是前两行,def attributes(attrs)data = super(attrs)
    【解决方案2】:

    您可以使用自定义序列化程序创建不同的序列化程序和respond_withrender,如下所示:

    # serialize an array of WeatherLog(s)
    render json: objects, each_serializer: WeatherLogSerializer
    # serialize a WeatherLog
    render json: object, serializer: WeatherLogSimpleSerializer 
    
    # just gimme id and temp
    class WeatherLogSimpleSerializer < ActiveModel::Serializer
      attributes :id, :temperature
      def temperature
        "Celsius: #{object.air_temperature.to_f}"
      end
    end
    
    # gimme everything
    class WeatherLogSerializer < ActiveModel::Serializer
      attributes(*WeatherLog.attribute_names.map(&:to_sym))
    end
    

    【讨论】:

      猜你喜欢
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      相关资源
      最近更新 更多