在Rails和Backbone.js的模型之间构建多对多关系

时间:2011-07-11 08:32:38

标签: ruby-on-rails rest models backbone.js

我正在尝试设置具有多对多关系的item模型和tag模型(项目有多个标签和标签属于多个项目)。我正在使用Rails和Backbone.js,所以我需要让它们在彼此之间无缝地存储,检索和更新模型。如果我可以从客户端一次性保存特定项目的新标签列表,我也会喜欢它。

构建Rails端的模型和控制器以及Backbone端的模型的正确方法是什么,以保持系统RESTful并便于在它们之间共享模型?具体来说,API在服务器上会是什么样子,模型的JSON表示在保存和检索它们时会是什么?

我真的很感激任何关于结构的建议,我真的不需要任何代码或实现细节 - 只需高级设置就可以了。谢谢!

2 个答案:

答案 0 :(得分:7)

看起来你找到了你的铁轨答案。也许我可以帮助骨干方面:

Backbone有2个模型构造:Model和Collection(集合只是模型列表)。没有形式描述与骨干(afaik)的关系的方式,所以你必须自己做。我认为我要做的是处理这个结构将是3个集合:

ItemCollection

项目集合将保存您的所有项目,而每个项目依次拥有自己的TagCollection,其中包含与其相关的标记模型。

ItemCollection.TagCollection

保留对主TagCollection实例的引用,但仅是此Item的本地列表。既然你可以'。'添加一个模型到一个集合,那么你可以有多个集合,并使用相同的模型填充它们。

TagCollection

TagCollection包含您的标签。它是每个ItemCollections TagCollection将引用的“主要”标记列表。

例如:TagCollection中有3个标签,还有2个项目。

  • item_1.TagCollection具有tag_A和tag_B
  • item_2.TagCollection具有tag_A和tag_C

如果,item_1然后添加了tag_C,您只需:item_1.TagCollection.add(tag_C)同样,删除:item_1.TagCollection.remove(tag_C)会将其从item_1集合中删除,但不会删除任何其他集合。 / p>

无论您使用哪种方法,您都需要编写一些代码才能让它进行批量更新/创建。请记住,骨干只是在执行同步时将属性列表作为请求正文中的JSON字符串传递。它并不关心它发送的是什么。因此,只要您的控制器设置为接受其创建方法的列表(1或更多),您应该能够通过执行TagCollection.create([list of tags])来完成此操作。困难的部分是覆盖骨干同步以处理成功创建,并将[标签列表]转换为集合的单个模型。

希望有所帮助!

答案 1 :(得分:5)

[除了教皇的回答:]

作为参考,Rails答案(来自Creating multiple resources in a single RESTful POST in rails)是使用accepts_nested_attributes_for

class Item < ActiveRecord::Base
  has_many_and_belongs_to :tags
  accepts_nested_attributes_for :tags
end

class Tag < ActiveRecord::Base
  has_many_and_belongs_to :items
end

以下假设您已将ActiveRecord::Base.include_root_in_json = false添加到其中一个初始值设定项中(请参阅here了解原因)。

要从Backbone保存项目的标记列表,答案(来自Saving nested objects with Rails, backbone.js, and accepts_nested_attributes_for)将覆盖Item模型上的sync

sync: (method, model, options) ->
    data = JSON.stringify model.toJSON()
    if (method == "create" || method == "update")
        json = model.attributes
        json = _.extend json, {tags_attributes: model.tags.toJSON()}
        data = JSON.stringify json

    options.data = data
    options.contentType = 'application/json'
    Backbone.sync method, model, options

这个解决方案可能需要更多的hackery让Rails了解Backbone,但这就是你开始设置它们的方法。