Hey, my first rails plugin

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 :-D

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.

  1. module ActiveRecord
  2. module Validations
  3. module ClassMethods
  4. def validates_range_of(*attrs)
  5. options = {  :on => :save  }
  6. options.update(attrs.pop) if attrs.last.is_a?(Hash)
  7. attrs.flatten!
  8. unless options[:message]
  9. if options[:maximum] && options[:minimum]
  10. options[:message] = ‘must be betweeen ‘ + options[:minimum].to_s + ‘ and ‘ + options[:maximum].to_s
  11. elsif options[:maximum]
  12. options[:message] = ‘must be less than or equal to ‘ + options[:maximum].to_s
  13. elsif options[:minimum]
  14. options[:message] = ‘must be greater than or equal to ‘ + options[:minimum].to_s
  15. else
  16. raise ArgumentError, ‘Range unspecified.  Specify the :maximum and/or :minimum.’
  17. end
  18. end
  19.  
  20. validates_numericality_of( attrs, options )
  21.  
  22. validates_each(attrs, options) do |record, attr_name, value|
  23. if ((!options[:maximum].nil?) && (!options[:minimum].nil?)) &&
  24. (value > options[:maximum] || value < options[:minimum])
  25. record.errors.add( attr_name, options[:message] )
  26. elsif (!options[:maximum].nil?) && value > options[:maximum]
  27. record.errors.add( attr_name, options[:message] )
  28. elsif (!options[:minimum].nil?) && value < options[:minimum]
  29. record.errors.add( attr_name, options[:message] )
  30. end
  31. end
  32. end
  33. end
  34. end
  35. 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:

  1. class BjcpScoresheet < ActiveRecord::Base
  2. belongs_to :brew_session
  3. validates_associated :brew_session
  4. validates_range_of :brew_session_id, { :minimum => 1, :message => ‘does not belong to a brew session’ }
  5. validates_range_of :aroma_score, { :minimum => 1, :maximum => 12, :only_integer => true }
  6. validates_range_of :appearance_score, { :minimum => 1, :maximum => 3, :only_integer => true }
  7. validates_range_of :flavor_score, { :minimum => 1, :maximum => 20, :only_integer => true }
  8. validates_range_of :mouthfeel_score, { :minimum => 1, :maximum => 10, :only_integer => true }
  9. validates_range_of :impression_score, { :minimum => 1, :maximum => 10, :only_integer => true }

How nice - reusable user input validation.

–Dean

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Posted by: Dean @ 1:46 am

Categories: Dean, code, ruby |

2 Responses to “Hey, my first rails plugin”

  1. tony Says:

    oooo a brewer and ruby programmer… You should make something to compete with ProMash and Beermith! Open Source FTW!

  2. Dean Says:

    Hi Tony,

    :-D BrewSession will compete with Promash and Beersmith, except we’re keeping it to ourselves. It will be free to use however. There is an open-source brewing software movement starting at http://www.beerhackers.com/ and we’re going to work with them to inter-operate.
    –Dean

Leave a Reply

You must be logged in to post a comment.

Our Sponsors