Created
June 28, 2012 13:49
-
-
Save jrafanie/3011499 to your computer and use it in GitHub Desktop.
ActiveRecord::Base doesn't serialize instance variables
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
~/Code/playground/rails-3-2-stable $ cat app/models/person.rb | |
class Person | |
attr_accessor :abc | |
end | |
~/Code/playground/rails-3-2-stable $ cat app/models/story.rb | |
class Story < ActiveRecord::Base | |
attr_accessor :abc | |
end | |
~/Code/playground/rails-3-2-stable $ cat app/models/user.rb | |
class User < ActiveRecord::Base | |
attr_accessor :abc | |
def encode_with(coder) | |
super | |
coder['abc'] = abc | |
end | |
def init_with(coder) | |
super | |
@abc = coder['abc'] | |
self | |
end | |
end | |
~/Code/playground/rails-3-2-stable $ bundle exec rails c | |
Loading development environment (Rails 3.2.2) | |
# Person is a plain old ruby object which serializes instance variables correctly in 1.9.3: | |
1.9.3p125 :001 > Person.new.tap {|p| p.abc = 123} | |
=> #<Person:0x007fd325c07290 @abc=123> | |
1.9.3p125 :002 > Person.new.tap {|p| p.abc = 123}.abc | |
=> 123 | |
1.9.3p125 :003 > Person.new.tap {|p| p.abc = 123}.to_yaml | |
=> "--- !ruby/object:Person\nabc: 123\n" | |
1.9.3p125 :004 > YAML.load(Person.new.tap {|p| p.abc = 123}.to_yaml) | |
=> #<Person:0x007fd325cdfcd0 @abc=123> | |
1.9.3p125 :005 > YAML.load(Person.new.tap {|p| p.abc = 123}.to_yaml).abc | |
=> 123 | |
# Story is a ActiveRecord::Base object which only serializes @attributes but not instance variables | |
# (see: https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/base.rb#L582) | |
1.9.3p125 :001 > Story.new.tap {|s| s.abc = 123} | |
=> #<Story id: nil, type: nil, name: nil, created_at: nil, updated_at: nil> | |
1.9.3p125 :002 > Story.new.tap {|s| s.abc = 123}.abc | |
=> 123 | |
1.9.3p125 :003 > Story.new.tap {|s| s.abc = 123}.to_yaml | |
=> "--- !ruby/object:Story\nattributes:\n id: \n type: \n name: \n created_at: \n updated_at: \n" | |
1.9.3p125 :004 > YAML.load(Story.new.tap {|s| s.abc = 123}.to_yaml) | |
=> #<Story id: nil, type: nil, name: nil, created_at: nil, updated_at: nil> | |
1.9.3p125 :005 > YAML.load(Story.new.tap {|s| s.abc = 123}.to_yaml).abc | |
=> nil | |
# User is a ActiveRecord::Base object which has a custom encode_with and init_with methods to | |
# properly serialize the abc instance variable. | |
1.9.3p125 :001 > User.new.tap {|u| u.abc = 123} | |
=> #<User id: nil, type: nil, name: nil, created_at: nil, updated_at: nil> | |
1.9.3p125 :002 > User.new.tap {|u| u.abc = 123}.abc | |
=> 123 | |
1.9.3p125 :003 > User.new.tap {|u| u.abc = 123}.to_yaml | |
=> "--- !ruby/object:User\nattributes:\n id: \n type: \n name: \n created_at: \n updated_at: \nabc: 123\n" | |
1.9.3p125 :004 > YAML.load(User.new.tap {|u| u.abc = 123}.to_yaml) | |
=> #<User id: nil, type: nil, name: nil, created_at: nil, updated_at: nil> | |
1.9.3p125 :005 > YAML.load(User.new.tap {|u| u.abc = 123}.to_yaml).abc | |
=> 123 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi jrafanie,
You saved us a lot of time running around tweaking between delayed_jobs 2 (uses syck yaml parser) and delayed_jobs 3 (uses psych yaml parser). In the older version we persisted attr_accessors but the newer version doesn't care about them. So we applied your style of overriding encode_with and init_with methods to add attr_accessors to the coder hash and that took care of Psych parser's behavior of being ignorant towards instance variables.
Thanks you so much!