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

Che*_*tan 14 rest ruby-on-rails models backbone.js

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

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

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

Cra*_*son 7

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

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

ItemCollection

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

ItemCollection.TagCollection

保留对主TagCollection实例的引用,但仅是此Item的本地列表.由于您可以将".add"模型添加到集合中,因此您可以使用相同的模型填充多个集合.

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集合中删除,但不会删除任何其他集合.

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

希望有所帮助!

  • 另外,有用的是:当你将模型添加到多个集合时,`model.collection`将始终是它被添加到的第一个集合,除非你明确地改变它.但是当模型被销毁时,它将自动从所有集合中删除. (2认同)

Che*_*tan 5

[除了教皇的回答:]

作为参考,Rails答案(来自在rails中的单个RESTful POST中创建多个资源)将使用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
Run Code Online (Sandbox Code Playgroud)

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

要从Backbone 保存项目的标签列表,答案(来自使用Rails保存嵌套对象,backbone.js和accepts_nested_attributes_for)将覆盖syncItem模型:

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
Run Code Online (Sandbox Code Playgroud)

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