ruby on rails - new - Control de condición condicional con ActiveModel:: Serializadores
rails api json serializer (3)
Estoy construyendo una API usando ActiveModel :: Serializadores . ¿Cuál es la mejor manera de descargar datos condicionalmente usando params?
Así que puedo hacer peticiones como GET /api/customers
:
"customers": {
"first_name": "Bill",
"last_name": "Gates"
}
Y GET /api/customers?embed=address,note
"customers": {
"first_name": "Bill",
"last_name": "Gates"
},
"address: {
"street": "abc"
},
"note": {
"body": "Banned"
}
Algo así dependiendo de los params. Sé que ActiveModel :: Serializadores tiene el include_[ASSOCIATION]?
sintaxis pero ¿cómo puedo usarla eficientemente desde mis controladores?
Esta es mi solución actual, pero no es ordenada:
customer_serializer.rb:
def include_address?
!options[:embed].nil? && options[:embed].include?(:address)
end
application_controller.rb:
def embed_resources(resources = [])
params[:embed].split('','').map { |x| resources << x.to_sym } if params[:embed]
resources
end
clientes_controller.rb:
def show
respond_with @customer, embed: embed_resources
end
Debe ser una forma más fácil?
¡Muy útil saber acerca de include_associations !, gracias! Notando que con la gema active_model_serializers (versión 0.8.3) puede usar @options
para establecer el contexto en el controlador. Por ejemplo, si en el controlador se llama
render json: customer, include_addresses: true
luego en CustomerSerializer:
has_many :addresses
def include_associations!
if @options[:include_addresses]
include! :addresses
end
end
entonces las direcciones serán serializadas. Si renderizas con include_addresses
establecidas en false
, no lo serán. Con las versiones más recientes de active_model_serializers, use serialization_options
lugar de @options
.
También estoy buscando una manera efectiva y limpia de hacer esto.
Encontré una solución pero no es bonita.
En mi BaseController / ApplicationController agregué este método:
serialization_scope :params
¿Entonces el ámbito es ahora el hash de parámetros y puedo usarlo en el include_[ASSOCIATION]?
Métodos de mis serializadores.
def include_associations?
if scope[:embed]
embed = scope[:embed].split('','')
return true if embed.include?(''associations'')
end
end
No me gusta este método porque si necesito usar el alcance para algo más como current_user
para devolver datos condicionalmente si es un administrador, por ejemplo.
Pero esta solución puede funcionar en algunos casos.
ACTUALIZAR
Puede pasar view_context
lugar de pasar directamente los params
.
Y puede delegar en su Serializador para mantener el nombre de los params
lugar del scope
.
en su controlador de aplicaciones:
serialization_scope :view_context
en su serializador:
delegate :params, to: :scope
¿Y voila puede usar params [: embed] en el include_[ASSOCIATION]?
Métodos de sus serializadores.
Tengo otra solución basada en sus respuestas porque quería una funcionalidad similar. De acuerdo con la documentación, si uno quiere un control de nivel inferior de la serialización de asociación, ¡pueden anular include_associations!
.
Por ejemplo:
def include_associations!
if scope[:embed]
include! :addresses, {embed: :ids, include: true}
else
include! :addresses, {embed: :ids}
end
end