Ember-data和MongoDB,如何处理_id

时间:2012-07-20 01:50:02

标签: ruby-on-rails mongodb mongoid ember.js ember-data

我正在使用带有rails和MongoDB的ember-data,并且对于在MongoDB中存储ID的方式存在问题 - 在_id字段中。

Ember-data将使用id作为ID的默认字段,所以我试图像这样覆盖它:

App.User = DS.Model.extend
    primaryKey: "_id"
    name: DS.attr "string"
    image: DS.attr "string"

这似乎在大部分时间都有效,但在某些情况下我从ember说得到例外:

  

未捕获错误:断言失败:您的服务器返回了哈希值   key _id但你没有映射

我怀疑这可能是ember-data中的一个错误,因为它仍处于开发阶段,但是我试图找到一种方法来将_id映射到服务器端的id中?我正在使用mongoid来进行mongo映射。

9 个答案:

答案 0 :(得分:8)

如果您正在使用Mongoid,那么这是一个解决方案,因此您不必为每个序列化程序添加方法def id; object._id.to_s; end

添加以下Rails初始化程序

Mongoid 3.x

module Moped
  module BSON
    class ObjectId
      alias :to_json :to_s
      alias :as_json :to_s
    end
  end
end

Mongoid 4

module BSON
  class ObjectId
    alias :to_json :to_s
    alias :as_json :to_s
  end
end

Building

的活动模型序列化程序
class BuildingSerializer < ActiveModel::Serializer
  attributes :id, :name
end

产生的JSON

{
  "buildings": [
    {"id":"5338f70741727450f8000000","name":"City Hall"},    
    {"id":"5338f70741727450f8010000","name":"Firestation"}
  ]
}

这是brentkirby建议的猴子补丁,并由arthurnn

更新为Mongoid 4

答案 1 :(得分:3)

另一种方法可能是ActiveModel::Serializer使用(如果可能的话)。 (我认为它应该接近rabl(?))

来自ember-data gihtub:https://github.com/emberjs/data
对遵循active_model_serializers gem的约定的Rails应用程序的开箱即用支持

当我们开始使用ember-data时,我们正在制作as_json(),但使用gem肯定更好:)

答案 2 :(得分:1)

啊,不是在你的JSON中包含_id,你可以用JSON来代替使用id方法而不是_id属性。方法:

您可以使用rabl,JSON可以是:

object @user 
attributes :id, :email
node(:full_name) {|user| "#{user.first_name} #{user.last_name}"}

你也可以制作as_json方法

class User
  def as_json(args={})
    super args.merge(:only => [:email], :methods => [:id, :full_name])
  end
end

答案 3 :(得分:1)

我在使用带有ember-resource和couchdb的ember.js时遇到了类似的问题,它还将它的ID存储为_id

作为这个问题的解决方案,我为包含计算属性的所有模型类定义了一个超类,以便将_id复制到id,如下所示:

// get over the fact that couchdb uses _id, ember-resource uses id
id: function(key, value) {
    // map _id (couchdb) to id (ember)
    if (arguments.length === 1) {
        return this.get('_id');
    }
    else {
        this.set('_id', value);
        return value;
    }
}.property('_id').cacheable()

也许这也可以解决你的问题?

答案 4 :(得分:1)

最好的方法是使用ActiveModel::Serializers。由于我们使用 Mongoid ,您需要添加类似的include语句(请参阅benedikt的gist):

# config/initializers/active_model_serializers.rb
Mongoid::Document.send(:include, ActiveModel::SerializerSupport)
Mongoid::Criteria.delegate(:active_model_serializer, :to => :to_a)

然后包括你的序列化程序。这样的事情:

# app/serializers/user_serializer.rb
class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :email
  def id
    object._id
  end 
end

这解决了_id问题

答案 5 :(得分:1)

耶稣答案的第二部分用Rails 4 / Ruby2修复了我的id问题,除了我必须.to_s的_id。

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :email
  def id
    object._id.to_s
  end
end

答案 6 :(得分:0)

如果你使用Mongoid3,这里的猴子补丁可能适合你。

https://gist.github.com/4700909

答案 7 :(得分:0)

我不确切知道这个添加的时间,但你可以告诉Ember-Data primaryKey是_id:

DS.RESTAdapter.extend({
  serializer: DS.RESTSerializer.extend({
    primaryKey: '_id'
  })
});

答案 8 :(得分:0)

虽然问题很老但我仍然认为我的答案可以帮助其他人:

如果您使用的是ActiveModelSerializer,那么您只需要这样做:

class UserSerializer < ActiveModel::Serializer
     attributes :id , :name
end

一切正常。我正在前端使用emberjs。