ruby-on-rails - 如何使用 Ember Data & Rails 在单个 Ember.js 表单中保持 hasMany 关联?

标签 ruby-on-rails ember.js has-many ember-data

我无法确定使用 Ember.js、Ember Data 和 Rails 将 hasMany 关联与单个表单保持一致的正确方法。一个客户有很多项目。我有一个新的项目表单,它有两个字段:项目名称和客户名称。 http://cl.ly/image/3z0P0R3M1t2u

我试图将我的创建逻辑保留在 Ember.js ClientsController 和 ProjectsController 中,但我是否需要将其中的一些移动到我的 ProjectsNewView 上的提交操作中?

更新:找到这个 issue 后我更新了我的代码.我越来越近了,但 Rails ProjectsController 仍然没有收到关联的 client_id。它不是 Controller 接收的参数的一部分。我仍然觉得我可能不会以最好的方式去做。

型号:

rails

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.'

Controller :

rails
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)

最佳答案

@David 我不是专家,但我再次查看您的问题,我认为要获得相关的 client_id,您必须 调用 toJSON 方法 在 RestAdapter 上并传递它:

{associations: true}

下面的链接解释了如何做到这一点:

https://stackoverflow.com/questions/10184213/is-there-a-way-to-post-embedded-objects-back-to-the-api-with-ember-data

Ember-data embedded objects stored as separate objects

Emberjs - unable to query for embedded model or association

更新

在我回答代码在哪里使用 toJSON 的问题之前,我想回到我刚刚在代码设计中观察到的一些事情。

您正在尝试在子记录中创建 parentRecord,因为 客户 是 parent ,而 项目是 child 。如果你观察得好,issue-115您链接到的,明确表示 parentRecord 存储将用于创建记录。此外,如果您最终检查测试 pull-request that was merged关于问题 115 ,您将再次看到它表示为 在 parentRecord 中创建子记录.

但你正在做相反的事情,即 在子记录中创建 parentRecord .你需要扭转这一点。

另外,在 rails 一侧 , 在 客户型号 ,您调用了接受嵌套属性:项目 , 就像 emberjs 一样只允许你创建 项目来自客户的记录,反之亦然。所有使用示例接受_nested_attributes_for rails guide , railscasts这个在nested attributes ,显示从父模型中的表单创建的子模型的字段。

所以在这个用例中,rails 和 emberjs 都是从子记录创建 parentRecord。这可能就是您遇到客户端 ID 问题的原因。 所以反转你的设计再试一次。如果它仍然没有发送客户端 ID。然后您应该在作为父关联的客户端模型上调用 toJSON,如 first link 所示。从我发布的初始链接建议您调用 {关联:真} 在 restAdapter 中的 toJson 上。
 App.Client 
 ##
 toJSON: (options={}) ->
   options['associations'] = true
   @_super(options)

我希望这有帮助。请评论什么有效或无效,以便其他遇到类似问题的人找到这篇文章可以知道从哪里开始。

最后,创建您的 不会有什么坏处。 rails API active_model_serializer gem ,这是 ember-core 团队推荐的用于创建 的 gem rails API 对于 ember-data 和 RestAdapter。这样你就可以从 ember 端和 rails 端加载和嵌入关联。

关于ruby-on-rails - 如何使用 Ember Data & Rails 在单个 Ember.js 表单中保持 hasMany 关联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12439165/

相关文章:

grails - CreateCriteria-在hasMany关联中使用逻辑或

ruby-on-rails - ActiveRecord has_many 其中表 A 中的两列是表 B 中的主键

ruby-on-rails - 供应商/bundle 的目的是什么? Heroku 告诉我删除它

ruby-on-rails - 嵌套 Rails 引擎

javascript - Ember 。 DS.Adapter 的自定义 createRecord 不会被触发

ember.js - 使用 Ember.js 为移动应用程序优化 View 结构

ruby-on-rails - 在 Ruby 中开始/结束/同时

ruby-on-rails - 在处理电子邮件回复时,我怎样才能忽略任何电子邮件客户端细节和历史记录?

javascript - 如何对 Ember JS 软件的设计进行建模?

sql - has_many :through 的索引