2015-02-20 3 views
0

В моем контроллере комментариев я сериализую комментарии. Когда я помещаю belongs_to :post_id в свой сериализатор, у каждого комментария есть сообщение с ним, но поскольку все эти комментарии исходят из одного сообщения, он избыточен. Я знаю, что могу использовать постсериализатор сообщений с комментариями has_many, но так как я - контроллер комментариев, который не кажется идиоматическим. Как я могу это достичь?Активная модель Сериализатор отправляет родителя has_many

Надеясь: { comments: { ... }, post: { ... } }

ответ

1

Если вы хотите, чтобы предотвратить избыточное включение ассоциаций, установить embed:

embed :objects    # Embed associations as full objects 
embed :ids     # Embed only the association ids 
embed :ids, :include => true # Embed the association ids and include objects in the root 

Так

class Comments < ActiveModel::Serializer 
    embed :ids, include: true 
end 

будет включать запись только один раз на верхнем уровне :

{ 
    comments: [ 
    { 
     id: 1, 
     text: "Foo", 
     post_id: 1 
    }, 
    { 
     id: 2, 
     text: "Bar", 
     post_id: 1 
    } 
    ], 
    posts: [ 
    { 
     id: 1, 
     title: "Lorem ipsum" 
    } 
    ] 
} 

Если вы хотите включить или исключить ассоциации полностью в зависимости от ситуации, this wonderful StackOverflow answer имеет изящное решение, что с помощью (аb) с помощью жадной загрузки:

class Comments < ActiveModel::Serializer 
    attributes :id, :text, :poster_id 

    belongs_to :poster 

    def include_poster? 
    object.association(:poster).loaded? 
    end 

    def include_poster_id? 
    !include_poster? 
    end 
end 

Теперь, очистив post ассоциации вы можете предотвратить его от быть включены на всех:

@comments = @post.comments 
@comments.post.reset 

respond_with @comments 

В обратном направлении, явно стремится загрузки ассоциации будет включать в себя это:

@comments = Comment.includes(:poster).order(id: :asc).limit(10) 
respond_with @comments 
+0

Как это применимо, если я получу комментарии, подобные «@comments = @ post.comments»? У меня уже есть почта. Это вопрос его включения. Быстрый взлом - это просто включить его в мета, но я не слишком увлекаюсь этим. – David

+0

@David Думаю, я понимаю, что вы имеете в виду, кроме мета-части? – janfoeh

+0

@David 'embed include: true' должен делать трюк. Что касается '@comments = @ post.comments', вы можете выгрузить ассоциацию, вызвав на нее' .reset'. '@comments = @ post.comments; @ comments.post.reset' оставит 'пост' обезвоженным. – janfoeh