Rails: How To Create Custom Validations 0

Posted by luca
on Friday, December 21

Often our model objects leaning toward to be confused or noisy, due to validations DSLs. Imagine a class Answer, with an attribute, that should be exactly a string representation of a boolean. Ok, I know it's an odd example, but: it's trivial enough to make this example clear, and.. It happened to me to deal with this situation. :-P

class Answer < ActiveRecord::Base
  validates_inclusion_of :value, :in => %w( true false ),
                         :message => "Should be exactly true or false."
end

Now, we try to clean-up a bit this code.
First, create a file named validations.rb into lib, then copy and paste this code:

module ActiveRecord
  module Validations
    module ClassMethods
      @@boolean_values = %w( true false )
      @@validates_boolean_msg = "Should be exactly #{@@boolean_values.join(' or ')}."

      # Check if the value is a boolean: <tt>true</tt> or <tt>false</tt>.
      def validates_boolean(*attr_names)
        configuration = { :message   => @@validates_boolean_msg,
                          :in        => @@boolean_values }

       configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
       validates_inclusion_of attr_names, configuration
      end
    end
  end
end

Then we are going to add the following line at the end of environment.rb
require 'validations'

Let's clean the code:

class Answer < ActiveRecord::Base
  validates_boolean :value
end

Is it better? Maybe.. ;-)

Ruby on Rails: Validate URL 2

Posted by luca
on Wednesday, February 21
Hi, just a snippet to validate an url with Ruby on Rails.
class WebSite < ActiveRecord::Base
  validates_format_of :url, :with => /^((http|https):\/\/)*[a-z0-9_-]{1,}\.*[a-z0-9_-]{1,}\.[a-z]{2,4}\/*$/i

  def validate
    errors.add(:url, "unexistent") unless WebSite.existent_url?(:url)
  end

  def self.existent_url?(url)
    uri = URI.parse(url)
    http_conn = Net::HTTP.new(uri.host, uri.port)
    resp, data = http_conn.head("/" , nil)
    resp.code == "200"
  end
end