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

发布于 2024-11-19 21:59:47 字数 356 浏览 1 评论 0原文

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

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

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

I'm trying to set up an item model and a tag model that have a many-to-many relationship (items have multiple tags and tags belong to multiple items). I'm using Rails and Backbone.js, so I need to have them store, retrieve and update models seamlessly between each other. I would also love it if I could save a new list of tags for a specific item in one go from the client.

What's the correct way to structure the models and controllers on the Rails side and the models on the Backbone side to keep the system RESTful and make it easy to share models between them? Specifically, what would the API look like on the server, and what would the JSON representation of the models be in saving and retrieving them?

I would really appreciate any advice on structure, and I don't really need any code or implementation details -- just a high level setup would be great. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚雾 2024-11-26 21:59:47

看来您找到了 Rails 答案。也许我可以在主干方面提供帮助:

主干有 2 个模型构造:模型和集合(集合只是模型列表)。没有正式的方式来描述与骨干的关系(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 集合,但不是任何其他集合。

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

希望有帮助!

Looks like you found your rails answer. Maybe I can help with the backbone side:

Backbone has 2 model constructs: The Model, and the Collection (the collection just being a list of models). There is no formal way of describing relationships with backbone (afaik), so you have to do it yourself. I think what I would do to handle this structure would be 3 collections:

ItemCollection

The item collection would hold all of your items, and each item would, in turn, have it's own TagCollection, which holds the tag models that are related to it.

ItemCollection.TagCollection

Holds references to the main TagCollection instance, but is a local list for this Item only. Since you can '.add' a model to a collection, then you can have multiple collections with the same models populating them.

TagCollection

The TagCollection holds your tags. It's the "main" list of tags that every ItemCollections TagCollection would reference.

For example: You have 3 tags in your TagCollection, and 2 items.

  • item_1.TagCollection has tag_A and tag_B
  • item_2.TagCollection has tag_A and tag_C

If, item_1 then has tag_C added to it, you would simply: item_1.TagCollection.add(tag_C) Similarly, removing: item_1.TagCollection.remove(tag_C) would remove it from item_1 collection, but not any others.

Regardless of the methods you utilize, you'll need to write some code in order to have it do mass updates / creates. Remember that backbone just passes the attribute list along as a JSON string in the body of the request when it does a sync. It doesn't care what it sends. So, so long as your controller was setup to accept a list (1 or more) on it's create method, you should be able to do this pretty simply by doing TagCollection.create([list of tags]). The difficult part would be to override the backbone sync to handle the successful creation, and turning [list of tags] into individual models for the collection.

Hope that helps!

你的他你的她 2024-11-26 21:59:47

[除了 Pope 的答案:]

作为参考,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

以下假设您已将 ActiveRecord::Base.include_root_in_json = false 添加到您的初始化程序之一(请参阅 此处 了解原因)。

要从 Backbone 保存项目的标签列表,答案(来自 使用 Rails、backbone.js 和保存嵌套对象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

此解决方案可能需要更多技巧才能让 Rails 理解 Backbone,但这就是您开始设置它们的方式。

[In addition to Pope's answer:]

For reference, the Rails answer (from Creating multiple resources in a single RESTful POST in rails) is to use 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

The following assumes that you've added ActiveRecord::Base.include_root_in_json = false to one of your initializers (see here for why).

To save a list of tags for an item from Backbone, the answer (from Saving nested objects with Rails, backbone.js, and accepts_nested_attributes_for) is to override sync on the Item model:

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

This solution might require a bit more hackery to get Rails to understand Backbone, but this is how you would start setting them up.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文