我无法确定使用 Ember.js、Ember Data 和 Rails 将 hasMany 关联与单个表单保持一致的正确方法。一个客户有很多项目。我有一个新的项目表单,它有两个字段:项目名称和客户名称。http://cl.ly/image/3z0P0R3M1t2u
我试图将我的创建逻辑保留在 Ember.js ClientsController和ProjectsController中,但是我需要将其中的一些移到我的ProjectsNewView上的提交操作中吗?
更新:发现这个问题后我更新了我的代码。我越来越近了,但 Rails ProjectsController仍然没有收到关联的 client_id。它不是控制器接收的参数的一部分。我仍然觉得我可能不会以最好的方式去做。
楷模:
导轨
class Client < ActiveRecord::Base
attr_accessible :name
has_many :projects
accepts_nested_attributes_for :projects
validates :name, :presence => true
end
class Project < ActiveRecord::Base
attr_accessible :name, :client_id
belongs_to :client
validates :name, :presence => true
validates :client, :presence => true
end
Ember.js
App.Client = DS.Model.extend
name: DS.attr('string')
projects: DS.hasMany('App.Project', { embedded: true })
validate: ->
if @get('name') is null or @get('name') is ''
'Client requires a name.'
App.Project = DS.Model.extend
name: DS.attr('string')
client: DS.belongsTo('App.Client')
validate: ->
if @get('name') is `undefined` or @get('name') is null or @get('name') is ''
return 'Projects require a name.'
if @get('client') is `undefined` or @get('client') is null or @get('client') is ''
'Projects require a client.'
控制器:
导轨
class Api::ClientsController < Api::BaseController
def create
@client = Client.find_or_create_by_name(params[:client][:name])
respond_to do |format|
if @client.save
format.json { render json: @client, status: :create }
else
format.json { render json: @client.errors, status: :unprocessable_entry }
end
end
end
end
class Api::ProjectsController < Api::BaseController
def create
@project = Project.new(params[:project])
respond_to do |format|
if @project.save
format.json { render json: @project, status: :created, location: @project }
else
format.json { render json: @project.errors, status: :unprocessable_entry }
end
end
end
end
Ember.js
App.ClientsController = Em.ArrayController.extend
createClient: (data) ->
@transaction = App.store.transaction()
client = @transaction.createRecord(App.Client, data)
project_data = data.projects_attributes[0]
client.get('projects').createRecord(project_data)
validation_errors = client.validate()
if validation_errors
App.displayError validation_errors
client.destroy()
else
@transaction.commit()
App.ProjectsController = Em.ArrayController.extend
createProject: (data) ->
@transaction = App.store.transaction()
project = @transaction.createRecord(App.Project, data)
validation_errors = project.validate()
if validation_errors
App.displayError validation_errors
project.destroy()
else
@transaction.commit()
App.get('router').transitionTo('projects')
意见:
Ember.js
App.ProjectsNewView = Em.View.extend
classNames: ['form row']
tagName: 'form'
templateName: 'projects/new'
init: ->
@_super()
submit: (event) ->
event.preventDefault()
client = {}
client.name = @get('client')
project = {}
project.name = @get('name')
client.projects_attributes = []
client.projects_attributes.push project
App.router.clientsController.createClient(client)