2014-12-02 8 views
6

Ho usato AMS (0.8) con Rails 3.2.19 ma un posto in cui mi trovo davvero a disagio è come controllare se i serializzatori includono o meno le loro associazioni. Ovviamente uso AMS per costruire JSON Api. A volte un serializzatore è l'elemento foglia o più lontano e talvolta è il livello più alto e deve includere associazioni. La mia domanda è qual è il modo migliore per farlo o è la soluzione che faccio sotto lavoro (o è la soluzione migliore).come includere condizionalmente le associazioni in un serializzatore di modelli Active Rails v0.8

Ho visto alcune discussioni ma le trovo molto confuse (e basate sulla versione). È chiaro che per gli attributi o le associazioni Serializer esiste un include_XXX? metodo per ciascuno e si può restituire una dichiarazione di verità o falsità qui.

Ecco il mio codice proposto: è un enologo che ha molti wine_items. È così che faresti questo?

Classi modello:

class WineItem < ActiveRecord::Base 
    attr_accessible :name, :winemaker_id 
    belongs_to :winemaker 

end 

class Winemaker < ActiveRecord::Base 
    attr_accessible :name 
    has_many :wine_items 
    attr_accessor :show_items 
end 

Serializzatori:

class WinemakerSerializer < ActiveModel::Serializer 
    attributes :id, :name 
    has_many :wine_items 

    def include_wine_items? 
    object.show_items 
    end 
end 

class WineItemSerializer < ActiveModel::Serializer 
    attributes :id, :name 
end 

e nel mio controller:

class ApiWinemakersController < ApplicationController 
    def index 
    @winemakers=Winemaker.all 
    @winemakers.each { |wm| wm.show_items=true } 
    render json: @winemakers, each_serializer: WinemakerSerializer, root: "data" 
    end 
end 
+0

AMS 0.10.2: non funziona. 'def include_wine_items?' non ha alcun effetto - non importa se restituisce true o false l'associazione è inclusa. – prograils

risposta

1

mi sono imbattuto in questo problema me stesso e questa è la soluzione più pulita finora (ma non ne sono un fan)

Questo metodo permette di fare le cose come:

/parents/1?include_children=true

o utilizzando una sintassi più pulito come:

/parents/1?include=[children], ecc ...

# app/controllers/application_controller.rb 
class ApplicationController 
    # Override scope for ActiveModel-Serializer (method defined below) 
    # See: https://github.com/rails-api/active_model_serializers/tree/0-8-stable#customizing-scope 
    serialization_scope(:serializer_scope) 

    private 

    # Whatever is in this method is accessible in the serializer classes. 
    # Pass in params for conditional includes. 
    def serializer_scope 
    OpenStruct.new(params: params, current_user: current_user) 
    end 
end 

# app/serializers/parent_serializer.rb 
class ParentSerializer < ActiveModel::Serializer 
    has_many :children 

    def include_children? 
    params[:include_children] == true 
    # or if using other syntax: 
    # params[:includes].include?("children") 
    end 
end 

Kinda hackish a me , ma funziona. Spero che tu lo trovi utile!

+0

AMS 0.10.2: non funziona. def include_children? non ha alcun effetto - non importa se restituisce vero o falso l'associazione è inclusa. – prograils

Problemi correlati