ruby-on-rails - new - rails serializer nested
Atributos condicionales en serializadores de modelo activo (5)
La anulación es una buena idea, pero si usa la super
los atributos se calcularán antes de eliminar lo que desea. Si no te hace la diferencia, está bien, pero cuando lo haga, puedes usarlo:
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
¿Cómo puedo representar un atributo solo si alguna condición es verdadera?
Por ejemplo, quiero representar el atributo de token del usuario en la acción de creación.
Las options serializador se fusionaron en ActiveModel Serializadores y ahora están disponibles (desde 0.10).
Podría comenzar estableciendo una condición en el método de "inicialización" de los serializadores. Esta condición se puede transmitir desde cualquier lugar en su código, incluido en el hash de opciones que ''initialize'' acepta como segundo argumento:
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
En este caso, attr1 siempre se pasaría, mientras que los atributos condicionales se ocultarán si la condición es verdadera.
Obtendrá el resultado de esta serialización personalizada en cualquier otro lugar de su código de la siguiente manera:
custom_serialized_object = SomeCustomSerializer.new(object_to_serialize, {:condition => true})
¡Espero que esto haya sido útil!
Puedes anular el método de attributes
, aquí hay un ejemplo simple:
class Foo < ActiveModel::Serializer
attributes :id
def attributes(*args)
hash = super
hash[:last_name] = ''Bob'' unless object.persisted?
hash
end
end
También puedes hacerlo de esta manera:
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr, if: :condition?
def condition?
#condition code goes here
end
end
Por ejemplo:
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
EDITAR (Sugerido por Joe Essey ):
Con la última versión es aún más simple. No tiene que usar la if: :condition?
. En su lugar, puede usar la siguiente convención para lograr el mismo resultado.
class EntitySerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at
attribute :conditional_attr
def include_conditional_attr?
#condition code goes here
end
end
El ejemplo de arriba se vería así.
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
Ver documentation para más detalles.