2013-05-01 9 views
12

Ich habe ein Problem mit der Begrenzung der Ebene der Zuordnungen, die in einer aktiven Modellressource serialisiert sind.Begrenzen der Zuordnungskaskade im aktiven Modell-Serializer

Zum Beispiel:

A Game hat viele Teams, die viele Spieler

class GameSerializer < ActiveModel::Serializer 
    attributes :id 
    has_many :teams 
end 

class TeamSerializer < ActiveModel::Serializer 
    attributes :id 
    has_many :players 
end 

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

hat Wenn ich die JSON für das Team abrufen, enthält es alle Spieler in einem Sub-Array, wie gewünscht.

Wenn ich die JSON für das Spiel abzurufen, enthält es die Teams alle in einem Subarray, ausgezeichnet, sondern auch alle Spieler für jedes Team. Dies ist das erwartete Verhalten, aber ist es möglich, die Ebene der Assoziationen zu begrenzen? Have Game gibt nur die serialisierten Teams ohne die Spieler zurück?

Antwort

12

Eine weitere Option ist Rails' zu missbrauchen eifrig Laden, um zu bestimmen, welche Assoziationen zu ren die:

In Ihrem Schienen-Controller:

def show 
    @post = Post.includes(:comments).find(params[:id]) 
    render json: @post 
end 

dann in AMS Land:

class PostSerializer < ActiveModel::Serializer 
    attributes :id, :title 
    has_many :comments, embed: :id, serializer: CommentSerializer, include: true 

    def include_comments? 
    # would include because the association is hydrated 
    object.association(:comments).loaded? 
    end 
end 

Wahrscheinlich nicht die sauberste Lösung, aber es funktioniert für mich schön!

+0

'object.association (: Kommentare) .loaded?' Das ist genau das, wonach ich gesucht habe, danke! Ich denke, diese Methode ist sauberer als die angenommene Antwort. In der Dokumentation active_model_serializer empfiehlt es sich, Zuordnungen zu berücksichtigen, die entweder einen Join oder Includes im Controller verwenden, um n + 1 Abfragen zu vermeiden. Wo ich ratlos war, war im Serializer, wie man feststellen kann, ob eine Assoziation geladen oder weggelassen wurde. Aus der Dokumentation: „versuchen, n + 1-Abfragen zu vermeiden, indem sie, dass die Datenlasten in optimaler Weise gewährleistet, wenn Sie zB Active verwenden, können Sie Abfrage verwenden enthält oder schließt sich je nach Bedarf“ – Mark

+2

Wo muss ich anrufen die include_comments? Methode? – Kaspar

8

Sie eine andere Serializer erstellen:

class ShortTeamSerializer < ActiveModel::Serializer 
    attributes :id 
end 

Dann:

class GameSerializer < ActiveModel::Serializer 
    attributes :id 
    has_many :teams, serializer: ShortTeamSerializer 
end 

Oder Sie können ein include_teams? in GameSerializer definieren:

class GameSerializer < ActiveModel::Serializer 
    attributes :id 
    has_many :teams 

    def include_teams? 
    @options[:include_teams] 
    end 
end 
+0

Dank Pablo, ist das, was ich tun endete ... Ich habe versucht, es ein bisschen Schienen-y, Modellierung zu machen: Index und: anzeigen Pluralisierung aber mit einem 'TeamsSerializer' und' TeamSerializer'. Sonderfälle erhalten einen anderen Serializer. –

+4

Woher kommt @options? – Samnang

Verwandte Themen