ObjectID JSON Serialization Issue

28 views
Skip to first unread message

Felipe Coury

unread,
Nov 21, 2009, 8:15:27 AM11/21/09
to mongo...@googlegroups.com
John,

I finally had time to try the ObjectID issue again. Here's how I was able to isolate the problem:


Any hints?

-- Felipe.

Felipe Coury

unread,
Nov 21, 2009, 8:41:55 AM11/21/09
to mongo...@googlegroups.com
I have also changed test_serializations.rb to include the problem:

http://gist.github.com/240127

It's dirty (declaring classes inside the test) but it reproduces the problem.

Hope this helps, I'll continue investigating as well...

Thanks!

-- Felipe.

Felipe Coury

unread,
Nov 21, 2009, 9:11:05 AM11/21/09
to mongo...@googlegroups.com
John,

I am nowhere near confident that this is the fix, but changing the ObjectId class in types.rb to treat the hash that mongo gem's ObjectID spit when converting to JSON spits made it work, look:

    class ObjectId
      def self.to_mongo(value)
        if value.nil?
          nil
        elsif value.is_a?(Mongo::ObjectID)
          value
        elsif value.is_a?(Hash)
          Mongo::ObjectID.new(value["data"])
        else
          Mongo::ObjectID.from_string(value.to_s)
        end
      end
      
      def self.from_mongo(value)
        value
      end
    end

What are your thoughts on this?

Thanks,

-- Felipe.

John Nunemaker

unread,
Nov 21, 2009, 9:41:45 AM11/21/09
to mongo...@googlegroups.com
I think the most simple thing would be to make sure that when we are
to_json'ing any key that is an object id, we should just call to_s
first. That would probably be the most simple. I'm doing this for _id
already.
> --
> You received this message because you are subscribed to the Google
> Groups "MongoMapper" group.
> For more options, visit this group at
> http://groups.google.com/group/mongomapper?hl=en?hl=en

Alexandre Bini

unread,
Nov 28, 2009, 12:12:51 PM11/28/09
to MongoMapper
i'm having the same problem... have you solved it?

Thanks

On Nov 21, 12:41 pm, John Nunemaker <nunema...@gmail.com> wrote:
> I think the most simple thing would be to make sure that when we are
> to_json'ing any key that is an object id, we should just call to_s
> first. That would probably be the most simple. I'm doing this for _id
> already.
>
> On Sat, Nov 21, 2009 at 9:11 AM, Felipe Coury <felipe.co...@gmail.com> wrote:
> > John,
> > I am nowhere near confident that this is the fix, but changing the ObjectId
> > class in types.rb to treat the hash that mongo gem's ObjectID spit when
> > converting to JSON spits made it work, look:
> >     class ObjectId
> >       def self.to_mongo(value)
> >         if value.nil?
> >           nil
> >         elsif value.is_a?(Mongo::ObjectID)
> >           value
> >         elsif value.is_a?(Hash)
> >           Mongo::ObjectID.new(value["data"])
> >         else
> >           Mongo::ObjectID.from_string(value.to_s)
> >         end
> >       end
>
> >       def self.from_mongo(value)
> >         value
> >       end
> >     end
> > What are your thoughts on this?
> > Thanks,
> > -- Felipe.
>
> > On Sat, Nov 21, 2009 at 11:41 AM, Felipe Coury <felipe.co...@gmail.com>
> > wrote:
>
> >> I have also changed test_serializations.rb to include the problem:
> >>http://gist.github.com/240127
> >> It's dirty (declaring classes inside the test) but it reproduces the
> >> problem.
> >> Hope this helps, I'll continue investigating as well...
> >> Thanks!
> >> -- Felipe.
>
> >> On Sat, Nov 21, 2009 at 11:15 AM, Felipe Coury <felipe.co...@gmail.com>

John Nunemaker

unread,
Nov 28, 2009, 1:38:05 PM11/28/09
to mongo...@googlegroups.com
Should be fixed in latest release or in master.



On Nov 28, 2009, at 11:12 AM, Alexandre Bini <alexan...@gmail.com>
wrote:

Alexandre Bini

unread,
Nov 28, 2009, 4:37:25 PM11/28/09
to mongo...@googlegroups.com
Hi John...

i did a little bit modification to solve it

from this:
      def serializable_record       
        returning(serializable_record = {}) do
          serializable_names.each { |name| serializable_record[name] = @record.send(name) }
        end
      end


to this:
      def serializable_record       
        returning(serializable_record = {}) do
          serializable_names.each do |name|
            serializable_record[name] = (name==:id ? @record.send(name).to_s : @record.send(name))
          end
        end
      end

I don't know if it brakes other things... but solved my problem!
Alexandre Bini
fone: 18 3641-4382
site: www.voraz.com.br
blog da voraz: http://blog.voraz.com.br

blog pessoal: www.alexandrebini.com
msn: alex...@voraz.com.br
gtalk: alexan...@gmail.com
skype: voraz.com.br
Rua Americana, 104, Birigui-SP

Alexandre Bini

unread,
Nov 28, 2009, 4:38:20 PM11/28/09
to mongo...@googlegroups.com
I did it in  lib/mongo_mapper/serialization.rb

Steve England

unread,
Dec 1, 2009, 7:50:08 AM12/1/09
to MongoMapper
Hi Alexandre,

Your fix solved my issues with JSON serialisation. Thanks.


On Nov 28, 9:38 pm, Alexandre Bini <alexandreb...@gmail.com> wrote:
> I did it in  lib/mongo_mapper/serialization.rb
>
> On Sat, Nov 28, 2009 at 7:37 PM, Alexandre Bini <alexandreb...@gmail.com>wrote:
>
>
>
>
>
> > Hi John...
>
> > i did a little bit modification to solve it
>
> > from this:
>
> >>       def serializable_record
> >>         returning(serializable_record = {}) do
> >>           serializable_names.each { |name| serializable_record[name] =
> >> @record.send(name) }
> >>         end
> >>       end
>
> > to this:
>
> >>       def serializable_record
> >>         returning(serializable_record = {}) do
> >>           serializable_names.each do |name|
> >>             serializable_record[name] = (name==:id ?
> >> @record.send(name).to_s : @record.send(name))
> >>           end
> >>         end
> >>       end
>
> > I don't know if it brakes other things... but solved my problem!
>
> > On Sat, Nov 28, 2009 at 4:38 PM, John Nunemaker <nunema...@gmail.com>wrote:
>
> >> Should be fixed in latest release or in master.
>
> >> On Nov 28, 2009, at 11:12 AM, Alexandre Bini <alexandreb...@gmail.com>
> > msn: alexan...@voraz.com.br
> > gtalk: alexandreb...@gmail.com
> > skype: voraz.com.br
> > Rua Americana, 104, Birigui-SP
>
> --
> Alexandre Bini
> fone: 18 3641-4382
> site:www.voraz.com.br
> blog da voraz:http://blog.voraz.com.br
>
> blog pessoal:www.alexandrebini.com
> msn: alexan...@voraz.com.br
> gtalk: alexandreb...@gmail.com

Felipe Coury

unread,
Dec 1, 2009, 1:12:14 PM12/1/09
to mongo...@googlegroups.com
This is not a definitive fix, since it still breaks for foreign keys (the foreign key ObjectID is not being enclosed in quotes). This fix, however, makes it work:

      def serializable_record
        returning(serializable_record = {}) do
          serializable_names.each do |name|
            if (record = @record.send(name)).is_a?(Mongo::ObjectID)
              serializable_record[name] = record.to_s
            else
              serializable_record[name] = record
            end
          end
        end
      end

And here's the updated testcase:


Best regards,

--
Felipe Gonçalves Coury
CTO, Webbynode - Serious hosting for Developers
http://webbynode.com

Latest from Twitter:

Steve England

unread,
Dec 2, 2009, 5:58:13 AM12/2/09
to MongoMapper
Awesome. Thanks Felipe

Justin Palmer

unread,
Dec 2, 2009, 9:38:37 PM12/2/09
to MongoMapper
I was able to fix this in regards to the JSON gem by adding a special
type as it suggests. I'm not sure if this fix works for
ActiveSupport's to_json, but here it is:

class Mongo::ObjectID
def to_json(*a)
to_s.inspect
end
end

http://flori.github.com/json/

I'll be the first to admit I didn't spend a lot of time checking this
thoroughly. Your milage may vary.

-Justin

On Dec 2, 2:58 am, Steve England <stephen.engl...@gmail.com> wrote:
> Awesome. Thanks Felipe

John Nunemaker

unread,
Dec 2, 2009, 10:28:43 PM12/2/09
to mongo...@googlegroups.com
Are you guys all on the latest version of the gem? I swear I have this fixed.


I'll be patching the ruby driver soon but until then, I have the hack above in MM already. If you aren't using 0.6.5, upgrade. If you are then there must be another issue.

Justin Palmer

unread,
Dec 3, 2009, 12:21:28 PM12/3/09
to MongoMapper
I think you need to tweak that a bit. The to_s value isn't quoted.
Note the *id fields below after the to_json call. All of them lack
quotes resulting in invalid JSON.

>> m = Mention.find(:first)
=> #<Mention tweet_id: 4b15ddc18aebb17556000001, created_at: Wed Dec
02 03:23:45 UTC 2009, updated_at: Wed Dec 02 03:23:45 UTC 2009, _id:
4b15ddc18aebb17556000002, player_id: 4b15db8e8aebb1744900018e>
>> m.to_json
=> "{\"tweet_id\":4b15ddc18aebb17556000001,\"created_at\":\"2009/12/02
03:23:45 +0000\",\"updated_at\":\"2009/12/02 03:23:45 +0000\",
\"player_id\":4b15db8e8aebb1744900018e,\"id\":
4b15ddc18aebb17556000002}"


On Dec 2, 7:28 pm, John Nunemaker <nunema...@gmail.com> wrote:
> Are you guys all on the latest version of the gem? I swear I have this
> fixed.
>
> http://github.com/jnunemaker/mongomapper/blob/master/lib/mongo_mapper...

Felipe Coury

unread,
Dec 3, 2009, 12:22:09 PM12/3/09
to mongo...@googlegroups.com
Yeah, that was the exact problem I was having too.

--
Felipe Gonçalves Coury
CTO, Webbynode - Serious hosting for Developers
http://webbynode.com

Latest from Twitter:



John Nunemaker

unread,
Dec 3, 2009, 2:10:10 PM12/3/09
to mongo...@googlegroups.com
10-4. I'll tweak it. Thanks!
Reply all
Reply to author
Forward
0 new messages