在hasMany关系中创建新骨干关系模型实例的“正确”方法

时间:2013-12-05 23:58:53

标签: ruby-on-rails backbone-relational

我是一个试图成为Rails API服务器+ Backbone前端人的Rails人,我有一种强烈的感觉,我不会在另一个包含的集合中创建一个模型的新实例。宾语。

以下所有我都使用骨干关系。 FWIW我也在使用木偶,但我认为这并不重要。

要具体说明我有一个引擎模型,那引擎可以有很多Gears。我正在将旧Rails代码中的引擎编辑页面转换为一个小的Backbone应用程序。我的新Backbone Engine编辑页面如下所示:

Engine edit page mockup

当我点击“添加新装备”按钮时,我理想的结果是(1)服务器创建(持久)连接到引擎的新空白Gear对象和(2)新主干添加了与新服务器状态同步的Gear实例。

在纯粹的Rails世界中,我可以发布到以下URL:

api/engines/42/gears

这会在服务器端创建新的Gear实例,我会重定向到某个页面。我只是不知道如何在客户端做到这一点,并最终将所有内容同步。

以下是EngineGearGears集合的Backbone(关系)模型:

class Engine extends Backbone.RelationalModel
  urlRoot: '/api/engines'

  relations: [
    {
      type: Backbone.HasMany,
      key: 'gears',
      relatedModel: 'Gear'
      collectionType: 'Gears',
      reverseRelation: {
        key: 'engine',
        includeInJSON: false
      }
    }
  ]

Engine.setup()   // here b/c I'm using coffeescript

这是Gears集合:

class Gears extends Backbone.Collection
  model: Gear

这是Gear模型:

class Gear extends Backbone.RelationalModel
  urlRoot: '/api/gears'

Gear.setup()    // here b/c I'm using coffeescript

我可以使用Gear创建新的主干newGear = new Gear()对象,但如何将其连接到引擎列表中?如果我说myEngine.get('gears').add(newGear),我应该保存什么?

我希望我能以某种方式保存(POST)新装备而不在Engine实例上调用save()。尝试更新引擎实例(上面的myEngine.save()之后)似乎并没有真正做到这一点,因为新的Gear实例还没有ID,所以引擎更新调用就吓坏了。

如果有人能指引我朝着正确的方向前进,我会很感激!

对于那些最终在这里寻找有关Rails Engines的信息的人感到抱歉...选择不好的示例: - )

1 个答案:

答案 0 :(得分:1)

我能够弄清楚这一点。写一个SO问题确实有助于集中思想: - )

Gear添加到Engine的最终代码非常简单:

gear = new Gear()
myEngine.get('gears').create(gear)

之前我曾尝试过此操作(实际上我将第二行拆分为add(...)后跟save()调用)但是它无效。这有多种原因,其中最大的原因是我对HasMany关系的设置。这是Engine类的更新关系:

class Engine extends Backbone.RelationalModel
  urlRoot: '/api/engines'

  relations: [
    {
      type: Backbone.HasMany,
      key: 'gears',
      relatedModel: 'Gear'
      collectionType: 'Gears',
      reverseRelation: {
        key: 'engine',
        keySource: 'engine_id',   # wasn't here before
        includeInJSON: 'id'       # used to be false
      }
    }
  ]

keySourceincludeInJSON一起让我指定我想要如何在齿轮的JSON输出中表示引擎。早些时候,当我只有includeInJSON的默认值时,我得到整个引擎序列化齿轮的JSON输出,这是我不想要的。所以我把它改成了假。但是在最终用于将新POST对象发送到要创建的服务器的Gear中,我确实需要引擎外键,以便Rails服务器可以正确地连接新模型。如果我将includeInJSON切换为'id',以便序列化的{engine: <id value>}更好(除了Rails我真的想要{engine_id: <id value>}。但是,只要我说{{1当我真的想要整个模型时,我得到了引擎的ID。myGear.get('engine')的发现让我发送keySource到API服务器,同时仍让我通过{{获取引擎模型1}}。

然后在我的Rails API中,我可以使用{engine_id: <id value>}并创建适当的空白myGear.get('engine'),然后以JSON的形式将其吐回客户端,然后更新视图。

如果其他人对整个情况有任何见解,我当然仍然很乐意听到他们。