使用Rails + active_model_serializers在EmberJS中加载具有非标准类名的对象

ben*_*ton 7 ember.js ember-data active-model-serializers

我在Rails中有一些模型看起来像这样:

class Issue < ActiveRecord::Base
  belongs_to :reporter, class_name: 'User'
  belongs_to :assignee, class_name: 'User'
  has_many :comments
end

class User < ActiveRecord::Base
end

class Comment < ActiveRecord::Base
end
Run Code Online (Sandbox Code Playgroud)

像这样的序列化器:

class IssueSerializer < ActiveModel::Serializer
  attributes :id
  embed :ids, include: true

  has_one :reporter, :embed => :ids
  has_one :assignee, :embed => :ids
end

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

class CommentSerializer < ActiveModel::Serializer
  attributes :id, :body
end
Run Code Online (Sandbox Code Playgroud)

这会生成类似于以下内容的JSON:

{
  "issues": [
    {
      "id": 6,
      "reporter_id": 1,
      "assignee_id": 2,
      "comment_ids": [
        3
      ]
    },
  ],
  "comments": [
    {
      "id": 3
      "body": "Great comment"
    }
  ],
  "reporters": [
    {
      "id": 1
      "name": "Ben Burton"
    }
  ],
  "assignees": [
    {
      "id": 2
      "name": "Jono Mallanyk"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

问题是侧载报告人和受让人JSON对象不被Ember识别为User对象,我看到以下错误:

Uncaught Error: assertion failed: Your server returned a hash with the key reporters but you have no mapping for it
Run Code Online (Sandbox Code Playgroud)

我不想删除

embed :ids, include: true
Run Code Online (Sandbox Code Playgroud)

来自我的IssueSerializer,因为那时评论不会被序列化.

我考虑过一些可能解决这个问题的方法:

  • 如果ActiveModel :: Serializer的embed方法在其include选项中接受了模型列表,则可以将JSON响应过滤为仅包含侧载注释.
  • Ember数据的模型可以配置为从"用户","记者"和"受让人"侧面加载用户......但据我所知,它只能支持一个密钥用于sideloadAs.
  • 以某种方式忽略/禁用未知密钥的侧载错误(可能是最不理智的方法).

我在这里缺少另一种选择吗?我想我可能必须写一个修复程序并向rails-api/active_model_serializers,emberjs/data或两者提交pull请求.

编辑:我的临时解决方法是将IssueSerializer更改为仅序列化记者和受让人的ID:

class IssueSerializer < ActiveModel::Serializer
  attributes :id, :reporter_id, :assignee_id
  embed :ids, include: true

  has_many :comments, :embed => :ids
end
Run Code Online (Sandbox Code Playgroud)

Wil*_*Wit 1

您应该阅读页。修订版 12 的部分解释了相同类型数据的侧面加载:

现在,homeAddress 和 workAddress 将作为地址一起侧载,因为它们是相同的类型。此外,默认的根命名约定(下划线和小写)现在也将应用于旁加载的根名称。

你的模型应该是这样的:

App.Issue  = DS.Model.extend({
  reporter: DS.belongsTo('App.User'),
  assignee: DS.belongsTo('App.User'),
  comments: DS.hasMany('App.Comment')
});
Run Code Online (Sandbox Code Playgroud)

JSON 结果应该有一个用户的密钥:

{
  "issues": [
    {
      "id": 6,
      "reporter_id": 1,
      "assignee_id": 2,
      "comment_ids": [
        3
      ]
    },
  ],
  "comments": [
    {
      "id": 3
      "body": "Great comment"
    }
  ],
  "users": [
    {
      "id": 1
      "name": "Ben Burton"
    },{
      "id": 2
      "name": "Jono Mallanyk"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

因为您在模型中配置了reporter类型User,所以 Ember 在结果中搜索用户。