我遇到了尝试使用ember-data和rails在Ember.js中保存多对多关系的问题。该关联在ember方面工作正常,但是当我尝试提交事务时,它将不包括提交到rails时的新关联列表。任何帮助都将非常感激,我一直在试图找到一个示例应用程序,在github上做这么简单的事情,但我似乎无法找到它。
这是我的Ember代码的一个愚蠢的版本:
App.Store = DS.Store.extend
revision: 11
adapter: DS.RESTAdapter.create
url: '/api'
App.Router.map ->
@resource 'rosters'
@resource 'users'
App.User = DS.Model.extend
rosters: DS.hasMany 'App.Roster'
App.Roster = DS.Model.extend
users: DS.hasMany 'App.User'
App.RostersEditRoute = Ember.Route.extend
setupController: (controller, model) ->
controller.set 'users_list', App.User.find()
App.RostersEditView = Ember.View.extend
userCheckbox: Em.Checkbox.extend
checkedObserver: ( ->
users = @get 'roster.users'
if @get 'checked'
users.addObject @get 'user'
else
users.removeObject @get 'user'
@get('controller.store').commit()
).observes 'checked'
编辑表格:
each user in users_list
label.checkbox
view view.userCheckbox rosterBinding="current_roster" userBinding="user" | #{user.full_name}
Rails后端(使用继承资源和活动模型序列化程序gems):
class User < ActiveRecord::Base
has_many :rosters_users
has_many :rosters, through: :rosters_users
accepts_nested_attributes_for :rosters
end
class RostersUser < ActiveRecord::Base
belongs_to :user
belongs_to :roster
end
class Roster < ActiveRecord::Base
has_many :rosters_users
has_many :users, through: :rosters_users
accepts_nested_attributes_for :users
end
module Api
class RostersController < BaseController
end
end
module Api
class UsersController < BaseController
end
end
module Api
class BaseController < ActionController::Base
inherit_resources
respond_to :json
before_filter :default_json
protected
# Force JSON
def default_json
request.format = :json if params[:format].nil?
end
end
end
class UserSerializer < BaseSerializer
has_many :rosters, embed: :ids
end
class RosterSerializer < BaseSerializer
has_many :users, embed: :ids
end
就像我说的那样,该关联在Ember上工作得很好但是rails似乎没有得到新的关联数据。当我检查Web检查器中的XHR选项卡时,我发现它只发送了这个:
请求有效负载 {“名册”:{“created_at”:“星期四,2013年3月21日23:16:02 GMT”,“team_id”:“1”}}
我的回复是204无内容错误,因为没有任何改变。
答案 0 :(得分:17)
尽管可以设置匹配的hasMany
关系,但Ember Data实际上并不支持多对多的关系(参见this issue)。你现在可以做的是使用会员模型分解关系。
App.User = DS.Model.extend
rosterMemberships: DS.hasMany 'App.RosterMembership'
App.RosterMembership = DS.Model.extend
user: DS.belongsTo 'App.User'
roster: DS.belongsTo 'App.Roster'
App.Roster = DS.Model.extend
rosterMemberships: DS.hasMany 'App.RosterMembership'
现在,您可以将createRecord()
和deleteRecord()
与成员资格模型一起使用来添加和删除关系。
不幸的是,在这个例子中,绑定到特定用户的名单集合并不容易。一种解决方法如下:
App.User = DS.Model.extend
rosterMemberships: DS.hasMany 'App.RosterMembership'
rosters: ( ->
@get('rosterMemberships').getEach('user')
).property 'rosterMemberships.@each.relationshipsLoaded'
App.RosterMembership = DS.Model.extend
user: DS.belongsTo 'App.User'
roster: DS.belongsTo 'App.Roster'
relationshipsLoaded: ( ->
@get('user.isLoaded') and @get('roster.isLoaded')
).property 'user.isLoaded', 'roster.isLoaded'
如果绑定到user.rosters
,则模板应在创建或销毁关系时更新。
答案 1 :(得分:0)
替代解决方案:
App.Roster = DS.Model.extend
users_map: DS.attr('array')
users: DS.hasMany 'App.User'
users_change: (->
@set('users_map', @get('users').map((el) -> el.id).toArray())
).observes('users.@each')
到POST数据中的服务器将发送用户ID数组