2013-05-01 30 views
12

我在限制活動模型資源中序列化的關聯級別時遇到了問題。有源模型串行器中的限制關聯級聯

例如:

一個遊戲中有很多球隊那裏有很多玩家

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 

當我取回JSON的團隊,它包括根據需要在子陣列中的所有玩家。

當我檢索遊戲的JSON時,它包含了一個子陣列中的所有團隊,非常出色,但也包含了每個團隊的所有玩家。這是預期的行爲,但可以限制關聯的級別嗎?有沒有玩家的遊戲只會返回序列化的團隊?

回答

12

另一種選擇是濫用Rails的渴望加載以確定要ren哪些關聯DER:

在Rails控制器:

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

然後在AMS土地:

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 

也許不是最乾淨的解決方案,但它工作得很好,我!

+0

'object.association(:comments).loaded?'這正是我期待的,謝謝!我認爲這種方法比接受的答案更清潔。從active_model_serializer docs推薦使用包含在控制器中的連接或包含的關聯來避免n + 1個查詢。在哪裏我被難倒在序列化器中如何確定一個關聯是否被加載或忽略它。 從文檔: 「嘗試通過確保數據以最佳方式加載來避免n + 1查詢,例如,如果您使用的是ActiveRecord,則可能需要根據需要使用查詢包含或連接」 – Mark 2013-10-28 07:59:04

+2

我必須致電include_comments?方法? – Kaspar 2014-12-08 15:21:45

8

您可以創建另一個Serializer

class ShortTeamSerializer < ActiveModel::Serializer 
    attributes :id 
end 

然後:

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

或者你可以定義一個include_teams?GameSerializer

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

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

感謝Pablo,這就是我最終做的......我嘗試讓它有點rails-y,modeling:index和:顯示覆數形式,但有一個「TeamsSerializer」和「TeamSerializer」。特殊情況下得到不同的序列化程序。 – 2013-08-13 20:07:09

+4

@options來自哪裏? – Samnang 2014-01-22 10:24:32