sur says ajax :on => rails

Monday, February 05, 2007

Blog moved to Expressica.com -- releasing the captcha plugin with multiple styles of clear images, with random string text

Hi Everbody !!

I am moving this blog to Expressica

and i would like to inform all the readers to update their feeds and bookmarks to the new url http://expressica.com .

On my new blog i am going to release a captcha plugin which is really very simple to implement. This plugin provides the functionality to add captcha based authentication in your rails applications.

It mainly features...

  • Controller based captcha

  • Model based captcha

  • and the feature i like the most is multiple image styles


You can simply pass the name of the image style from the view and captcha will throw the random strings as the selected style of image. The images are clear enough to read by human and blurred and manipulated enough to protect from bots.
Example of the images ...

  • simply_red

  • simply_green

  • simply_blue

  • embosed_silver

  • distorted_black

  • all_black

  • charcoal_grey

  • almost_invisible


Comments/Queries are welcome on this idea.

I will release this plugin very soon on Expressica.com

Thursday, October 19, 2006

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

Tuesday, October 17, 2006

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

Validates captcha is a good pluging 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 replace the code of the file /vendor/plugns/validates_captcha/lib/captcha_challenge.rb with the following code...

Visit Here for the latest modified source code.

Monday, October 16, 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


To remove all the files created by captcha, simply run the command

from the command line from your application root.

Thursday, September 14, 2006

RAILS_CONF.include?('VINSOL')


Marcel Molina, Manik Juneja and DHH
DHH and Marcel were surprised to know that there were Rails programmers in India.

RailsConf2006

VINSOL IS RAILING ....

RailsConf2006 marked the presence of Rails based Indian company Vinsol.
Vinsol's chief Manik Juneja is attending the conference. The 1st day of conference was shining with good sessions by DHH, Marcel, Jamis Buck, Thomas Fuchs and David Black.


There was a very interesting discussion between DHH, Marcel and Jamis Buck about what should go into functional testing and what should go into integration testing.
DHH believes testing for permission should go into integration.

Wednesday, September 06, 2006

How to prepare test database environment from migrations.

Usually we build our test database by using


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





Now from command prompt run this command to view all the rake tasks


You will c a task as rake db:test:migrate_schema
To prepare the test database run this command

Thursday, August 17, 2006

Source Code For Ajax Based Drag Drop Navigation Tree For Rails.

Hello Everyone!
for some CSS issues i was not able to publish the source code properly on my wordpress's blog so i am publishing all the code here only. Check this out...

CASE STUDY

I m providing a very generalized use case where the tree fits in a good position. Here it is...
Consider a model MyItem, a controller MyController and a myaction.rhtml as a view. MyItem model is using acts_as_tree and we are going to put a seed for MyItem to grow it in an ajax tree ;-) ... So, lets start the code now...

==========================================

From the command prompt run this command to generate the migration file to create the table in database



and a file name db/migrate/00x_create_my_item.rb will be created where 00x represents the version of your schema info incremented by 1.

Add the following code to this file 00X_create_my_item.rb


class CreateMyItem < force =""> true do |t|
t.column "name", :string
t.column "created_at", :datetime
t.column "parent_id", :integer, :default => 0, :null => false
end
end
def self.down
drop_table :my_items
end
end



As we are finished with the migration file, run this migration to create the
table in databse by this command.


Now create the model for this table by executing the follwing command


and this will create a file app/models/my_item.rb file will be created.

Add the following code to this file my_item.rb


class MyItem < order =""> "created_by"
HIERARCHY_LEVEL = 3
validates_presence_of :name
attr_accessor :style

def self.roots
self.find_all_by_parent_id(0)
end

def level
self.ancestors.size
end
end



Add the following code to the view file app/views/my_controller/myaction.rhtml



<% @myitem = @myitems[0] %>
<!-- here @myitems[0] reflects the first node item that will be selected by default -->
<div id="navtree">
<%= render :partial=>'my_controller/mytree', :object=>[@myitem,@myitems] %>
</div>

<div id="selected_item">
<%= render :partial=>'my_controller/myitem', :object=>@myitem %>
</div>



Add the following code to app/controllers/my_controller.rb




def myaction
@myitems = MyItem.find(:all)
end

def show_selected_item
if request.xhr?
@myitem = MyItem.find(params[:id])
if @myitem
# 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=>"my_controller/myitem", :object=>@myitem
page.visual_effect 'toggle_appear', "selected_item"
end
end
end
end

def sort_my_tree
if request.xhr?
if @myitem = MyItem.find(param[:id].split("_")[0])
parent_myitem = MyItem.find(params[:parent_id])
render :update do |page|
@myitem.parent_id = parent_myitem.id
@myitem.save
@myitems=MyItem.find(:all)
@sort = 'inline'
page.replace_html "navtree", :partial=>"my_controller/mytree", :object=>[@myitem,@myitems,@sort]
end
end
end
end



Add the following code in the file app/views/my_controller/_myitem.rhtml



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



I have include all the style and the javascript methods here in this file only.
You can make CSS and JS files accordingly. JS also includes collection proxies (fundo it is ).
Add the following code in the file app/views/my_controller/_mytree.rhtml



<% @sort ||= 'none' %>
<% reorder_style = (@sort=='none')? 'inline' : 'none' %>
<% done_style = (@sort=='none')? 'none' : 'inline' %>

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

<p>
<a href="#" id="reorder" style="display:<%=reorder_style%>" onclick="javascript: return showDrag();">Reorder</a>
<a href="#" id="done" style="display:<%=done_style%>" onclick="javascript: return hideDrag();">Done Reordering</a>
<br/><br/>
</p>

<a id="drop_at_collection" href="/collection" onclick="javascript: return toggleDiv(); ">
<img src="/images/expanded.gif" id='expanded' />
<img src="/images/collapsed.gif" style="display:none" id='collapsed'/>
<b><%= "Displayed Root" %></b>
</a>
<%= drop_receiving_element("drop_at_collection",:accept=>'inner_tree_element',
:url=>{:controller=>'my_controller',:action=>'sort_my_tree',:id=>nil},
:loading=>"Element.show('sort_tree_indicator')",
:complete=>"Element.hide('sort_tree_indicator');"
)%>

<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:2px 0 0 8px;
}

.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
{
/* this class is mandatory for the collection proxies...
u can avoid this class if u need ur tree not to work well :-) */
border:1px;
}
</style>

<div id="mytree" class="mytree">
<% @ancestors = @myitem.ancestors.collect{|parent| parent.id} unless !@myitem.has_parent? %>
<% @myitems = MyItem.find(:all) %>
<%= get_tree_data(@myitems,0){|n|
link_to_remote n.name,
:url=>{:controller=>'my_controller',:action=>'show_selected_item',:id=>n.id}
:loading=>"Element.show('tree_indicator')",
:complete=>"Element.hide('tree_indicator')",
}
<% @myitems.each do |node| %>
<% if node.has_parent? %>
<%= draggable_element node.id.to_s+'_tree_div',:revert=>true, :snap=>false, :handle=>"'#{node.id.to_s}_drag_image'" %>
<% end %>
<% if node.level < MyItem::HIERARCHY_LEVEL %>
<%= drop_receiving_element(node.id.to_s+'_tree_div',:accept=>'inner_tree_element',
:url=>{:controller=>'collection',:action=>'sort_my_tree',:parent_id=>node.id,:id=>nil},
:loading=>"Element.show('sort_tree_indicator')",
:complete=>"Element.hide('sort_tree_indicator');"
)%>
<% end %>
<% end %>

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

</div>


<script type="text/javascript">

var selected_el = document.getElementById('<%=@myitem.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>




Add the following code in app/helper/application_helper.rb



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='display:#{@sort}; 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(tree, node.id){|n| yield n}
ret += "</span>"
ret += "</div>"
end
end
ret += "</div>"
return ret
end


Wednesday, August 09, 2006

Fully Ajax Based Drag Drop Navigation Tree For Ruby on Rails

Ajaxified tree comes with the following features

1.) Containig 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 ny the acts_as_tree.

5.) C lear 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 this tree.

Friday, June 23, 2006

