9

我正在編寫一個練習骨幹應用程序,使用Rails後端API,我對保存在Backbone模型上的行爲感到困惑。爲什麼Backbone模型在保存時向服務器發送重複屬性?

假設一支球隊有很多球員,並且我希望在一個POST中保存一個擁有衆多球員的球隊。

所以在Rails的,我有:

class Team < ActiveRecord::Base 
    has_many :players 
    accepts_nested_attributes_for :players 
end 

class Player < ActiveRecod::Base 
    belongs_to :team 
end 

和骨幹網的客戶端,我有一個播放器模型和定義的玩家集合(未顯示)

,然後將含有組隊模式(注:無團隊集合)

Demo.Models.Team = Backbone.Model.extend({ 
    urlRoot: '/teams', 
    defaults: { 
    'team_size': 12 
    }, 
    initialize: function() { 
    this.players = new Demo.Collections.Players()); 
    }, 
    toJSON: function() { 
    var json = _.clone(this.attributes); 
    json.players_attributes = this.players.map(function(player) { 
     return player.toJSON(); 
    }); 
    return json; 
    } 
} 

當我審視我的字符串化JSON在瀏覽器中,一切看起來不錯:

{"team_size":12, "players_attributes":[{"name":"Fred"},{"name":"Jim" },{"name":"Mark"}]} 

檢查服務器日誌,獨行頂層屬性(「隊大小」)是重複的,一旦在頂層,然後根密鑰下重複。

Started POST "/teams" for 127.0.0.1 at 2012-06-07 13:39:40 -0400 
Processing by TeamsController#create as JSON 
    Parameters: { 
    "team_size"=>12, "players_attributes":[{"name":"Fred"},{"name":"Jim" },{"name":"Mark"}]}, 
    "team"=>{"team_size"=>12} 
    } 

我有幾個問題:

  1. 什麼是保證嵌套在根密鑰內player_attributes的最佳方式?我(這樣我就可以在TeamController中以標準的rails方式進行嵌套保存:(即Team.create(params [:team]))我可以用一些javascript hackery在json中完成這項工作,但我猜測這裏有一個更簡單,更清潔的方式。

  2. 這是標準的,期望的行爲?要送這樣的屬性的重複?我想有沒有危害,但它沒有氣味的權利。

  3. 我不是定義URL/urlRoot正確或一些這樣?

感謝

+2

主幹精確地發送toJSON()的結果:'params.data = JSON.stringify(model.toJSON());',所以無論你的模型包含這樣的屬性或者服務器上的一些奇怪的東西(日誌中有浪費的大括號)。檢查螢火蟲中的http請求內容,找出責任人。 – Yaroslav

+0

我在Backbone和Rails上遇到了同樣的問題......現在我需要進行優化,這已經變得令人討厭......任何想法都來自哪裏? – wulftone

+0

我認爲值得注意的是,就我而言(也可能是你的情況),骨幹似乎在發送非重複的信息。 Firebug告訴我發送給我的服務器的POST請求包含正確的,非重複的信息。然而,在它轉向紅寶石「params」之前,它重複了一些東西......爲什麼? – wulftone

回答

3

1-您必須重寫toJSON方法才能包含模型名稱作爲發送到服務器的JSON元素的根。

toJSON: function() { 
    return { team: _.clone(this.attributes) } 
    }, 

由於您已經搞亂並重寫此方法,我不認爲有任何理由不這樣做。

2-這是你描述的非常奇怪的行爲。嘗試:

class Team < ActiveRecord::Base 
    self.include_root_in_json = false 
end 

它可能會消除Rails的重複參數解析。從這裏得到的另一個好處是,Rails不會將團隊作爲其生成的JSON的根元素添加到客戶端。

3-您對urlRoot的定義很好。

+0

只要你不打補丁,這似乎是有效的。如果你用''''save''''{'patch:true}''''使用'''''',那麼Backbone sync方法更喜歡改變的attrs而不是調用toJSON方法。 –

0

儘管您可以使用其他人提到的toJSON攻擊,但實際上並不是這樣一個好主意。其一,它產生syncsave{patch: true}之間不一致的結果(這種不一致是因爲同步方法調用的toJSON如果不打補丁,但不調用的toJSON如果你有補丁設置爲true)

相反,更好的解決方案是使用補丁版本的Backbone來重載同步方法本身。 backbone-rails gem自動執行此操作,或者您可以將backbone_rails_sync.js拖放到您自己的應用程序中。這個問題的更完整的答案可以在這裏找到:Backbone.js and Rails - How to handle params from Backbone models?

相關問題