schwift
schwift

Reputation: 339

MongoMapper custom validation

I have this ruby class with an array of links. As it is now I'm able to save a Paper object even if the array contains links that are not valid urls. I have a method that runs through the array and validates the urls and returns false if a url is invalid. But I want to get an error message when I try to call Paper.save. Is that possible?

class Paper
  include MongoMapper::Document

  key :links,       Array

  validates_presence_of :links

  def validate_urls
    reg = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix
    status = []
    links.each do |link|
      if link.match(reg)
        status.push('true')
      else
        if "http://#{link}".match(reg)
          status.push('true')
        else
          status.push('false')
        end
      end
    end
    if status.include?('false')
      return false
    else
      return true
    end
  end

end

Upvotes: 2

Views: 1196

Answers (1)

Brian Hempel
Brian Hempel

Reputation: 9094

If you're using MongoMapper from GitHub (which supports ActiveModel), see http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validate

class Paper
  include MongoMapper::Document

  key :links,       Array

  validates_presence_of :links
  validate :validate_urls

  def validate_urls
    reg = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/ix
    status = []
    links.each do |link|
      if link.match(reg)
        status.push('true')
      else
        if "http://#{link}".match(reg)
          status.push('true')
        else
          status.push('false')
        end
      end
    end
    if status.include?('false')

      # add errors to make the save fail
      errors.add :links, 'must all be valid urls'

    end
  end

end

Not sure if that code works with the 0.8.6 gem but it might.

Also, it doesn't apply in this case but if it weren't an array you could smash it all into a single line:

key :link, String, :format => /your regex here/

Upvotes: 5

Related Questions