Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-4015

Document#set raising error when attribute setter is private.

    • Type: Icon: Task Task
    • Resolution: Done
    • 5.0.0
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      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

            Assignee:
            Unassigned Unassigned
            Reporter:
            sleepingkingstudios sleepingkingstudios
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: