2012-09-15 29 views
4

我無法確定使用Ember.js,Ember Data和Rails將單個窗體保持爲hasMany關聯的正確方法。客戶有許多項目。我有一個新的項目表單,它有兩個字段:項目名稱和客戶端名稱。 http://cl.ly/image/3z0P0R3M1t2u如何使用Ember Data&Rails在一個Ember.js表單中堅持hasMany關聯?

我試圖讓我的Ember.js ClientsController & ProjectsController中創建的邏輯,但我需要一些是移動到提交動作上我ProjectsNewView

更新:我發現此issue後更新了我的代碼。我越來越近了,但Rails ProjectsController仍然沒有收到關聯的client_id。它不是控制器收到的參數的一部分。它仍然覺得我可能不會採取這種最好的方式。

型號:

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

控制器:

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

瀏覽:

灰燼。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) 
+0

如果沒有人回答,可以通過在IRC頻道中粘貼Stackerflow鏈接獲得更好的成功,並在發佈鏈接後粘貼一段時間。我做了幾次,人們迴應了Stackoverflow鏈接並解決了我的問題。我知道你把它放在twitter上,這是我看到它的地方,但嘗試IRC頻道。 – brg

+0

感謝您的建議@brg。 – David

+0

我認爲現在可以使用RESTSerializer的embed_always映射來堅持hasMany,它也應該可以使用或不使用accept_nested_attributes_for。在github上展示它的示例應用程序的鏈接如下。 [Github上的應用程序](https://github.com/dgeb/ember_data_example)該應用程序的相關部分展示瞭如何使用單一表單保持hasMany關聯[ActiveRecord association showing has_many](https://github.com/dgeb/ ember_data_example/blob/master/app/models/contact.rb)[rails控制器,兩種模型都使用一個控制器](https://github.com/dgeb/ember_data_ – brg

回答

1

@大衛我不是專家,但我在你的問題再次尋找,我想,以獲得相關的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因爲客戶是父而項目是孩子。如果您觀察得很好,您鏈接到的issue-115,明確表示將使用parentRecord存儲創建記錄。此外,如果您檢查就在evenutual pull-request that was merged的測試問題-115,你會看到它再次表示爲的parentRecord中創建一個子記錄。

但是你正在做的是相反的,那就是在子記錄內創建parentRecord。你需要扭轉這一點。

此外,在鐵軌上側,在客戶端模型,你叫accepts_nested_attributes_for:項目,這就像emberjs並只允許您創建項目從客戶端記錄,而不是相反。如何在rails guiderailscasts,這對nested attributes使用accepts_nested_attributes_for,顯示從父模型的形式創建的子模型的字段所有的例子。

所以兩個軌和emberjs在這種使用情況下,從子記錄創建parentRecord。這可能是你有客戶端問題的原因。 因此,請改變您的設計並重試。如果它仍然不發送客戶端ID。在restAdapter上的toJSON:那你應該是在家長協會如圖所示first link從最初的聯繫我張貼建議你打電話{true關聯}客戶端模式叫的toJSON。

App.Client 
## 
toJSON: (options={}) -> 
    options['associations'] = true 
    @_super(options) 

我希望這會有所幫助。請回應一下有效或無效的內容,以便其他遇到類似問題的用戶可以知道該從哪裏開始。

最後,它不會傷害與active_model_serializer gem創建軌API,這是燼核心團隊的創建軌API爲灰燼數據和RestAdapter推薦的寶石。這樣你就可以從ember和rails兩邊加載和嵌入關聯。

+0

在我的代碼中,你提出我使用toJSON方法嗎?我很抱歉需要更多的解釋。謝謝! – David

+0

@David,看到我在* *更新**部分回覆您的評論 – brg

+0

感謝您的補充信息我實際上使用了active_model_serializer gem我也相信我正在創建孩子記錄在父母中,正如您在我的Cl中所描述的ientController用'client.get('projects')。createRecord(project_data)'我不是嗎? – David

相關問題