A GOOD SEARCH TECHNIQUE

A fine way to search from more than one column from the DB.
Even, all the join conditions can easily be provided...
Check this out ...

TextSearch

Friday, June 02, 2006

DO NOT GO FOR RJS TEMPLATES


RJS is undoubtly a good method of ajaxification of your web application.
But why to have another myaction.rjs file if its functionality could be merged
within the action itself.
Is it possible ?

Oh !!! its like applying butter on bread.......... check this out




class MyController < ApplicationController
def myaction
render :update do ¦ page ¦
page.replace_html 'update_this_element_id', :partial=>update_from_controller/update_partial_file'
# and all your effects of scrip.aculo.us as we do put in your myaction.rjs
end
end
end


Well, atleast you can avoid myaction.rjs files for just some render partials or a few special effects or when you can afford to not to separate your rjs code.


Well, RJS beautifully continues the MVC behaviour but,
in some cases it might be better to to go for the above one.


So dont feel hazi, you can try it for a while.



Monday, April 17, 2006

Net-SSH and Net-SFTP


Hello readers!
This post is all about the power of Ruby.
After the day full of work I need to take the backup of my work there on remote as well as on my local machine.
Ruby Scripting helps the way out in a beautiful manner. There are two modules Net::SSH and Net::SFTP available at RUBY FORGE which can add a lots of more geek functionalities to your daily routine. One of them has relaxed me a lot.
Here I am going to explain a small n great use of Net::SSH and Net::SFTP.
-----------------------Pre-Requisites------------------------
To use this functionality from your local machine u will have to install ruby on your local machine.
After that install these two modules simply using Ruby GEM as follows...

1.)
2.)

after installation write the following code and save it as a ruby file say "backup.rb"
here is the code for "backup.rb"



#----------------BACKUP YOUR DATA ON LOCAL MACHINE--------------#
require 'net/ssh'
require 'net/sftp'
#----------------CONNECTION PARAMETERS--------------------------#
#... If u wanna use the default connection parameters then set the $default variable to "y" and
#... set the default values for $host,$username,$password variables in following elsif block.
#... Or Set $default to "n" to provide the connection parameters dynamically.
$default = "n"
if $default == "n"
print " Host : "
$host = gets().chop
print "Username : "
$username = gets().chop
print "Password : "
$password = gets().chop
elsif $default == "y"
$host = "localhost"
$username = "user"
$password = "pass"
end
#----------------TO BE MODIFIED AS PER NEED-----------------------#
$file_path = "exe/"
$file_exist = "temp1"
$download_path = "c:/test_backup/"
#-----------------------------------------------------------------#
time_now = Time.now()
$file_new = $file_exist + "_" + time_now.strftime("%a_%b_%d_%Y_%H_%M_%S") + ".tar.gz"
#------------------------NET::SSH----------------------------------#
Net::SSH.start($host, $username, $password) do ¦session¦
shell = session.shell.open
puts "SHELL IS RUNNING..."
shell.tar "-czf " + $file_path + $file_new + " " + $file_path + $file_exist
puts $file_new + " is successfully created "
shell.exit
sleep 0.5
$stdout.print shell.stdout while shell.stdout?
session.loop
end
#------------------------NET::SFTP----------------------------------#
Net::SFTP.start($host, $username, $password) do ¦sftp¦
sftp.get_file $file_path + $file_new, $download_path + $file_new
end
#------feel free to send comments/queries at sur.max@gmail.com------#


now through command prompt run the file "backup.rb"
and enjoy the simple and trendy way to backup your work.

Thursday, April 06, 2006

Why switch to yet another technology ??

Rails is a full-stack framework for developing database-backed web applications according to the Model-View-Control pattern. From the Ajax in the view, to the request and response in the controller, to the domain model wrapping the database, Rails gives you a pure-Ruby development environment. To go live, all you need to add is a database and a web server.

Everyone from startups to non-profits to enterprise organizations are using Rails. Rails is all about infrastructure so it's a great fit for practically any type of web application Be it software for collaboration, community, e-commerce, content management, statistics, management.

I will try to provide the best of my experiences from the always relishing rails.