Using Regular Expression in Ruby on Rails — Regexp for Password Validation

A regular expression (abbreviated as regexp or regex, with plural forms regexps, regexes, or regexen) is a string that describes or matches a set of strings, according to certain syntax rules. Regular expressions are used by many text editors and utilities to search and manipulate bodies of text based on certain patterns. Many programming languages support regular expressions for string manipulation. Ruby has a strong Regular Expression engine built directly as a class of Ruby Programming language as Regexp
Here we will go through an example which will validate the password string.
Lets say we have to implement the following validations to validate a password…

  • Password should contain atleast one integer.
  • Password should contain atleast one alphabet(either in downcase or upcase).
  • Password can have special characters from 20 to 7E ascii values.
  • Password should be minimum of 8 and maximum of 40 cahracters long.

To fulfill above requirements we can have a regular expression like…

/^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/

in ruby programming language we can have a number of ways to define this regular expression as…
■ reg = Regexp.new(“^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$”)
or
■ reg = %r(^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$)
or simply
■ reg = /^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/

Now look what exactly this regex is doing…
(?=.*\d) shows that the string should contain atleast one integer.
(?=.*([a-z]|[A-Z])) shows that the string should contain atleast one alphabet either from downcase or upcase.
([\x20-\x7E]) shows that string can have special characters of ascii values 20 to 7E.
{8,40} shows that string should be minimum of 8 to maximum of 40 cahracters long.
We can simply use this regular expression for manual handling of password in an action as…

def validate_password(password)

  reg = /^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/

return (reg.match(password))? true : false

end

How to implement this regular expression in a model class in ruby on rails for password validation ?

To implement this regular expression in the model class in the rails way we can do it like…

class MyModel

  validates_format_of :password, :with => /^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,40}$/

end

4 comments October 19, 2006

Rake task to prepare test database from migrations

To use your migrations for preparing test database create a file testdb.rake
in the directory lib/tasks.
Now add the following code in the lib/tasks/testdb.rake file…

module Rake
  module TaskManager
    def redefine_task(task_class, args, &block)
      task_name, deps = resolve_args(args)
      task_name = task_class.scope_name(@scope, task_name)
      deps = [deps] unless deps.respond_to?(:to_ary)
      deps = deps.collect {|d| d.to_s }
      task = @tasks[task_name.to_s] = task_class.new(task_name, self)
      task.application = self
      task.add_comment(@last_comment)
      @last_comment = nil
      task.enhance(deps, &block)
      task
    end
  end
  class Task
    class << self
      def redefine_task(args, &block)
        Rake.application.redefine_task(self, args, &block)
      end
    end
  end
end

def redefine_task(args, &block)
  Rake::Task.redefine_task(args, &block)
end

namespace :db do
  namespace :test do

    desc 'Prepare the test database and migrate schema'
    redefine_task :prepare => :environment do
      Rake::Task['db:test:migrate_schema'].invoke
    end

    desc 'Use the migrations to create the test database'
    task :migrate_schema => 'db:test:purge' do
      ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
      ActiveRecord::Migrator.migrate("db/migrate/")
    end

  end
end

To prepare the test database from migrations run this command
$ rake db:test:migrate_schema

3 comments October 17, 2006

How to improve the image quality and generate random string image in the plugin validates_captcha

Hello Everyone !!
I have released a captcha plugin Simple Captcha. It is really simple to implement, and provides a cool feature of multiple styles of images.


Previous post about improving validates_captcha’s images


Validates captcha is a good plugin to implement captcha in your rails application.
However i found that there is repetition of the string of the image and the quality of image is not that good. To get a good quality image and random string
something like this

replace the code of the file /vendor/plugins/validates_captcha/lib/captcha_challenge.rb with the following code…


require 'digest/sha1'

