Hoe geef ik een attribuut alleen weer als een voorwaarde waar is?
Ik wil bijvoorbeeld het tokenkenmerk van de gebruiker weergeven bij het maken van een actie.
Antwoord 1, autoriteit 100%
In de nieuwste versie (0.10.x
) kun je het ook op deze manier doen:
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr, if: :condition?
def condition?
#condition code goes here
end
end
Bijvoorbeeld:
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
EDIT (Voorgesteld door Joe Essey) :
Deze methode werkt niet met de nieuwste versie (0.10
)
Met de versie 0.8
is het nog eenvoudiger. U hoeft de if: :condition?
niet te gebruiken. In plaats daarvan kunt u de volgende conventie gebruiken om hetzelfde resultaat te bereiken.
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr
def include_conditional_attr?
#condition code goes here
end
end
Het bovenstaande voorbeeld ziet er als volgt uit.
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
Zie 0.8 documentatievoor meer details.
Antwoord 2, autoriteit 62%
u kunt de methode attributes
overschrijven, hier is een eenvoudig voorbeeld:
class Foo < ActiveModel::Serializer
attributes :id
def attributes(*args)
hash = super
hash[:last_name] = 'Bob' unless object.persisted?
hash
end
end
Antwoord 3, autoriteit 5%
Je zou kunnen beginnen met het instellen van een voorwaarde voor de serializers ‘initialize’-methode. Deze voorwaarde kan worden doorgegeven van waar dan ook in uw code, opgenomen in de hash-opties die ‘initialiseren’ als tweede argument accepteert:
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
In dit geval zou attr1 altijd worden doorgegeven, terwijl de voorwaardelijke kenmerken verborgen zouden zijn als de voorwaarde waar is.
Je krijgt het resultaat van deze aangepaste serialisatie waar dan ook in je code als volgt:
custom_serialized_object = SomeCustomSerializer.new(object_to_serialize, {:condition => true})
Ik hoop dat dit nuttig was!
Antwoord 4, autoriteit 3%
Serializer optieszijn samengevoegd in ActiveModel Serializers en zijn nu beschikbaar (sinds 0.10 ).
Antwoord 5
Overschrijven is een goed idee, maar als u de super
gebruikt, worden de kenmerken berekend voordat u verwijdert wat u wilt. Als het voor jou geen verschil maakt, oké, maar als dat wel het geval is, kun je het gebruiken:
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
Antwoord 6
Hier leest u hoe u parameters rechtstreeks aan de serializer-instantie kunt doorgeven en kenmerken toonof verbergtop basis van deze parameters in de serializer-declaratie.
Het werkt ook met serializers voor ouder en kind.
Controller of parent-serializer:
ActiveModelSerializers::SerializableResource.new(object.locations, {
each_serializer: PublicLocationSerializer,
params: {
show_title: true
},
})
Serializer met voorwaarden:
class PublicLocationSerializer < ActiveModel::Serializer
attributes :id, :latitude, :longitude, :title
def title
object.title if @instance_options[:params][:show_title]
end
end