3

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

2 Answers2

4

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...

Community
  • 1
  • 1
0

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?

Rails Guy
  • 3,836
  • 1
  • 20
  • 18
  • in the case of this question `Raffler.Entry.find()` is javascript not rails – intuitivepixel Jul 17 '13 at 07:33
  • I am also asking in context of javascript. Are these output values are wrong that I have posted here? Have you tried these in your console. – Rails Guy Jul 17 '13 at 07:35
  • there are not wrong, but in the question for example doing `e.objectAt(0).get('name')` is ember.js notation and not the same as doing `e.entries[0].name` – intuitivepixel Jul 17 '13 at 07:38
  • `e.entries` doesn't even exists. `Raffler.Entry.find()` does not return the JSON but it generates an API request whose JSON is the output. The problem is that the Rails API returns 3 entries and Ember only loads the last one. – Gauthier Delacroix Jul 17 '13 at 08:32