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

Mongoid::Errors::Callback instead of Mongoid::Errors::Validations

    • Type: Icon: Task Task
    • Resolution: Done
    • 3.0.3
    • Affects Version/s: None
    • Component/s: None
    • None

      As far as I noticed that before_save callbacks raise Errors::Callback until I use 'errors.add'. 'errors.add' makes it throw Errors::Validations when the callback method returns false.

      However, there is a situation when this is not true. I am not sure whether this is an issue or not. Also sorry for the example. It is a simplified version of something not that crazy.


      rails new silicone -O
      cd silicone
      echo "gem 'mongoid'" >> Gemfile
      bundle
      rails g mongoid:config
      rails g scaffold post title:text
      rails g scaffold comment content:text

      nano -w app/models/comment.rb

      class Comment
        include Mongoid::Document
        field :content, type: String
      
        belongs_to :post
        before_save :check_content
      
        # recommended (?)
        validates_presence_of :post
        # not recommended (?)
        #validates_presence_of :post_id
      
        def check_content
          if content == 'bad'
            errors.add :content, 'Bad content'
            return false
          end
        end
      end
      

      nano -w app/models/post.rb

      class Post
        include Mongoid::Document
        field :title, type: String
      
        has_many :comments
      end
      

      rails console

      p = Post.create; c = Comment.new; c.post = p; c.content = 'bad'; c.save!
      Mongoid::Errors::Callback:
      Problem:
        Calling save! on Comment resulted in a false return from a callback.
      

      Note that:

      Using 'validates_presence_of :post_id' instead of 'validates_presence_of :post' throws Errors::Validation. (What seems to be good.)
      If you remove the 'has_many :comments' from post.rb then Errors::Validation is thrown instead of Errors::Callback.
      Changing "errors.add :content, 'Bad content'" to "errors.add :base, 'Bad content'" doesn't help.
      Normally errors.add in before_save callback throws Errors::Validation what I find a good and logical thing.

      Mongoid::Errors::Callback is thrown when all of these are true:
      You use 'belongs_to :something'
      something.rb contains 'has_many :your_model'
      'validates_presence_of :something' is used and not 'validates_presence_of :something_id' in your_model.rb
      You have a before_save callback.
      You return false in the callback but you also call errors.add before that.

      I find it a little misleading when writing integration tests. It is not a big issue though. I noticed this when I wanted to standardize my errors and 'validates_presence_of' lines and removing some '_id'. I read that using '_id' in validates_presence_of is not recommended.

            Assignee:
            durran Durran Jordan
            Reporter:
            veriel veriel
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: