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.
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
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 :)
Ahh, instead of including _id in your JSON, you could craft the JSON to instead use the id method rather than the _id attribute. Ways:
You could use rabl, and the JSON could be like:
object @user
attributes :id, :email
node(:full_name) {|user| "#{user.first_name} #{user.last_name}"}
You could also craft the as_json method
class User
def as_json(args={})
super args.merge(:only => [:email], :methods => [:id, :full_name])
end
end
I had a similar problem using ember.js with ember-resource and couchdb, which also stores it's IDs as _id
.
As solution to this problem I defined a superclass for all my model classes containing a computed property to duplicate _id
into id
like this:
// 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()
Maybe this could solve your problem too?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With