Skip to content

@jrafanie /gist:3011499
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
ActiveRecord::Base doesn't serialize instance variables
~/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
@pmanda-carecloud

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.