module AngryMidgetPluginsInc #:nodoc:

	# CaptchaChallenge
	class CaptchaChallenge

		include CaptchaConfig
		extend CaptchaConfig

		DEFAULT_TTL = 1200#Lifetime in seconds. Default is 20 minutes.

		attr_reader :id, :created_at
		attr_accessor :ttl

		def initialize(options = {}) #:nodoc:
			generate_id

			options = {
				:ttl => config['default_ttl'] || DEFAULT_TTL
			}.update(options)

			self.ttl = options[:ttl]
			@created_at = Time.now

			self.class.prune
		end

		# Implement in subclasses.
		def correct? #:nodoc:
			raise NotImplementedError
		end

	private

		def generate_id #:nodoc:
			self.id = Digest::SHA1.hexdigest(Time.now.to_s+rand.to_s)
		end

		def id=(i) #:nodoc:
			@id = i
		end

		def write_to_store #:nodoc:
			store.transaction{
				store[:captchas] = Array.new unless store.root?(:captchas)
				store[:captchas] << self
			}
		end

	class << self

		# Removes old instances from PStore
		def prune
			store.transaction{
				if store.root?(:captchas)
					store[:captchas].each_with_index{|c,i|
						if Time.now > c.created_at+c.ttl
							store[:captchas].delete_at(i)
						end
					}
				end
			}
		end#prune
	end#class << self

	end

	# A CAPTCHA challenge where an image with text is
	# generated. A human can read the text with relative
	# ease, while most robots can not. There are accessibility
	# problems with this challenge, though, as people
	# with reduced or no vision are unlikely to pass the test.
	class CaptchaImageChallenge < CaptchaChallenge

		WORDS = 'gorilla costume, superman, banana bender, chuck norris, xray vision, ahoy me hearties,
				 chunky bacon, latex, rupert murdoch, clap your hands, year 2000,
				 sugar coated, coca cola, rastafarian, airbus a380'.split(/,s+/)
		DEFAULT_DIR = 'captcha'#public/images/captcha
		WRITE_DIR = File.join(RAILS_ROOT, 'public', 'images')
		DEFAULT_FILETYPE = 'jpg'

		attr_reader :image
		attr_accessor :string, :dir, :filename, :filetype

		# Creates an image challenge.
	  def initialize(options = {})
			super

			options = {
				:string => config['words'] ? config['words'][rand(config['words'].size)] : WORDS[rand(WORDS.size)],
				:dir => config['default_dir'] || DEFAULT_DIR,
				:filetype => config['default_filetype'] || DEFAULT_FILETYPE
			}.update(options)

            self.string = Digest::SHA1.hexdigest(Time.now.to_s)[0..4].upcase #options[:string]
            self.dir = options[:dir]
            self.filetype = options[:filetype]
            self.filename = options[:filename] || generate_filename
            write_to_store
          end

		# Generates the image.
		def generate(options = {})
			options = {
				:fontsize => 50,
				:padding => 20,
				:color => '#000',
				:background => '#fff',
				:fontweight => 'bolw',
				:rotate => true
			}.update(options)

			options[:fontweight] = case options[:fontweight]
				when 'bold' then 700
				else 400
			end

			#added
			text = Array.new
			0.upto(4) do |i|
				text[i] = Magick::Draw.new
				text[i].pointsize = options[:fontsize]
				text[i].font_weight = 600 #options[:fontweight]
				text[i].fill = 'black' #options[:color]
				text[i].gravity = Magick::CenterGravity
				text[i].rotation = (rand(2)==1 ? rand(30) : -rand(30)) if options[:rotate]
			end

                  metric = text[2].get_type_metrics(self.string)
                  #add bg
		  canvas = Magick::ImageList.new
		  fill = Magick::HatchFill.new('white','black')
		  x = metric.width+options[:padding]
		  y = metric.height+options[:padding]

		  #ADDING NOISE

		  img1 = Magick::Image.new(x,y,fill)
		  gc = Magick::Draw.new
		  gc.stroke_linejoin('round')
		  gc.stroke('black')
		  gc.stroke_width(1)
                  100.times do |i|
                    x1 = rand(x)
                    y1 = rand(y)
                    gc.circle(x1,y1,x1.next,y1)
                  end
                  gc.draw(img1)
                  canvas << img1
                  0.upto(4) do |i|
				canvas << Magick::Image.new(metric.width+options[:padding], metric.height+options[:padding]){
					self.background_color = '#000F'
					y_loc = rand(y)
				}.annotate(text[i], 0, 0, (i-2)*30, rand(y/4), self.string[i,1]) #.wave(5, 20)
		  end

		  canvas << Magick::Image.new(metric.width+options[:padding], metric.height+options[:padding]){
		    #changed
		    p = Magick::Pixel.from_color(options[:background])
		    p.opacity = Magick::MaxRGB
		    self.background_color = p
		  }  #.add_noise(Magick::LaplacianNoise)

			self.image = canvas.flatten_images.blur_image(1)
		end

		# Writes image to file.
		def write(dir = self.dir, filename = self.filename)
			self.image.write(File.join(WRITE_DIR, dir, filename))
		end

		# Determine if the supplied +string+ matches
		# that used when generating the image.
		def correct?(string)
			string.downcase == self.string.downcase
		end

		# The full path to the image file, relative
		# to <tt>public/images</tt>.
		def file_path
			File.join(dir,filename)
		end

	class << self

		# Deletes old image files. Also calls CaptchaChallenge.prune
		def prune
			store.transaction{
				if store.root?(:captchas)
					store[:captchas].each_with_index{|c,i|
						if Time.now > c.created_at+c.ttl
							if File.exists?(File.join(WRITE_DIR, c.file_path))
								begin
									File.unlink(File.join(WRITE_DIR, c.file_path))
								rescue Exception
								end
							end
						end
					}
				end
			}
			super
		end#prune
	end#class << self

	private

		def generate_filename #:nodoc:
			self.id+'.'+self.filetype
		end

		def image=(i) #:nodoc:
			@image = i
		end

	end

end

visit Here to view the customized use of the plugin validates_captcha in RoR.

22 comments October 17, 2006

Rake task to remove the image and audio files created by captcha

To add a rake task to the rails application which removes all the image and audio files created by captcha, create a file named remove_captcha_files.rake in the lib/tasks directory.
Add the following code to the lib/tasks/remove_captcha_files.rake file…

desc "Remove captcha images and audio files"
task :remove_captcha_files do
  image_path = "#{RAILS_ROOT}/public/images/captcha/"
  audio_path = "#{RAILS_ROOT}/public/captcha_audio/"
  Dir.foreach(image_path){|file| File.delete(image_path+file) if (/^.*.jpg$/).match(file)} if File.exist?(image_path)
  Dir.foreach(audio_path){|file| File.delete(audio_path+file) if (/^.*.wav$/).match(file)} if File.exist?(audio_path)
  puts "Captcha files removed."
end

You can confirm that task is added to your app by running
rake –task

To remove all the files created by captcha, simply run the command
rake remove_captcha_files
from the command line from your application root.
To better view the code visit here

Add comment October 16, 2006

Translate Your Rails Application.

Gettext is a great tool for translating user interfaces of applications into different languages. It has been around for a long time and is very well established for this task. Gettext helps you to open up your application for a much wider user base than you would normaly reach with only one language. Since it is used in many open source projects it has a lot of useful tools you can use to your own advantage. It would be possible to “roll your own” solution, but this would consume a large amount of time. Time you would lose for the development of your app. And this is not something you would want, right?

So in this tutorial I am going to show you how to effectively use Gettext for all your translation needs in your Ruby on Rails application.

What can Gettext do for you?

Here is a quick explanation of Gettext for those of you who haven’t worked with it, yet. Gettext is a set of tools that provide help when translating strings in your software. It gives you (straight from the gettext manual):

  • A set of conventions about how programs should be written to support message catalogs.
  • A directory and file naming organization for the message catalogs themselves.
  • A runtime library supporting the retrieval of translated messages.
  • A few stand-alone programs to massage in various ways the sets of translatable strings, or already translated strings.

The only thing you have to do to your program sources is wrap all translatable strings with a method call: gettext(text) or shorter _(text). Example:

Without gettext:

notice = 'Thank you for buying our product.'

With gettext:

notice = _('Thank you for buying our product.')

For more details check this out

GetText on Rails

Add comment September 6, 2006

Protected: AN INSTANIA OF FRUSTRA

This post is password protected. To view it please enter your password below:


