【问题标题】:Conditional attributes and methods in rails serializer 0.10rails 序列化器 0.10 中的条件属性和方法
【发布时间】:2025-12-10 15:15:01
【问题描述】:
class Api::V1::BookSerializer < ActiveModel::Serializer
  attributes :id, :status, :name, :author_name, :published_date

  attributes :conditional_attributes if condition_1?
  belongs_to :user if condition_2?
end

这里我想对控制器的基本动作设置条件。

例如,我只想为索引操作而不是其他操作发送条件属性。

但据我所知,rails "active_model_serializers", "~> 0.10.0" 没有给出任何这样的东西。

【问题讨论】:

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


    【解决方案1】:

    这样的事情应该可以解决问题:

    class Api::V1::BookSerializer < ActiveModel::Serializer
      attributes :id, :status, :name, :author_name, :published_date
    
      attribute :conditional_attribute, if: :some_condition?
      belongs_to :conditional_association, if: :some_other_condition?
    
      private
    
      def some_condition?
        # some condition
      end
    
      def some_other_condition?
        # some other condition
      end
    end
    

    您也可以将:unless 用于否定条件。

    如果需要,您可以在条件中使用instance_optionsinstance_reflections(请参阅https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/howto/passing_arbitrary_options.md),或者您可以使用scopes(请参阅https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/serializers.md#scope

    注意:据我所知,这仅适用于 attribute 和关联方法 - 它不适用于 attributes(请参阅 https://github.com/rails-api/active_model_serializers/blob/0-10-stable/lib/active_model/serializer.rb#L204-L210),因为它不会传递选项。

    我阅读了您关于坚持使用 AM 序列化器的评论,但我仍然要指出:如果您正在寻找比 AM 序列化器更强大和灵活的解决方案,jsonapi-serializerBlueprinter 工作得很好,而且两者都很好支持条件字段以及条件关联。

    【讨论】:

      【解决方案2】:

      我假设您正在尝试从控制器进行渲染。

      您可以将选项从对渲染的调用中传递给您的序列化程序:

        render json: @track, serializer: Api::V1::BookSerializer, return_user: return_user?, return_extra_attributes: return_extra_attributes?
      

      然后您可以通过@instance_options[:your_option] 在序列化程序定义中访问该选项。

      在这里,您可能会有类似的内容:

      class Api::V1::BookSerializer < ActiveModel::Serializer
        attributes :id, :status, :name, :author_name, :published_date
      
        attributes :conditional_attributes if return_conditional_attributes?
        belongs_to :user if return_user?
      
        def return_conditional_attributes?
          @instance_options[:return_extra_attributes]
        end
      
        def return_user?
          @instance_options[:return_user]
        end
      end
      

      return_extra_attributes?return_extra_attributes? 将是您的控制器中定义的方法

      此处的文档:https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/howto/passing_arbitrary_options.md

      【讨论】:

      • 这段代码完全是错误的:你不能在类级别访问实例变量。
      • 你说得对,我走得太快了,会进行编辑。虽然我确实运行了类似的代码,但它有效