Skip to content
This repository has been archived by the owner on Jun 16, 2020. It is now read-only.

Issue with PaperTrail gem and yaml conversion of bitmask_attributes #32

Open
glennfu opened this issue Nov 13, 2012 · 3 comments
Open

Comments

@glennfu
Copy link

glennfu commented Nov 13, 2012

PaperTrail is a handy gem that lets you track old versions of models. It tracks by doing:

string = model.changes.to_yaml

Then later parsing them back with

YAML::load(string)

Unfortunately this fails when you've changed something with Bitmask Attributes. In my model I have:

  bitmask :days_of_week, :as => [:sunday, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday]

If I set it to [:saturday], then reload, I see the value of days_of_week is 64. If I set it to [:monday, :tuesday] and call b.changes, I see:

1.9.2p318 > b.changes
 => {"days_of_week"=>[64, [:monday, :tuesday]]}

If I convert to yaml and back I get:

1.9.2p318 > b.changes.to_yaml
 => "--- !map:ActiveSupport::HashWithIndifferentAccess \ndays_of_week: \n- 64\n- !seq:BitmaskAttributes::ValueProxy \n  - :monday\n  - :tuesday\n" 
1.9.2p318 > YAML.load(b.changes.to_yaml)
NoMethodError: undefined method `key?' for nil:NilClass
    from /Users/glenn/.rvm/gems/ruby-1.9.2-p318/gems/bitmask_attributes-0.3.0/lib/bitmask_attributes/value_proxy.rb:35:in `block in validate!'
    from /Users/glenn/.rvm/gems/ruby-1.9.2-p318/gems/bitmask_attributes-0.3.0/lib/bitmask_attributes/value_proxy.rb:34:in `each'
    from /Users/glenn/.rvm/gems/ruby-1.9.2-p318/gems/bitmask_attributes-0.3.0/lib/bitmask_attributes/value_proxy.rb:34:in `validate!'
    from /Users/glenn/.rvm/gems/ruby-1.9.2-p318/gems/bitmask_attributes-0.3.0/lib/bitmask_attributes/value_proxy.rb:48:in `updated!'

Do you have any suggestions for what I can do about this? I'm not sure if the problem should be solved so that .changes returns something different, or if it's a yaml conversion thing that needs to be addressed. Either way I'd really appreciate your help. Thanks!

@glennfu
Copy link
Author

glennfu commented Mar 18, 2013

I'm not sure if this is the best solution, but this has helped me:

module BitmaskAttributes
    class ValueProxy

        def to_yaml(options={})
            self.to_i.to_yaml(options)
        end

    end
end

@adamico
Copy link

adamico commented Oct 8, 2014

I'm struggling with the same issue even if I'm not using Papertrail. In one of my projects I need to extract the difference resulting from foo.changes when I change the bitmask attributes.
I'm not fond of overriding methods of ActiveModel::Dirty. One of the possible solutions could be to write a method to return the difference in one of these two ways:

{"days_of_week"=>[[:saturday], [:monday, :tuesday]]}

#or

{"days_of_week"=>[64, 19]} #substitute 19 with the new bitmask integer value

< goes to dig the source to find how the reverse bitmask method in the gem is called >

@adamico
Copy link

adamico commented Oct 8, 2014

got it

>Foo.days_of_week_for_bitmask(foo.days_of_week_was)
  => [:saturday]

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants