简体   繁体   中英

Conditional attributes and methods in rails serializer 0.10

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

Here I want to put condition on action basic of the controller.

For example I will like to send conditional_attributes for only index action and not for other actions.

But rails "active_model_serializers", "~> 0.10.0" does not give any such things according to my knowledge.

Something like this should do the trick:

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

You can also use :unless for negated conditions.

You can use instance_options or instance_reflections in your conditions if you need them (see https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/howto/passing_arbitrary_options.md ) or you can use scope s (see https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/serializers.md#scope )

Note: To the best of my knowledge, this only works with attribute and association methods – it doesn't work with attributes (see https://github.com/rails-api/active_model_serializers/blob/0-10-stable/lib/active_model/serializer.rb#L204-L210 ) since it doesn't pass options along.

I read your comment regarding sticking with AM Serializers, but I'll still point it out: If you're looking for a more robust and flexible solution than AM Serializers, jsonapi-serializer or Blueprinter work quite well and both have support for conditional fields as well as conditional associations.

I assume you're trying to render from the controller.

You can pass options to your serializer from the call to render:

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

You can then access that option in your serializer definition, via @instance_options[:your_option] .

Here, you would likely have something like:

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? and return_extra_attributes? would be method defined in your controller

documentation here: https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/howto/passing_arbitrary_options.md

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM