Mongoid uses _id instead of id #8

Closed
niksosf opened this Issue Jul 1, 2011 · 4 comments

4 participants

@niksosf

Hi there, I am using MongoDB with Mongoid, where Mongoid uses the field _id instead of id.

So if I did the example provided in the readme of rails-backbone in the index.html.erb

$(function() {
window.controller = new Blog.Controllers.PostsController({posts: <%= @posts.to_json.html_safe -%>});
Backbone.history.start();
});

I'd get "id is not defined" in the Chrome console

if I changed the above to

$(function() {
window.controller = new Kiosk.Controllers.PostsController({posts: <%= @posts.to_json.gsub('_id','id').html_safe -%>});
Backbone.history.start();
});

the difference is the gsub(), it'll display okay, and works as it should until some part of the app re-request the model directly from server where no gsub('_id', 'id') was manually done, e.g., creating a new record.

I know this can be argued that it's a mongoid thing or mongodb thing in general and not this gem's business, but is there any chance that you can allow for a customizable key what is traditionally the "id".

@codebrew
Owner

Backbone models actually support you supplying an id attribute. Check out an older project of mine, specifically my mongo_model class. https://github.com/codebrew/rails3-backbone-coffeescript/blob/master/app/coffeescripts/lib/mongo_model.coffee

If you're using mongoid you need to set the idAttribute to "_id" and backbone will use it.

@codebrew codebrew closed this Jul 1, 2011
@eagsalazar

But backbone also sets the id attribute when saving which breaks on the rails side. So it doesn't look like it is really using the _id except for when fetching.

@niksosf

I haven't touched Backbone + Mongoid (but it is on the map, and not a maybe item) for a few weeks now. -- Thanks for adding your finding to this issue. - If I were to give it a shot, I would put an ApplicationController-wise before_filter if you use Mongoid and Backbone which looks for params[:id].present? && params[:_id].blank? and set params[:_id] to params[:id] manually when this simple condition is met. Think it will work?

@mankind

An alternative option is to change it serverside by overidding either the as_json method or the serializable_hash method, as described in the two links below:

http://blog.joshdzielak.com/blog/2011/12/24/tame-the-mongoid-id-field-in-your-rails-and-backbone-js-app/


  module Mongoid
    module Document
      def as_json(options={})
        attrs = super(options)
        attrs["id"] = self.persisted? ? self._id : nil
        attrs
      end
    end
 end

https://github.com/mongoid/mongoid/issues/1262


  module Mongoid
    module BackboneSerialization
      extend ActiveSupport::Concern
      module InstanceMethods
       def serializable_hash(options = nil)
          persisted? ? super.merge('id' => _id) : super
        end
      end
    end
  end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment