Hey, my first rails plugin
January 30, 2007 by Dean
Ruby on Rails allows for plugins to extend its functionality. My first attempt at one is nothing special but I am going to blog about it anyway
I needed a way to check if a number is within a range before saving a record to the database. Rails has a number of good validations built in, but not one that does that. In two or three hours, I was able to piece together a simple plugin that adds “validates_range_of” to my AR models. The code is a little ugly until I can get Greg to install a syntax highlighting plugin for this blog.
-
module ActiveRecord
-
module Validations
-
module ClassMethods
-
def validates_range_of(*attrs)
-
options = { :on => :save }
-
options.update(attrs.pop) if attrs.last.is_a?(Hash)
-
attrs.flatten!
-
unless options[:message]
-
if options[:maximum] && options[:minimum]
-
options[:message] = ‘must be betweeen ‘ + options[:minimum].to_s + ‘ and ‘ + options[:maximum].to_s
-
elsif options[:maximum]
-
options[:message] = ‘must be less than or equal to ‘ + options[:maximum].to_s
-
elsif options[:minimum]
-
options[:message] = ‘must be greater than or equal to ‘ + options[:minimum].to_s
-
else
-
raise ArgumentError, ‘Range unspecified. Specify the :maximum and/or :minimum.’
-
end
-
end
-
-
validates_numericality_of( attrs, options )
-
-
validates_each(attrs, options) do |record, attr_name, value|
-
if ((!options[:maximum].nil?) && (!options[:minimum].nil?)) &&
-
(value > options[:maximum] || value < options[:minimum])
-
record.errors.add( attr_name, options[:message] )
-
elsif (!options[:maximum].nil?) && value > options[:maximum]
-
record.errors.add( attr_name, options[:message] )
-
elsif (!options[:minimum].nil?) && value < options[:minimum]
-
record.errors.add( attr_name, options[:message] )
-
end
-
end
-
end
-
end
-
end
-
end
As you can see this plugin extends AR::Validations. So my models can use validates_range_of to check minimum and maximum values. Let’s look at the BJCP Scoresheet I needed it for:
-
class BjcpScoresheet < ActiveRecord::Base
-
belongs_to :brew_session
-
validates_associated :brew_session
-
validates_range_of :brew_session_id, { :minimum => 1, :message => ‘does not belong to a brew session’ }
-
validates_range_of :aroma_score, { :minimum => 1, :maximum => 12, :only_integer => true }
-
validates_range_of :appearance_score, { :minimum => 1, :maximum => 3, :only_integer => true }
-
validates_range_of :flavor_score, { :minimum => 1, :maximum => 20, :only_integer => true }
-
validates_range_of :mouthfeel_score, { :minimum => 1, :maximum => 10, :only_integer => true }
-
validates_range_of :impression_score, { :minimum => 1, :maximum => 10, :only_integer => true }
How nice - reusable user input validation.
–Dean

February 13th, 2007 at 12:17 am
oooo a brewer and ruby programmer… You should make something to compete with ProMash and Beermith! Open Source FTW!
February 13th, 2007 at 10:06 am
Hi Tony,
–Dean