Comment rendre un attribut uniquement si une condition est vraie?
Par exemple, je souhaite rendre l'attribut de jeton de l'utilisateur lors de la création d'une action.
Vous pouvez également le faire de cette façon:
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr, if: :condition?
def condition?
#condition code goes here
end
end
Par exemple:
class UserSerializer < ActiveModel::Serializer
attributes :id, :username, :name, :email, :created_at, :updated_at
attribute :auth_token, if: :auth_token?
def created_at
object.created_at.to_i
end
def updated_at
object.updated_at.to_i
end
def auth_token?
true if object.auth_token
end
end
Cette méthode ne fonctionne pas avec la dernière version (0.10
)
Avec la version 0.8
c'est encore plus simple. Vous n'êtes pas obligé d'utiliser le if: :condition?
. Au lieu de cela, vous pouvez utiliser la convention suivante pour obtenir le même résultat.
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr
def include_conditional_attr?
#condition code goes here
end
end
L'exemple ci-dessus ressemblerait à ceci.
class UserSerializer < ActiveModel::Serializer
attributes :id, :username, :name, :email, :created_at, :updated_at
attribute :auth_token
def created_at
object.created_at.to_i
end
def updated_at
object.updated_at.to_i
end
def include_auth_token?
true if object.auth_token
end
end
Voir documentation 0.8 pour plus de détails.
vous pouvez remplacer la méthode attributes
, voici un exemple simple:
class Foo < ActiveModel::Serializer
attributes :id
def attributes(*args)
hash = super
hash[:last_name] = 'Bob' unless object.persisted?
hash
end
end
Vous pouvez commencer par définir une condition sur la méthode d'initialisation des sérialiseurs. Cette condition peut être passée de n'importe où ailleurs dans votre code, incluse dans le hachage d'options que "initialize" accepte comme deuxième argument:
class SomeCustomSerializer < ActiveModel::Serializer
attributes :id, :attr1, :conditional_attr2, :conditional_attr2
def initialize(object, options={})
@condition = options[:condition].present? && options[:condition]
super(object, options)
end
def attributes(*args)
return super unless @condition #get all the attributes
attributes_to_remove = [:conditional_attr2, :conditional_attr2]
filtered = super.except(*attributes_to_remove)
filtered
end
end
Dans ce cas, attr1 sera toujours transmis, tandis que les attributs conditionnels seront masqués si la condition est vraie.
Vous obtiendriez le résultat de cette sérialisation personnalisée partout ailleurs dans votre code comme suit:
custom_serialized_object = SomeCustomSerializer.new(object_to_serialize, {:condition => true})
J'espère que c'était utile!
Serializer options ont été fusionnés dans ActiveModel Serializers et sont maintenant disponibles (depuis 0.10).
Remplacer est une bonne idée, mais si vous utilisez le super
les attributs seront calculés avant de supprimer ce que vous voulez. Si cela ne fait aucune différence pour vous, d'accord, mais quand c'est le cas, vous pouvez l'utiliser:
def attributes(options={})
attributes =
if options[:fields]
self.class._attributes & options[:fields]
else
self.class._attributes.dup
end
attributes.delete_if {|attr| attr == :attribute_name } if condition
attributes.each_with_object({}) do |name, hash|
unless self.class._fragmented
hash[name] = send(name)
else
hash[name] = self.class._fragmented.public_send(name)
end
end
end
ps: v0.10.0.rc3