与 Ember、ember-data 和 Rails 的多对多关系 [英] Many to Many Relationships with Ember, ember-data and Rails

查看:16
本文介绍了与 Ember、ember-data 和 Rails 的多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试使用 ember-data 和 rails 在 Ember.js 中保存多对多关系时遇到问题.该关联在 ember 方面工作正常,但是当我尝试提交事务时,它不会在提交到 rails 时包含新关联列表.任何帮助将不胜感激,我一直在努力寻找一个示例应用程序,该应用程序在 github 上执行如此简单的操作,但我似乎找不到.

I am having an issue with trying to save many to many relationships in Ember.js using ember-data and rails. The association works fine on the ember side of things, however when I try to commit the transaction it will not include the list of new associations when submitting to rails. Any help would be much appreciated, I've been tearing out my hair trying to find an example application that does something this simple on github but I can't seem to find one.

这是我的 Ember 代码的简化版:

Here is a dumbed down version of my Ember code:

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 后端(使用继承的资源和活动模型序列化程序 gem):

Rails Backend (Using Inherited Resources and Active Model Serializer 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 似乎没有获取新的关联数据.当我查看网络检查器中的 XHR 选项卡时,我看到它只发送了这个:

So like I said, the association works fine on Ember but rails doesn't seem to be getting the new association data. When I check out the XHR tab in the web inspector, I see it only sent this:

请求有效载荷{"roster":{"created_at":"星期四,2013 年 3 月 21 日 23:16:02 GMT","team_id":"1"}}

Request Payload {"roster":{"created_at":"Thu, 21 Mar 2013 23:16:02 GMT","team_id":"1"}}

返回 204 no content 错误,因为没有任何变化.

And I am returned with a 204 no content error because nothing changed.

推荐答案

尽管可以设置匹配的 hasMany 关系,但 Ember Data 实际上并不支持多对多关系(请参阅此问题).您现在可以做的是使用成员资格模型分解关系.

Despite the fact that it's possible to set up matching hasMany relationships, Ember Data doesn't actually support many to many relationships yet (see this issue). What you can do for now is decompose the relationship using a membership model.

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() 与成员资格模型一起使用来添加和删除关系.

Now you can use createRecord() and deleteRecord() with the membership model to add and delete relationships.

不幸的是,在此示例中,绑定到特定用户的名册集合并不容易.一种解决方法如下:

Unfortunately, in this example, it's not so easy to bind to the collection of rosters for a particular user. One work-around is as follows:

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.roster,那么您的模板应该在创建或销毁关系时更新.

If you bind to user.rosters, then your template should update when relationships are created or destroyed.

这篇关于与 Ember、ember-data 和 Rails 的多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