Enter your password to view comments September 2, 2006

Source Code For Ajax Based Drag Drop Navigation Tree in Ruby on Rails – the tree works well with firefox and IE-6

Ajaxified Drag Drop Tree in RoR
CASE STUDY

I m providing a very generalized use case where the tree fits in a good position. Here it is…

Consider a model Item, a controller Items. Item model is using a fabulous acts_as_tree and we are going to put a seed for Item to grow it in an ajax tree ;-) … Ok no more non-code talk. So, lets start the code now…

==========================================================
I have also incorporated the code into a sample application which you can directly check out and try the tree yourself if you find it a
headache to add the following code in a number of described files.
So, here is the Sample Tree Application

or you can try to code yourself as…

Create a sample rails application say treeapp by running

rails treeapp

from the command prompt.
Now simply change your directiry into just created treeapp and make sure that you are in the directory treeapp

Now configure the database settings for this application by modifying the file /config/database.yml as …

development:
  adapter: mysql
  database: tree_dev
  username: root
  password: root
  host: localhost

Here it simply shows that you have a mysql database named tree_dev and a user root with password root can access this database. So make sure about these settings.

From the command prompt in application root(i.e. you are in the directory treeapp) run this command to generate the model Item

treeapp> ruby script/generate model item

Add the following code to the file app/models/itme.rb

class Item < ActiveRecord::Base

  acts_as_tree
  validates_presence_of :name
  attr_accessor :style

  def self.roots
    self.find(:all, :conditions=>["parent_id = ?", 0])
  end

  def level
    self.ancestors.size
  end
end

This simply shows that you should have a table named tems in your database…
so why we havnt mentioned it earlier ?
Thats the thing which will make you feel an agile web development.
Now look at the directory db/migrateand a you will find a file named as db/migrate/001_create_items.rb
Add the following code to this file 001_create_items.rb
Here we are creating our database table and also adding some initial data to work with.

class CreateItems < ActiveRecord::Migration
  def self.up
      create_table "items", :force => true do |t|
         t.column "name", :string
         t.column "created_at", :datetime
         t.column "parent_id", :integer, :default => 0, :null => false
      end
      %w(item1 item2 item3 item4 item5).each do |name|
            parent = Item.new(:name=>name)
            parent.save
            Item.create(:name=>name+".1", :parent_id=>parent.id)
            Item.create(:name=>name+".2", :parent_id=>parent.id)
            Item.create(:name=>name+".3", :parent_id=>parent.id)
       end
 end

 def self.down
   drop_table :items
 end

end

Now from the command line from the root of your application run the following command to have a table named Item in your database with some initial data.

  treeapp> rake db:migrate

Before we start handling our views and controller part just have a smart small image named as drag.gif in your public/images directory that we will use as a handle to drag the nodes. So, now you can see a small image at public/images/drag.gif, cool !.
Now from the command line from the root of your application run the following command to create a controller …

treeapp> ruby script/generate controller items show

Make sure that now you have the files app/controllers/items_controller.rb and app/views/items/show.rhtml.
Add the following code in the file app/controllers/items_controller.rb

class ItemsController < ApplicationController

  def show
    @items = Item.find(:all)
    @item = Item.find(:first)
    # select according to your choice...
    #this item will be selected node by default in the tree when it will first be loaded.
  end

  def display_clicked_item
    # this action will handle the two way syncronization...all the tree nodes(items) will be linked
    # to this action to show the detailed item on the left of the tree when the item is clicked
    # from the tree
    if request.xhr?
      @item = Item.find(params[:id]) rescue nil
      if @item
        # the code below will render all your RJS code inline and
        # u need not to have any .rjs file, isnt this interesting
        render :update do |page|
          page.hide "selected_item"
          page.replace_html "selected_item", :partial=>"items/item", :o bject=>@item
          page.visual_effect 'toggle_appear', "selected_item"
        end
      else
        return render :nothing => true
      end
    end
  end

  def sort_ajax_tree
    if request.xhr?
      if @item = Item.find(params[:id].split("_").first) rescue nil
        parent_item = Item.find(params[:parent_id])
        render :update do |page|
          @item.parent_id = parent_item.id
          @item.save
          @items=Item.find(:all)
          page.replace_html "ajaxtree", :partial=>"items/ajax_tree", :o bject=>[@item,@items]
          page.hide "selected_item"
          page.replace_html "selected_item", :partial=>"items/item", :o bject=>@item
          page.visual_effect 'toggle_appear', "selected_item"
        end
      else
        return render :nothing => true
      end
    end
  end

end

Add the following code in the file app/views/items/show.rhtml

<h2>Ajax Tree Application</h2>

<div id="ajaxtree" style="width:40%;float:left;">
 <%= render :partial=>'items/ajax_tree', :o bject=>[@item,@items] %>
</div>

<div id="selected_item">
 <%= render :partial=>'items/item', :o bject=>@item %>
</div>

Add the following code in the file app/views/items/_item.rhtml

<% if @item %>
  <h2>Selected Item is <%=h @item.name%> </h2>
<% else %>
  Item not found
<% end %>

Add the following code in the file app/views/items/_ajax_tree.rhtml

<script type="text/javascript">

function toggleDiv()
{
  Element.toggle('mytree');
  Element.toggle('expanded');
  Element.toggle('collapsed');
  return false;
}
function showDrag()
{
  var drag_images = $$('img.drag_image');
  drag_images.all(function(value,index){return value.style.display='inline';});
  Element.toggle('done');
  Element.toggle('reorder');
  return false;
}
function hideDrag()
{
  var drag_images = $$('img.drag_image');
  drag_images.all(function(value,index){return value.style.display='none';});
  Element.toggle('done');
  Element.toggle('reorder');
  return false;
}
</script>

<style>

.mytree{padding:0 0 0 0px;}

.mytree li {padding:2 0 0 3px;}

.outer_tree_element{margin:0 0 0 10px;}

.inner_tree_element{margin:5px 0 0 10px;}

.mytree a{text-decoration:none; font-size:13px; color:black;}

.mytree a:hover{background-color:lightblue;}

.mytree label{font-weight:normal;}

.highlighted{background-color:lightblue;}

.normal{background-color:white;}

.drag_image{border:0px;}

</style>

<div id="mytree" class="mytree">

  <% @ancestors = @item.ancestors.collect{|parent| parent.id} if @item.has_parent? %>
  <% @items = Item.find(:all) %>
  <%= get_tree_data(@items, 0){|n|
      link_to_remote(n.name,
      :url=>{:controller=>'items', :action=>'display_clicked_item', :id=>n.id},
  :loading=>"Element.show('tree_indicator')",
  :complete=>"Element.hide('tree_indicator')"
  )}
  %>

  <% @items.each do |node| %>
  <%= draggable_element node.id.to_s+'_tree_div',:revert=>true,:snap=>false, :handle=>"'#{node.id.to_s}_drag_image'" %>
  <%= drop_receiving_element node.id.to_s+'_tree_div',
      :accept=>'inner_tree_element',
  :url=>{:controller=>'items',:action=>'sort_ajax_tree', :parent_id=>node.id,:id=>nil},
  :loading=>"Element.show('sort_tree_indicator')",
  :complete=>"Element.hide('sort_tree_indicator')"
  %>

  <% end %>

  <%= image_tag 'indicator.gif', :id=>'tree_indicator', :style=>'display:none' %>
  <%= image_tag 'indicator.gif', :id=>'sort_tree_indicator', :style=>'display:none' %>
</div>

<script type="text/javascript">

  var selected_el = document.getElementById('<%=@item.id%>_tree_item');
  selected_el.className='highlighted';

  function toggleMyTree(id)
  {
  Element.toggle(id+'collapsed');
  Element.toggle(id+'expanded');
  Element.toggle(id+'children');
  return false;
  }
  function toggleBackground(el)
  {
  // using collection proxies to change the background
  var highlighted_el = $$("span.highlighted");
  highlighted_el.all(function(value,index){return value.className='normal'});

  el.className='highlighted';
  selected_el = el;
  return false;
  }
  function openMyTree(id)
  {
  Element.hide(id+'collapsed');
  Element.show(id+'expanded');
  Element.show(id+'children');
  return false;
  }

