This project is archived and is in readonly mode.
ActiveRecord marshal dump/load has a different behavior on boolean [rails]
Reported by prasanna | August 14th, 2010 @ 07:45 PM
Step 1: setup
a = Aritcle.new(:some_boolean => false)
a.save
write_to_memcache(a.id, Marshal.dump(a))
b = Marshal.load(read_from_memcache(a.id))
If I do:
b.some_boolean = nil
b.save
the some_boolean is not written back to the DB. DB still remains false.
But:
a.some_boolean = nil
a.save
works perfectly. DB is set to NULL.
Also:
c = Article.find(a.id)
c.some_boolean = nil
c.save
works fine. DB is set to NULL.
I'm not very sure if this is a boolean specific problem, but I'm thinking rails has some private variable to detect if the record is new, and the marshal is screwing it up.
Any hints? This one was a tough nut to crack on production :) Thanks.
Comments and changes to this ticket
-
prasanna August 14th, 2010 @ 07:52 PM
- Assigned user set to Aaron Patterson
I was wondering if this should be a bug report of a ticket?
-
Aaron Patterson August 16th, 2010 @ 06:37 PM
- State changed from new to needs-more-info
- Importance changed from to Low
I can't seem to reproduce this problem. What database are you using? What version of Rails? Can you share your schema?
Even better would be if you could supply a small rails app that reproduces the problem. I would really appreciate that! :-D
I've tried adding the following test to the AR test cases, but cannot reproduce the problem:
class Booleantest < ActiveRecord::Base; end def test_saving_after_marshal bool = Booleantest.new(:value => false) bool = Marshal.load Marshal.dump bool bool.value = nil bool.save bool.reload assert_nil bool.value end
-
prasanna August 16th, 2010 @ 08:11 PM
DataBase: mysql
Rails: 2.3.5To reproduce it: You have to put the following statement in your after_save handler.
class Bool after_save :dumper def dumper $global = Marshal.load Marshal.dump self end end Bool.new(:value => false).save puts $global.value # is false -> OK $global.value = nil $global.save puts $global.value # is nil -> OK $global.reload puts $global.value # is false -> BAD
I owe you an apology for not testing Marshal.load Marshal.dump sequence. I was binary-searching the problem and this is what I got it down to. If you need any more info, or if you are unable to reproduce this, feel free to ping me. myprasanna@gmail.com
-
prasanna August 16th, 2010 @ 08:21 PM
It is probably not a deal-breaker. I am guessing, rails works like this:
@after_save_running = true # call the after_save handlers @after_save_running = false
And since I dump in the after_save handler, that variable gets dumped as true. The next time I try to save it fails, to do it, thinking the after_save handler is calling a save function, causing recursion. I think you can safely close this.
Thanks for your time.
-
Aaron Patterson November 4th, 2010 @ 10:10 PM
- State changed from needs-more-info to invalid
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>