-
Type: Task
-
Resolution: Done
-
Affects Version/s: None
-
Component/s: None
-
None
I started getting Mongoid::Errors::UnknownAttribute exceptions when running a #set operation on a model instance with a private setter. I've traced the issue to the Mongoid::Attributes::Processing module's #process_attribute method, which is checking for the presence of the attribute (I assume in case the user is trying to set a dynamic attribute without including the Mongoid::Attributes::Dynamic module). However, it is only checking for public methods.
Based on the intended use, I think the presence of a protected or private setter would still indicate that there is an existing attribute there. I propose a minor update to the #process_attribute method to allow protected or private setter methods. The partial stack trace and commits for the test case and proposed solution are below.
Mongoid::Errors::UnknownAttribute: Problem: Attempted to set a value for 'published_order' which is not allowed on the model BlogPost. Summary: Without including Mongoid::Attributes::Dynamic in your model and the attribute does not already exist in the attributes hash, attempting to call BlogPost#published_order= for it is not allowed. This is also triggered by passing the attribute to any method that accepts an attributes hash, and is raised instead of getting a NoMethodError. Resolution: You can include Mongoid::Attributes::Dynamic if you expect to be writing values for undefined fields often. /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/attributes/processing.rb:96:in `process_attribute' /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/persistable/settable.rb:25:in `block (2 levels) in set' /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/persistable.rb:172:in `block in process_atomic_operations' /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/persistable.rb:167:in `each' /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/persistable.rb:167:in `process_atomic_operations' /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/persistable/settable.rb:24:in `block in set' /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/persistable.rb:145:in `prepare_atomic_operation' /Users/peregrine/.rvm/gems/ruby-2.2.0@nova/gems/mongoid-4.0.2/lib/mongoid/persistable/settable.rb:23:in `set'
I've reproduced the issue with a test case on this commit:
https://github.com/sleepingkingstudios/mongoid/commit/f2738edf8a392fd99a3f15f4a6e735d22a927516
And a solution on this commit:
https://github.com/sleepingkingstudios/mongoid/commit/804db5d3a6c205c80e7e76f495960046f4e58f72