rails new active_model_serializers active ruby-on-rails json api active-model-serializers

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