问题
I'm trying to reproduce Railscasts 410 example (called Raffler
), changing the setup for last versions and to match my habits:
- Ember 1.0.0-rc.6
- Rails 4.0.0
- Mongoid master (4.0)
- Haml 4
- Emblem 0.3.0
In this example project, we create a simple model Entry
that calls a small Rails Rest API.
Everything works as expected, except that calling Raffler.Entry.find() to get all entries only loads the last record.
Here is my model :
Raffler.Entry = DS.Model.extend
name: DS.attr('string')
winner: DS.attr('boolean')
My store :
DS.RESTAdapter.configure('plurals', entry: 'entries')
Raffler.Store = DS.Store.extend
revision: 12
adapter: DS.RESTAdapter.create()
When calling Raffler.Entry.find()
there's an AJAX request on http://localhost:3000/entries
and all records are returned (so I don't think the problem is server side) :
{"entries":[{"id":{"$oid":"51e5b35b492cd4d286000001"},"name":"Foo","winner":true},{"id":{"$oid":"51e5b35b492cd4d286000002"},"name":"Bar","winner":false},{"id":{"$oid":"51e5b384492cd4d286000003"},"name":"Baz","winner":true}]}
But only the last of these records is really loaded in the model.
Here in the JS console :
e=Raffler.Entry.find()
e.toArray().length
=> 1
e.objectAt(0).get('name')
=> "Baz" (always the last one)
e.objectAt(1)
=> undefined
回答1:
I've finally found the cause of the problem (thanks to this question): it was because, by default, Mongoid returns JSON with id
in the format {"id":{"$oid":"51e5b35b492cd4d286000001"}
, that Ember does not seem to understand.
By adding this serializer on my Rails Entry
model:
class EntrySerializer < ActiveModel::Serializer
attributes :id, :name, :winner
def id
object._id.to_s
end
end
API request now responds this (note there's no $oid
anymore):
{"entries":[{"id":"51e5b35b492cd4d286000001","name":"Foo","winner":true},{"id":"51e5b35b492cd4d286000002","name":"Bar","winner":false},{"id":"51e5b384492cd4d286000003","name":"Baz","winner":true}]}
and Ember now loads all records :
Raffler.Entry.find().toArray().length
=> 3
EDIT: Note that this is a Mongoid 4 specific issue since the $oid
notation wasn't used in earlier versions. Here is a test with an existing Rails 3.2 / Mongoid 3.0 app :
1.9.3-p194 :006 > Mongoid::VERSION
=> "3.0.23"
1.9.3-p194 :007 > Node.first.id.as_json
=> "507521e68df996381b00151b"
Now with my Ember test under Rails 4 / Mongoid 4 :
2.0.0-p247 :007 > Mongoid::VERSION
=> "4.0.0"
2.0.0-p247 :008 > Entry.first.id.as_json
=> {"$oid"=>"51e5b35b492cd4d286000001"}
I've added the mongoid
tag to my question.
The Serializer solution works well but it means creating a serializer for every single Mongoid model...just to return to Mongoid 3 behavior...not that clean...
回答2:
You have posted that Raffler.Entry.find() returns this :
{"entries":[{"id":{"$oid":"51e5b35b492cd4d286000001"},"name":"Foo","winner":true},{"id": {"$oid":"51e5b35b492cd4d286000002"},"name":"Bar","winner":false},{"id":{"$oid":"51e5b384492cd4d286000003"},"name":"Baz","winner":true}]}
than :
e=Raffler.Entry.find()
e.entries.length
=> 3
e.entries[0]
=> {"id":{"$oid":"51e5b35b492cd4d286000001"},"name":"Foo","winner":true}
e.entries[0].name
=> "Foo"
Whats the problem?
来源:https://stackoverflow.com/questions/17692851/ember-model-only-loads-last-record