2014-12-02 15 views
6

Używam AMS (0.8) z Railsami 3.2.19, ale jedno miejsce, w którym naprawdę walczę z nimi, to jak kontrolować, czy serializatory zawierają ich skojarzenia, czy nie. Oczywiście używam AMS do budowy JSON'a Api. Czasem serializator jest elementem liścia lub najbardziej oddalonym, a czasami jest najwyższym poziomem i musi zawierać skojarzenia. Moje pytanie brzmi: jaki jest najlepszy sposób na zrobienie tego lub czy rozwiązanie, które wykonuję poniżej, działa (lub jest najlepszym rozwiązaniem).jak warunkowo dołączyć asocjacje w Rails Active Model Serializer v0.8

Widziałem niektóre z dyskusji, ale uważam je za bardzo mylące (i oparte na wersjach). Jest oczywiste, że w przypadku atrybutów lub asocjacji Serializera występuje parametr include_XXX? metoda dla każdego i możesz zwrócić tutaj oświadczenie truey lub falsey.

Oto mój proponowany kod - to winiarz, który ma wiele win. Czy tak to zrobiłbyś?

modelu Klasy:

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 

Serializers:

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 

i w moim kontrolera:

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: to nie działa. "def include_wine_items?" nie ma żadnego skutku - bez względu na to, czy zwróci true czy false, dołączone jest powiązanie. – prograils

Odpowiedz

1

wpadłem na ten problem samodzielnie i jest to najczystszy roztwór tak daleko (ale nie jestem fanem tego).

Ta metoda pozwala robić takie rzeczy jak:

/parents/1?include_children=true

lub za pomocą filtra składnię jak:

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

# 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 do mnie , ale działa. Mam nadzieję, że okaże się to przydatne!

+0

AMS 0.10.2: to nie działa. def include_children? nie ma żadnego efektu - niezależnie od tego, czy zwraca true czy false, dołączone jest skojarzenie. – prograils