ember.js - Muchas a muchas relaciones con Ember, Ember-data y Rails
ember api (2)
A pesar de que es posible establecer relaciones de coincidencia con hasMany
, Ember Data aún no admite muchas o muchas relaciones (consulte este tema ). Lo que puede hacer por ahora es descomponer la relación usando un modelo de membresía.
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''
Ahora puede usar createRecord()
y deleteRecord()
con el modelo de membresía para agregar y eliminar relaciones.
Desafortunadamente, en este ejemplo, no es tan fácil vincularse a la colección de listas para un usuario en particular. Un trabajo alternativo es el siguiente:
App.User = DS.Model.extend
rosterMemberships: DS.hasMany ''App.RosterMembership''
rosters: ( ->
@get(''rosterMemberships'').getEach(''user'')
).property ''[email protected]''
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''
Si se vincula a user.rosters
, su plantilla debería actualizarse cuando se crean o destruyen las relaciones.
Tengo un problema al tratar de guardar muchas relaciones en Ember.js usando los datos y los rails. La asociación funciona bien por el lado de las cosas, sin embargo, cuando intento comprometer la transacción, no incluirá la lista de nuevas asociaciones al enviar a los rieles. Cualquier ayuda sería muy apreciada, me he estado arrancando el pelo tratando de encontrar una aplicación de ejemplo que haga algo tan simple en Github, pero parece que no puedo encontrar ninguna.
Aquí hay una versión simplificada de mi código 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''
Editar formulario:
each user in users_list
label.checkbox
view view.userCheckbox rosterBinding="current_roster" userBinding="user" | #{user.full_name}
Rails Backend (Uso de recursos heredados y gemas de serializador de modelo activo):
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
Así que como dije, la asociación funciona bien en Ember, pero los rieles no parecen estar obteniendo los nuevos datos de asociación. Cuando reviso la pestaña XHR en el inspector web, veo que solo envió esto:
Solicitud de carga útil {"lista": {"created_at": "Jue, 21 de marzo de 2013, 23:16:02 GMT", "team_id": "1"}}
Y me devuelven un 204 sin error de contenido porque nada ha cambiado.
Solución alternativa:
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'')
al servidor en los datos POST se enviará una matriz de ID de usuarios