</script>

As you can see in the above file we have used some indicator and toggle images. So you will be required to have three more images in the directory public/images/.
Here is the small description about these images…

  • An indicator image that will be displayed at the bottom of the tree whenever a tree node is clicked. You can select from a number of Ajax Inidicatorsavailable on the web. Select one indicator image and save in your app with the name indicator.gif. So, now make sure that you can see the image at public/images/indicator.gif
  • Second, we need to have a small image with + sign. That will be used to toggle the tree. save it as public/images/collapsed.gif
  • Similarly, an image with - sign. Save it as public/images/expanded.gif

We have to include the prototype and scriptaculous javascript libraries in the application.
So just manually create a layout file app/views/layouts/application.rhtml and add the following code in the file application.rhtml

<html>
  <head>
    <%= javascript_include_tag :defaults %>
  </head>

  <body>
    <%= @content_for_layout %>
  </body>

</html>

Now the last but the most importatnt…The recursion to obtain the tree.
Add the following code in the file app/helpers/application_helper.rb

module ApplicationHelper

  def get_tree_data(tree, parent_id)
    ret = "<div class='outer_tree_element' >"
    tree.each do |node|
      if node.parent_id == parent_id
        node.style = (@ancestors and @ancestors.include?(node.id))? 'display:inline' : 'display:none'
        display_expanded = (@ancestors and @ancestors.include?(node.id))? 'inline' : 'none'
        display_collapsed = (@ancestors and @ancestors.include?(node.id))? 'none' : 'inline'
        ret += "<div class='inner_tree_element' id='#{node.id}_tree_div'>"
        if node.has_children?
          ret += "<img id='#{node.id.to_s}expanded' src='/images/expanded.gif' onclick='javascript: return toggleMyTree(\"#{node.id}\"); ' style='display:#{display_expanded}; cursor:pointer;'  />  "
          ret += "<img style='display:#{display_collapsed}; cursor:pointer;'  id='#{node.id.to_s}collapsed' src='/images/collapsed.gif' onclick='javascript: return toggleMyTree(\"#{node.id.to_s}\"); '  />  "
        end

        ret += " <img src='/images/drag.gif' style='cursor:move' id='#{node.id}_drag_image' align='absmiddle' class='drag_image' /> "

        ret += "<span id='#{node.id}_tree_item'>"
        ret += yield node
        ret += "</span>"
        ret += "<span id='#{node.id}children' style='#{node.style}' >"
        ret += get_tree_data(node.children, node.id){|n| yield n}
        ret += "</span>"
        ret += "</div>"
      end
    end
    ret += "</div>"
    return ret
  end
end

Now you can check the tree functionality at http://localhost:3000/items/show.. assuming that you are running your server on port 3000. njoy!!

28 comments August 18, 2006

Fully Ajax Based Drag Drop Navigation Tree For Ruby on Rails

Ajaxified tree comes with the following features

1.) Containing the ajax links for the tree items using link_to_remote

2.) Highlighting the selected node of the tree and other custom effects.

3.) Two way syncronization between the tree nodes and the currently displayed item on the web-page.

4.) Supports the tree architecture provided by the acts_as_tree.

5.) Clear and self traversing upto the selected node and all remaining nodes remained closed.

6.) Drag-n-Drop sorting of the tree nodes, including the functionality of even changing the parent of the node.

This tree works very fine in my application and hope it will help u also. Check out the Source Code of the tree.

3 comments August 9, 2006

Protected: Best Live In Concert Attended Ever…

This post is password protected. To view it please enter your password below:


Enter your password to view comments March 21, 2006

Next Posts


Ruby on Rails

Contact

sur.max(at)gmail.com

Seems Useful

 

November 2009
M T W T F S S
« Feb    
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Recent Posts

Power Shots

Untitled

midnight city still

PPPA: Professional Puppy Photographers of America.

Untitled

Mortuary

Palm trees at night

Three Impala drink at Kruger waterhole

Untitled

Untitled

morning windows

More Photos

Zipped

Subscribe