如何为多对多关系编写activemodel序列化器?

时间:2014-09-14 14:49:46

标签: ruby-on-rails ember.js ember-cli active-model-serializers

尝试为ember-cli应用设置后端。以下是Ember模型的样子:

post.js

export default DS.Model.extend({
  heading: DS.attr('string'),
  content: DS.attr(''),
  imageUrl: DS.attr('string'),
  pageId: DS.belongsTo('page'),
  tagIds: DS.hasMany('tag')
});

tag.js

export default DS.Model.extend({
  name: DS.attr('string'),
  postIds: DS.hasMany('post')
});

Rails和Active Record中的模型只是Post,Tag和Theme。主题加入帖子和标签。 (即:发布has_many:标签,通过::主题)

这是我的序列化工具的样子:

class PostSerializer < ActiveModel::Serializer
  embed :ids, include: true

  attributes :id, :heading, :content, :image_url

  has_many :tags
end

class TagSerializer < ActiveModel::Serializer
  embed :ids, include: true

  attributes :id, :name
end

这可以向一个方向发展:搜索帖子也会获得所有标签。不能在另一个中工作,因为我在TagSerializer中没有has_many。但是,如果我在两个序列化程序中都放置了has_many,则会出现堆栈级别太深的错误。

所以我想我的问题是:与ActiveModel序列化器实现多对多关系的典型方法是什么?我似乎无法找到有关如何在Rails后端设置它的任何资源。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:5)

你的筹码水平太深了#34;错误,因为每个序列化程序递归嵌入另一个。

我首先要确保您在Rails控制器中使用includes

# posts controller
def show
  post = Post.includes(:tags).find_by id: params[:id]
  render json: post
end

# tags controller
def show
  tag = Tag.includes(:posts).find_by id: params[:id]
  render json: post
end

然后,在你的序列化程序中,只有在加载了关联时才告诉它有条件地包含标签/帖子:

# post serializer
def include_tags?
  object.association(:tags).loaded?
end

# tag serializer
def include_posts?
  object.association(:posts).loaded?
end

在此之后,它应该只降级一级。

作为旁注,您可能希望将余烬模型中的tagIdspostIds属性重命名为tagsposts