想象一下,我们有两个实体,存储在关系数据库中:
person(id, name)
friendship(id, personAID, personBID, strength)
在这里,我们可以看到两个人可以成为朋友,并且可以成为一个"力量" (一些数值)将给予这种友谊。 如果第1和第2人是朋友,那么我们在友谊表中有以下条目:
xyz | 1 | 2 | 50
请注意,以下相应条目不存在:
abc | 2 | 1 | 50
每个"友谊"。
只创建一个条目我挣扎的是如何在ember应用程序中对此进行建模。 A"人"可以有很多友谊,还有友谊和友谊。确切地说是2个人。
// models/person.js
DS.Model.extend({
name: DS.attr('string'),
friendships: DS.hasMany('friendship', {inverse: 'friends'})
});
友谊对象被序列化为
数组{
id: 'abc',
friends: ['1', '2'],
score: '50'
}
这样:
// models/friendship.js
DS.Model.extend({
friends: DS.hasMany('person', {inverse: friendships}),
personA: Ember.computed(friends, function() {
return this.get('friends').objectAt('0');
}),
personB: Ember.computed(friends, function() {
return this.get('friends').objectAt('1');
}),
getFriend: function(id) {
if (id === this.get('personA.id')) {
return this.get('personB');
}
if (id === this.get('personB.id')) {
return this.get('personA');
}
return null;
},
score: DS.attr('number')
});
友谊模式的实施由于很多原因而感到沮丧。首先,友谊不会有很多"朋友。它有两个。但是,如果我将实现更改为:
DS.Model.extend({
personA: DS.belongsTo('person'),
personB: DS.belongsTo('person'),
...
});
然后我不确定如何建模" hasMany"人际关系=>友谊。 '逆转'例如,字段设置为?
"得分"领域正在变得复杂。如果那不存在,那么这将是“人”中的反身关系。 model,但该关系具有其他数据,必须能够表示为自己的实体。
另外,考虑到我想列出某个人的所有朋友的情况,以及该友谊的力量," getFriend()"功能是必需的。这个功能对我来说有点味道,我无法理解为什么。
所以我的问题是,你认为什么是一种有效的方法来模拟包含额外数据的双向对称关系,例如"得分"领域?我无法改变数据在数据库中的存储方式,但我确实可以控制其他所有内容,因此我可以将数据转换为数据库中的任何结构,然后转移到Ember客户端。 / p>
Ember和Ember-data 2.x
答案 0 :(得分:4)
所以我花了一年时间,但我终于回到了这个问题,我认为我有一个相当不错的解决方案。我实际上写了两篇博文,详细介绍了解决方案(part 1和part 2),但是让我试着在这里总结一下。
该解决方案具有前端和后端组件。
我定义了模型(在Rails中,但它可能是真的),如下所示:
colorbar
我使用JSON API compliant backend和名为jsonapi-resources的gem来帮助我实现服务器响应。无论您的实施方式如何,重要的一点是为每个人提供一个返回该人友谊的终点(例如import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import matplotlib.colors as mcolors
gs = gridspec.GridSpec(2, 1,
height_ratios=[1, 4]
)
ax = [plt.subplot(g) for g in gs]
parameterToColorBy = np.linspace(5, 10, 6, dtype=float)
def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=-1):
if n == -1:
n = cmap.N
new_cmap = mcolors.LinearSegmentedColormap.from_list(
'trunc({name},{a:.2f},{b:.2f})'.format(name=cmap.name, a=minval, b=maxval),
cmap(np.linspace(minval, maxval, n)))
return new_cmap
minColor = 0.00
maxColor = 0.85
inferno_t = truncate_colormap(plt.get_cmap("inferno"), minColor, maxColor)
colors = [inferno_t(i)
for i in np.linspace(0, 1, parameterToColorBy.shape[0])]
norm = mpl.colors.Normalize(parameterToColorBy[0],
parameterToColorBy[-1])
cb = mpl.colorbar.ColorbarBase(ax[0],
cmap=inferno_t,
norm=norm,
ticks=parameterToColorBy,
orientation='horizontal')
ax[0].xaxis.set_ticks_position('top')
for p, c in zip(parameterToColorBy, colors):
ax[1].plot(np.arange(2)/p, c=c)
plt.show()
)。
该端点应返回可以获取数据的关系链接,以查看人员在关系的两侧是谁:
# app/models/friendship.rb
class Friendship < ActiveRecord::Base
belongs_to :friender, class_name: Person
belongs_to :friended, class_name: Person
end
# app/models/person.rb
class Person < ActiveRecord::Base
def friendships
Friendship.where("friender_id = ? OR friended_id = ?", id, id);
end
end
Ember侧的模型如下所示:
/people/1/friendships
在路线中,我正在抓住这个人,并以最简单的方式展示他们的友谊:
{
"data": [
{
"id": "1",
"type": "friendships",
(...)
"attributes": {
"strength": 3
},
"relationships": {
"friender": {
"links": {
"self": "http://localhost:4200/friendships/1/relationships/friender",
"related": "http://localhost:4200/friendships/1/friender"
},
"data": {
"type": "people",
"id": "1"
}
},
"friended": {
"links": {
"self": "http://localhost:4200/friendships/1/relationships/friended",
"related": "http://localhost:4200/friendships/1/friended"
},
"data": {
"type": "people",
"id": "4"
}
}
}
},
{
"id": "2",
"type": "friendships",
(...)
}
]
}
这样可行,但会向后端发送大量xhr请求,每个结束一个(friender和friended)的关系。
您可以在友谊关卡的响应中使用resource linkage来减少这些请求的数量。如果您不使用JSON API,肯定有方法可以指示哪条记录位于关系的末尾(friendship.friender或friendship.friended),这样就不需要再进行ajax请求来获取它们。