如何定义多态关联?

How to define a polymorphic association?

我正在尝试设置多态关联。不幸的是,Ember 文档并没有很好地涵盖这一点。

我的 API (Rails) 有如下定义:

class User < ActiveRecord::Base
  belongs_to :profile, polymorphic: true#, dependent: :destroy
end

class MemberProfile < ActiveRecord::Base
  has_one :user, as: :profile, dependent: :destroy
end

class GuestProfile < ActiveRecord::Base
  has_one :user, as: :profile, dependent: :destroy
end

这意味着,在 Rails 控制台中,我可以执行 User.last.profile,这将 return 一个 MemberProfileGuestProfile 对象。

我应该如何在客户端定义它 (Ember)?

// app/models/user.js
import DS from 'ember-data';
export default DS.Model.extend({
  profile:      DS.belongsTo('profile', { polymorphic: true, async: true })
});

// app/models/member-profile.js
import DS from 'ember-data';
export default DS.Model.extend({
  profile:      DS.belongsTo('profile', { polymorphic: true, async: true })
});

// app/models/guest-profile.js
import DS from 'ember-data';
export default DS.Model.extend({
  profile:      DS.belongsTo('profile', { polymorphic: true, async: true })
});

你是对的,Ember 文档似乎缺少。除了您已经概述的 DS.belongsTo('profile', { polymorphic: true, async: true }) 之外,我认为它没有太多意义。

一个选项是扩展配置文件 class:

// Standard Ember code - use export/import conventions for ember-cli
App.Profile = DS.Model.extend({
  // Attributes here, maybe a reference to the related User
});

App.MemberProfile = App.Profile.extend({
  // Member-specific attributes
});

App.GuestProfile = App.Profile.extend({
  // Guest-specific attributes
});

App.User = DS.Model.extend({
  profile: DS.belongsTo('profile', {polymorphic: true, async: true})
});

这将允许您执行 someUser.get('profile'),并使返回值成为会员或来宾。它基于以下位置提供的代码:http://www.toptal.com/emberjs/a-thorough-guide-to-ember-data#the-ember-data-value-proposition

您也可以在需要的情况下创建类似形式的混合。

今年早些时候在 Ember 论坛上有一个关于使用 Ember 的多态关联的最佳实践的相关讨论:http://discuss.emberjs.com/t/cleaner-way-to-define-polymorphic-associations/6369

作为旁注,在您的 javascript 代码中,member-profile.jsguest-profile.js 会 link 到 user,而不是 profile 模仿您的 Rails 代码。