如何使用RESTAdapter处理单一资源

时间:2012-09-22 01:00:30

标签: rest ember.js ember-data

如何在ember-data中处理奇异资源?假设我有以下RESTful路由:

GET /cart
POST /cart
UPDATE /cart
DELETE /cart

ember-data期望find()返回一个数组,并且它会自动尝试复数我传递给我的模型的任何网址。处理这种情况的最佳方法是什么?

4 个答案:

答案 0 :(得分:7)

你可以在这里做很多事情。

RESTAdapter调用pluralize,在名称的末尾添加“s”,或者在复数哈希中查找名称(如果存在)。假设您的DS.Model为App.Cart

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L209

DS.RESTAdapter.create({
  plurals: {
    cart: 'cart'
  }
});

如果您的URL方案非常不同并且需要一些其他逻辑,您实际上可以覆盖buildURL函数。

https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js#L288

DS.RestAdapter.create({
  buildURL: function() {
    return "/always_this"
  })
});

答案 1 :(得分:3)

所以,我在github上找到了this pull request。它已经有8个月了,所以由于此后增加的复杂性将无法工作,但我已经实施了建议的解决方法:

App.store = DS.Store.create({
  revision: 4,
  adapter: DS.RESTAdapter.create({
    plurals: {
      'cart': 'cart'
    }
  })
});

App.Cart.reopenClass({
  find: function () {
    this._super("singleton");
  }
});

在我的服务器上(我正在使用rails),我必须在路由中添加以下内容:

get "cart/:ignored" => "carts#show"

然后我必须将以下内容添加到CartSerializer(使用active_model_serializers gem):

attributes :id
def id
  "singleton"
end

这是必要的,因为,显然,如果json响应中的id与find()(在这种情况下为singleton)请求的id不匹配,那么ember将不会将数据加载到模型。

现在,这显然不是理想的解决方案,但是在ember-data增加对它的支持之前,它似乎是最不痛苦的方式。

顺便说一下,我提交了an issue来添加支持。

答案 2 :(得分:2)

以下是我如何在Ember 1.9中使用它。首先,我阅读了指南的this section。在最底部,它解释了如何仅为一个模型覆盖适配器。

App.CartAdapter = App.ApplicationAdapter.extend {
  pathForType: ->
    'cart'
}

pathForType函数是多元化发生的地方(至少在我正在使用的RESTAdapter中),因此适配器的其他功能都不会受到影响(如主机或命名空间)。

答案 3 :(得分:1)

只是为了分享一个对我有用的更完整的解决方案 - 扩展你的应用程序的ApplicationRouter(它本身扩展了DS.RESTAdapter)。

App.CartAdapter = App.ApplicationAdapter.extend({
    pathForType: function(type) {
        return 'cart';
    }
});

接下来,在App.Router.map中定义您的资源:

this.resource('cart');

最后,传递一个空字符串作为路径中的id。这是允许在没有id的情况下生成URL的原因。

App.CartRoute = Ember.Route.extend({
    model : function(params) {
        return this.store.find('cart', '');
    }
});