Ember-data and MongoDB, how to handle _id

2020-06-03 06:29发布

I'm using ember-data with rails and MongoDB and am having problem with the way IDs are stored in MongoDB - in a _id field.

Ember-data will use id as the default field for ID so I tried to override it like this:

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

This seems to work most of the time but in some instances I get exceptions from ember saying:

Uncaught Error: assertion failed: Your server returned a hash with the key _id but you have no mappings

I suspect this might be a bug in ember-data because it's still heavily under development, but I was trying to find a way to get to map _id to id on the server side in rails? I'm using mongoid to do the mongo mapping.

9条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-06-03 06:59

An other way could be to use (if possible for you) the ActiveModel::Serializer. (I think it should be close to rabl (?))

From the ember-data gihtub: https://github.com/emberjs/data:
Out of the box support for Rails apps that follow the active_model_serializers gem's conventions

When we began with ember-data we were crafting as_json(), but using the gem is definitely better :)

查看更多
地球回转人心会变
3楼-- · 2020-06-03 07:02

If you are using Mongoid here is a solution that makes it so you don't have to add a method def id; object._id.to_s; end to every serializer

Add the following Rails initializer

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

Active Model Serializer for Building

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

Resulting JSON

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

This is a monkey patch suggested by brentkirby and updated for Mongoid 4 by arthurnn

查看更多
\"骚年 ilove
4楼-- · 2020-06-03 07:03

The second part of joscas's answer fixed the id issue for me with Rails4/Ruby2 except I had to .to_s the _id.

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :email
  def id
    object._id.to_s
  end
end
查看更多
【Aperson】
5楼-- · 2020-06-03 07:11

I don't know exactly when this was added, but you can just tell Ember-Data that the primaryKey is _id:

DS.RESTAdapter.extend({
  serializer: DS.RESTSerializer.extend({
    primaryKey: '_id'
  })
});
查看更多
ゆ 、 Hurt°
6楼-- · 2020-06-03 07:14

Although the question is quite old but i still think my answer could help others:

If you are using ActiveModelSerializer then you just need to do this :

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

It works all fine. I am using emberjs on the front end btw.

查看更多
爷、活的狠高调
7楼-- · 2020-06-03 07:17

The best way is to use ActiveModel::Serializers. Since we are using Mongoid, you will need to add an include statement like that (see this gist from benedikt):

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

And then include your serializer. Something like that:

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

This fixes the _id problem

查看更多
登录 后发表回答