<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1611524385965097078</id><updated>2011-12-31T01:21:50.744-08:00</updated><category term='Authorize.net'/><title type='text'>Ruby and Ruby on Rails</title><subtitle type='html'>Ramesh S - Software Engineer @
Citrisys solutions
Chennai, India</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-3281621490110578049</id><published>2008-01-03T05:07:00.000-08:00</published><updated>2009-04-27T23:18:22.104-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Authorize.net'/><title type='text'>Rails Application Using Active Merchant</title><content type='html'>Hi All&lt;br /&gt; I think i write this post after a long time. Sorry pals, i was in ATG project. Hmm... Ok Lets start now to create an application using &lt;a href="http://www.activemerchant.org/"&gt;Active Merchant&lt;/a&gt;. What is Active Merchant. Its an &lt;span class="highlight"&gt;extraction from the e-commerce system &lt;a href="http://shopify.com/"&gt;Shopify&lt;/a&gt;&lt;/span&gt;. Shopify's requirements for a simple and unified API to access dozens of different payment gateways with very different internal APIs was the chief principle in designing the library. Now we are going to know how to create an application using active merchant API with &lt;a href="http://en.wikipedia.org/wiki/Payment_gateway"&gt;payment gateway&lt;/a&gt; authorize.net. The &lt;a href="http://www.authorize.net/"&gt;Authorize.net&lt;/a&gt; is a very famous and effective gateway that i know. Ok, Come on lets start&lt;br /&gt;&lt;br /&gt;Create a rails application named as creditcard&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ rails creditcard&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Before enter into next step make sure the plugin active merchant is installed in your application's vendor/plugins directory. Then install the gem money too.Next,Create a model creditcard&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby script/generate model creditcard&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and place the following code in the migration file&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;create_table :creditcards do |t|&lt;br /&gt; t.column :first_name, :string&lt;br /&gt; t.column :last_name, :string&lt;br /&gt; t.column :card_type, :string&lt;br /&gt; t.column :card_number, :string&lt;br /&gt; t.column :expiration_month, :integer&lt;br /&gt; t.column :expiration_year, :integer&lt;br /&gt; t.column :created_at, :date&lt;br /&gt; t.column :updated_at, :date&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 0);"&gt;Create a controller called home by&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ruby script/generate controller home index check_balance result&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 0);"&gt;Copy and paste the following code in your home controller&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def index&lt;br /&gt;return unless request.post?&lt;br /&gt;@creditcard = Creditcard.new(params[:creditcard])&lt;br /&gt;creditcard = ActiveMerchant::Billing::CreditCard.new(&lt;br /&gt;:type =&amp;gt; params[:creditcard][:card_type],&lt;br /&gt;:number =&amp;gt; params[:creditcard][:card_number],&lt;br /&gt;:month =&amp;gt; params[:creditcard][:expiration_month],&lt;br /&gt;:year =&amp;gt; params[:creditcard][:expiration_year],&lt;br /&gt;:first_name =&amp;gt; params[:creditcard][:first_name],&lt;br /&gt;:last_name =&amp;gt; params[:creditcard][:last_name]&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;if creditcard.valid?&lt;br /&gt;    if @creditcard.save&lt;br /&gt;       flash[:message] ="Creditcard Info saved!"&lt;br /&gt;       redirect_to :action =&amp;gt; 'check_balance', :id=&amp;gt; @creditcard&lt;br /&gt;    else&lt;br /&gt;       flash[:message] = "Error in server. Try again later!"&lt;br /&gt;       redirect_to :action =&amp;gt; 'index'&lt;br /&gt;    end&lt;br /&gt;else&lt;br /&gt;   flash[:message] = "Error in credit card info!"&lt;br /&gt;   redirect_to :action =&amp;gt; index&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def check_balance&lt;br /&gt;return unless request.post?&lt;br /&gt;  @creditcard = Creditcard.find(params[:id])&lt;br /&gt;  gateway = ActiveMerchant::Billing::AuthorizeNetGateway.new(:test =&amp;gt; true, :login =&amp;gt; "your authorize.net login id", :password=&amp;gt; "your authorize.net password")&lt;br /&gt;amount_to_charge = Money.ca_dollar(params[:user][:balance].to_i) #1000 = ten US dollars&lt;br /&gt;creditcard = ActiveMerchant::Billing::CreditCard.new(&lt;br /&gt;:type =&amp;gt; @creditcard.card_type,&lt;br /&gt;:number =&amp;gt; @creditcard.card_number,&lt;br /&gt;:month =&amp;gt; @creditcard.expiration_month,&lt;br /&gt;:year =&amp;gt; @creditcard.expiration_year,&lt;br /&gt;:first_name =&amp;gt; @creditcard.first_name,&lt;br /&gt;:last_name =&amp;gt; @creditcard.last_name&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;response = gateway.authorize(amount_to_charge,creditcard)&lt;br /&gt;if response.success?&lt;br /&gt;   flash[:message] ="You have enough balance to shop!"&lt;br /&gt;   redirect_to :action =&amp;gt; 'result'&lt;br /&gt;else&lt;br /&gt;   flash[:message] = "Please check your Balance!"&lt;br /&gt;   redirect_to :action =&amp;gt; 'check_balance'&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Your view file index.rhtml should be&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;% if flash[:message] %&amp;gt;&lt;br /&gt;&amp;lt;%=flash[:message]%&amp;gt;&lt;br /&gt;&amp;lt;%end%&amp;gt;&lt;br /&gt;&amp;lt;%form_tag({:action =&amp;gt; 'index'}, :name =&amp;gt; 'frmnew')do%&amp;gt;&lt;br /&gt;&lt;br /&gt;Card Holder First Name&lt;br /&gt;( As shown in creditcard)&lt;br /&gt;&amp;lt;%= text_field 'creditcard', 'first_name', :size =&amp;gt; '40' %&amp;gt;&lt;br /&gt;Card Holder Last Name&lt;br /&gt;( As shown in creditcard)&lt;br /&gt;&amp;lt;%= text_field 'creditcard', 'last_name', :size =&amp;gt; '40' %&amp;gt;&lt;br /&gt;Card Type&lt;br /&gt;&amp;lt;%=cards("creditcard[card_type]", "creditcard_card_type")%&amp;gt;&lt;br /&gt;Card Number&lt;br /&gt;&amp;lt;%= text_field 'creditcard', 'card_number', 'value' =&amp;gt; "", :size =&amp;gt; '40' %&amp;gt;&lt;br /&gt;&lt;br /&gt;Expiry Month &amp;lt;%=expiry_month%&amp;gt;&lt;br /&gt;Expiry Year &amp;lt;%=expiry_year%&amp;gt;&lt;br /&gt;&amp;lt;%= submit_tag "SignUp" %&amp;gt;&lt;br /&gt;&amp;lt;%end%&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(51, 0, 0);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then , copy and paste the following code into your check_balance.rhtml&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;% if flash[:message] %&amp;gt;&lt;br /&gt;&amp;lt;%=flash[:message]%&amp;gt;&lt;br /&gt;&amp;lt;%end%&amp;gt;&lt;br /&gt;&amp;lt;%form_tag({:action =&amp;gt; 'check_balance'})do%&amp;gt;&lt;br /&gt;&lt;br /&gt;Enter Your Balance in account:&lt;br /&gt;&amp;lt;%= text_field 'user', 'balance', :size =&amp;gt; '40' %&amp;gt;&lt;br /&gt;&amp;lt;%= submit_tag "Check Availability" %&amp;gt;&lt;br /&gt;&amp;lt;%end%&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(51, 0, 0);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Finally, Your result.rhtml should like&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;% if flash[:message] %&amp;gt;&lt;br /&gt;&amp;lt;%=flash[:message]%&amp;gt;&lt;br /&gt;&amp;lt;%end%&amp;gt;&lt;br /&gt;Creditcard Validated!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(51, 0, 0);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally you have to add some code in your application helper as like below. Its for the expiry_month and expiry_date date.Add the following code to your application_helper.rb&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def expiry_month&lt;br /&gt;  b = "&amp;lt;select name='creditcard[expiration_month]'&amp;gt;"&lt;br /&gt;  b+= "&amp;lt;option value='MM'&amp;gt;MM&amp;lt;/option&amp;gt;"&lt;br /&gt;  01.upto 12 do |x|&lt;br /&gt;    b+= "&amp;lt;option value='0#{x}'&amp;gt;0#{x}&amp;lt;/option" if x.to_s.length == 1&lt;br /&gt;    b+= "&amp;lt;option value='#{x}'&amp;gt;#{x}&amp;lt;/option" if x.to_s.length !=1&lt;br /&gt;  end&lt;br /&gt;    b+= "&amp;lt;/select&amp;gt;"&lt;br /&gt;    b&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def expiry_year&lt;br /&gt;   a= "&amp;lt;select name='creditcard[expiration_year]'&amp;gt;"&lt;br /&gt;   a+= "&amp;lt;option value='YYYY'&amp;gt;YYYY&amp;lt;/option&amp;gt;"&lt;br /&gt;&lt;br /&gt;   2009.upto 2020 do |x|&lt;br /&gt;      a+= "&amp;lt;option value='#{x}'&amp;gt;#{x}&amp;lt;/option&amp;gt;"&lt;br /&gt;   end&lt;br /&gt;   a += "&amp;lt;/select&amp;gt;"&lt;br /&gt;   a&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def cards(name, id)&lt;br /&gt;  str = "&amp;lt;select name='#{name}' id='#id}' style='width:265px'&amp;gt;"&lt;br /&gt;  str += "&amp;lt;option value='select'&amp;gt;select&amp;lt;/option&amp;gt;"&lt;br /&gt;  str += "&amp;lt;option value='visa'&amp;gt;Visa&amp;lt;/option&amp;gt;"&lt;br /&gt;  str += "&amp;lt;option value='master card'&amp;gt;Master Card&amp;lt;/option&amp;gt;"&lt;br /&gt;  str += "&amp;lt;/select&amp;gt;"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now configure your application Database and create table using&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ rake db:migrate&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you run the application. Check with my code and comment me please if any error occurs.&lt;br /&gt;Your can capture the response also by&lt;br /&gt;&lt;pre&gt;gateway.capture(1000, response.authorization)&lt;/pre&gt;&lt;br /&gt;You can get login and password in the check_balance action by registering with&lt;br /&gt;&lt;a href="http://www.authorize.net/"&gt;http://www.authorize.net&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-3281621490110578049?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/3281621490110578049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2008/01/rails-application-using-active-merchant.html#comment-form' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/3281621490110578049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/3281621490110578049'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2008/01/rails-application-using-active-merchant.html' title='Rails Application Using Active Merchant'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-5000875357065629667</id><published>2007-11-25T22:24:00.000-08:00</published><updated>2009-04-27T23:22:57.111-07:00</updated><title type='text'>Radiant CMS - Ruby on Rails</title><content type='html'>&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Radiant CMS&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Its a powerful open source &lt;a href="http://en.wikipedia.org/wiki/Content_management_system"&gt;CMS (Content Management System) &lt;/a&gt;developed in ruby on rails. &lt;/span&gt;&lt;/span&gt;&lt;span style=""&gt;&lt;a href="http://radiantcms.org/"&gt;&lt;b&gt;Radiant&lt;/b&gt; 0.6.4&lt;/a&gt; has just been released! This version includes a powerful extension system so developers can tailor &lt;b&gt;Radiant&lt;/b&gt; to their specific needs. Here i gave you some instructions to deploy it on your localhost.&lt;br /&gt;&lt;br /&gt;First install the gem by&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;% gem install --include-dependencies radiant&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;Then create a radiant project of your own by &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;pre&gt;% radiant --database [mysql|postresql|sqlite3] path/to/project&lt;br /&gt;&lt;br /&gt;for eg: &lt;/code&gt;&lt;br /&gt;&lt;code&gt;% radiant --database mysql my_radiant_application&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;Then you have to configure your database by edit your database.yml file like follows&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;development:&lt;br /&gt;adapter: mysql&lt;br /&gt;database: my_radiant_development&lt;br /&gt;username: root&lt;br /&gt;password: admin&lt;br /&gt;host: localhost&lt;br /&gt;&lt;br /&gt;# Warning: The database defined as 'test' will be erased and&lt;br /&gt;# re-generated from your development database when you run 'rake'.&lt;br /&gt;# Do not set this db to the same as development or production.&lt;br /&gt;test:&lt;br /&gt;adapter: mysql&lt;br /&gt;database: my_radiant_test&lt;br /&gt;username: root&lt;br /&gt;password:&lt;br /&gt;host: localhost&lt;br /&gt;&lt;br /&gt;production:&lt;br /&gt;adapter: mysql&lt;br /&gt;database: my_radiant_production&lt;br /&gt;username: root&lt;br /&gt;password: admin&lt;br /&gt;host: localhost&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;you can use any of the database modes listed in database.yml. Then based on your database configuration &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;database schema should created by &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;% rake [environment] db:bootstrap&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;for eg: % rake production db:bootstrap if u r in production environment&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;Here u goes, start your server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;% mongrel_rails start -e &lt;/pre&gt;, where mongrel is your server (&lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel server&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;Type the &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://localhost:3000/admin"&gt;http://localhost:3000/admin&lt;/a&gt;&lt;span style="font-weight: normal;"&gt; to login. The user name is password should be known to you because &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;while creating schema it asks for u the admin user name and password.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;In the application you can't see any model, controller or view files but its working &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;fine this is how possible is all those files are written along with the radiant gem that &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;u should installed before starting project. you can see those files in your local ruby gems folder.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;Thats all , now you can go ahead with some other own radiant application.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;if you want more explanation go and visit &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://localhost:3000/admin"&gt;Radiant home page&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;code style="font-weight: normal;"&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-5000875357065629667?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/5000875357065629667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/11/radiant-cms-ruby-on-rails.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5000875357065629667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5000875357065629667'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/11/radiant-cms-ruby-on-rails.html' title='Radiant CMS - Ruby on Rails'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-6461578553172698603</id><published>2007-10-22T02:04:00.000-07:00</published><updated>2009-04-27T23:52:02.366-07:00</updated><title type='text'>Validations in Rails</title><content type='html'>Hi, let's gonna see something for validation in ROR. The validations are vital to convey the user to enter the correct inputs. Most of the developers were not concentrates on validations.&lt;br /&gt;&lt;br /&gt;The one thing you should keep remember that all the user's of your site or any product you developed might not have complete knowledge about your site or product. so you have the responsibility to guide them inn a right channel.&lt;br /&gt;&lt;br /&gt;Okay , Lets come into rails. Rails supports  most of the validations in simple way. ie. most of the validations can be done in a single line. Some of the validations are shown below,&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Validation for empty field :&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;validates_presence_of :name&lt;br /&gt;validates_presence_of :age&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The rails by default show u the error message as "can't be blank" and if u want to override that u can do like&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;validates_presence_of :name , :message =&gt; "This field should not be empty! "&lt;br /&gt;validates_presence_of :age , :message =&gt; "Age can not be null! "&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Validation for uniqueness :&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;validates_uniqueness_of :employee_id&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;validation to check the field is a number :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;validates_numericality_of :age, :message =&gt; "Age cant be string/special character"&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;validation of email :&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;validates_format_of :email,&lt;br /&gt;                    :with =&gt;  /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i,&lt;br /&gt;                    :message =&gt; "Its not a valid format"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It will check the email is in format of something@something.com (or) something@something.co.uk as example. This validation might be very useful to you because every application has special validations for different fields. Consider if your requirement says that name field should not contain numbers and special characters then write validation like&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;validates_format_of :name,&lt;br /&gt;                    :with =&gt; /^[A-Za-z.]*\z/,&lt;br /&gt;                    :message =&gt; "Cannot contain Numbers,White Space"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Its accepts the string with characters A-Z and a-z. The syntax for the validation is somewhat complex but u do understand if u notice carefully.The following is the validation of zip code according to unites states of america. Its allows either 5 digit numbers or 5 plus 4 digit area code.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;validates_format_of :zip_code,&lt;br /&gt;                    :with =&gt; %r{\d{5}(-\d{4})?},&lt;br /&gt;                    :message =&gt; "should be 12345 or 12345-1234"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Special validations:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;validates_format_of  :name ,&lt;br /&gt;                     :with =&gt; /^[A-Za-z.]*\z/,&lt;br /&gt;                     :message =&gt; "Cannot contain Numbers,White Space"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;validates_format_of  :name ,&lt;br /&gt;                     :with =&gt;  /^[A-Z a-z 0-9]*\z/ ,&lt;br /&gt;                     :message =&gt; "Invalid"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;/span&gt;which allows space and numbers for the field name&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Other than the formal validations there is a method called add which u can overide the validations errors.I think u know the before_save method which is in the model and its called every time the record creates. for eg.,&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;before_save :check&lt;br /&gt;  def check&lt;br /&gt;      errors.add(:date_of_birth, "You are gladly welcome") if date_of_birth == 18&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;By this you can validate your own condition by adding an error message by using add function.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;To know more about the validations ? &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://ar.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html"&gt;Yes, I'm ready to do&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-6461578553172698603?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/6461578553172698603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/10/validations-in-rails.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/6461578553172698603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/6461578553172698603'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/10/validations-in-rails.html' title='Validations in Rails'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-5954722321393867288</id><published>2007-09-10T23:10:00.000-07:00</published><updated>2007-09-13T02:41:13.337-07:00</updated><title type='text'>File upload using plugin - attachment_fu</title><content type='html'>Listed : &lt;a href="http://www.dmegs.com/"&gt;Web Directory Top Sites Free&lt;/a&gt;&lt;br /&gt;&lt;script src="http://www.google-analytics.com/urchin.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;_uacct = "UA-2597032-1";&lt;br /&gt;urchinTracker();&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;p&gt; A picture might be worth a thousand words, but how many lines of code does it take to upload one to your Rails application? Sounds like a fun feature to tackle on a Friday. Let's upload some mug shots. You know, to identify the goofballs around the office. &lt;/p&gt;  &lt;h5&gt;1. Install an Image Processor&lt;/h5&gt;  &lt;p&gt;We'll need to resize the mugshots during the upload process, and we'll also want to generate thumbnails of the mugshots to use around the site. &lt;/p&gt; &lt;p&gt; Image processing of this kind is best handled by native code. This means you end up either building a library for your operating system or downloading a pre-built library specific to your operating system. Then you install a Ruby library (gem) that wraps the image processing library with a Ruby API. Either way, it's the least fun step of the entire process, so let's get it out of the way early. &lt;/p&gt; &lt;p&gt; Choose from one of the following libraries:  &lt;/p&gt; &lt;ul&gt;&lt;li&gt;   &lt;p&gt;     &lt;a href="http://seattlerb.rubyforge.org/ImageScience.html"&gt;ImageScience&lt;/a&gt;:      A light inline-Ruby library that &lt;em&gt;only&lt;/em&gt; resizes images.       (Wraps the FreeImage library.)   &lt;/p&gt;   &lt;/li&gt;&lt;li&gt;     &lt;p&gt;     &lt;a href="http://rmagick.rubyforge.org/"&gt;RMagick&lt;/a&gt;: The grand-daddy,     both in terms of advanced image processing features and memory usage.       (Wraps the ImageMagick library.)     &lt;/p&gt;   &lt;/li&gt;&lt;li&gt;     &lt;p&gt;     &lt;a href="http://rubyforge.org/projects/mini-magick/"&gt;minimagick&lt;/a&gt;:      It's much easier on memory than RMagick because it runs the ImageMagick      command in a shell.       &lt;/p&gt;   &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt; OK, so which library should you use? Well, given that we just need to resize images (and thumbnailing is just resizing), ImageScience is a perfect fit. If you have one of the others installed, go with it. Otherwise, spend a few minutes with the short and sweet &lt;a href="http://seattlerb.rubyforge.org/ImageScience.html"&gt;instructions&lt;/a&gt;  for installing ImageScience and FreeImage. &lt;/p&gt;  &lt;h5&gt;2. Download the attachment_fu Plugin&lt;/h5&gt;  &lt;p&gt; To make light work of the rest of this task, we're going to use  &lt;a href="http://techno-weenie.net/"&gt;Rick Olson's&lt;/a&gt; &lt;code&gt;attachment_fu&lt;/code&gt; plugin.  It's a significant rewrite of his original &lt;code&gt;acts_as_attachment&lt;/code&gt; plugin. That's right, this isn't Rick's first rodeo, and it's probably not his second. Seriously, I don't know of a more experienced person then Rick when it comes to uploading files into Rails applications. (And he's the king of good plugins!) &lt;/p&gt; &lt;p&gt; If you're using &lt;code&gt;acts_as_attachment&lt;/code&gt;, you might be wondering if it's time to upgrade. It's probably not one of those high-priority chores, but it's definitely something you want to consider doing soon. Rick's been working on &lt;code&gt;attachment_fu&lt;/code&gt; for almost a year now, and polishing it smooth in production settings. It comes with a comprehensive set of tests, as well. And as you'll see, it's more flexible than its worthy predecessor. To top it off, the public API hasn't changed. I converted an app this morning simply by renaming one declaration in a model from &lt;code&gt;acts_as_attachment&lt;/code&gt; to &lt;code&gt;has_attachment&lt;/code&gt;.  Well worth the price of admission.  One caveat: &lt;code&gt;attachment_fu&lt;/code&gt; requires Rails 1.2+. &lt;/p&gt;  &lt;p&gt; Here's how to get it: &lt;/p&gt;  &lt;pre&gt;script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/&lt;br /&gt;&lt;/pre&gt;  &lt;h5&gt;3. Write an Upload Form&lt;/h5&gt;  &lt;p&gt; Having installed all the supporting software, it's time to write our app.  Let's start with the upload form in the &lt;code&gt;new.rhtml&lt;/code&gt; file:&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_-xsiT-HQLy4/RuYzJPjTPoI/AAAAAAAAAK0/V5brrvLYwLs/s1600-h/new.bmp"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_-xsiT-HQLy4/RuYzJPjTPoI/AAAAAAAAAK0/V5brrvLYwLs/s400/new.bmp" alt="" id="BLOGGER_PHOTO_ID_5108827061184839298" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; Pretty standard form stuff, with a couple important bits.  First, I'm using RESTful named routes (&lt;code&gt;mugshots_paths&lt;/code&gt;), but it works just as well with traditional routes.  Second, the form uses the &lt;code&gt;file_field&lt;/code&gt; helper.  That helper generates a &lt;em&gt;Choose File&lt;/em&gt; button on the form.  It's important that we call the attribute &lt;code&gt;:uploaded_data&lt;/code&gt;, as its the attribute name that &lt;code&gt;attachment_fu&lt;/code&gt; looks for when storing the image.  Third, to allow the form to accept files as POST data, the form is generated with &lt;code&gt;:multipart =&gt; true&lt;/code&gt;.  Forget either of those finer points and you're in for a long afternoon.  &lt;/p&gt;  &lt;h5&gt;4. Write a Controller&lt;/h5&gt;  &lt;p&gt; The controller is oblivious to the fact that we're uploading images, so it's your typical overpaid middleman.  The &lt;code&gt;new&lt;/code&gt; action displays the upload form and the &lt;code&gt;create&lt;/code&gt; action accepts the POST data.   &lt;/p&gt;  &lt;pre&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;def new&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt; @mugshot = Mugshot.new&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;def create&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt; @mugshot = Mugshot.new(params[:mugshot])&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt; if @mugshot.save&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;   flash[:notice] = 'Mugshot was successfully created.'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;   redirect_to mugshot_url(@mugshot)    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt; else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;   render :action =&gt; :new&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt; end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;h5&gt;5. Write a Migration and Model&lt;/h5&gt;  &lt;p&gt; Next we need a &lt;code&gt;MugShot&lt;/code&gt; model (and a corresponding database table) to store the uploaded file information. Let's start with the migration file for the &lt;code&gt;mugshots&lt;/code&gt; database table. &lt;/p&gt;  &lt;pre&gt;class CreateMugshots &lt;&gt;  &lt;p&gt; How did we come up with those column names?  Well, we didn't.  By convention, &lt;code&gt;attachment_fu&lt;/code&gt; will automatically store the uploaded file information (the meta-data, if you will) in these columns. That begs the question: Where does the actual file data get stored? To answer that we need to write the &lt;code&gt;MugShot&lt;/code&gt; model. &lt;/p&gt;  &lt;pre&gt;class Mugshot &lt; content_type =""&gt; :image,&lt;br /&gt;           :storage =&gt; :file_system,&lt;br /&gt;           :max_size =&gt; 500.kilobytes,&lt;br /&gt;           :resize_to =&gt; '320x200&gt;',&lt;br /&gt;           :thumbnails =&gt; { :thumb =&gt; '100x100&gt;' }&lt;br /&gt;&lt;br /&gt;validates_as_attachment&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt; Here's where the &lt;code&gt;attachment_fu&lt;/code&gt; plugin makes you pump your fists in victory. Basically, at this point we'd rather not grovel around at the API level of whatever Ruby image library you have installed. We'd also like to program at a fairly high level and not worry about how the file information and data is stored. (We call those things &lt;em&gt;implementation details&lt;/em&gt; when our boss is listening.)     &lt;/p&gt;   &lt;p&gt; In the &lt;code&gt;has_attachment&lt;/code&gt; method we tell &lt;code&gt;attachment_fu&lt;/code&gt; what to do with the uploaded image.  The options are as follows:   &lt;/p&gt;  &lt;ul&gt;&lt;li&gt;     &lt;code&gt;:content_type&lt;/code&gt; - The content types that are allowed, which     defaults to all content types.  Using &lt;code&gt;:image&lt;/code&gt; allows all     standard image types.   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:min_size&lt;/code&gt; - The minimum size allowed, which defaults     to 1 byte   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:max_size&lt;/code&gt; - The maximum size allowed, which defaults     to 1 megabyte   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:size&lt;/code&gt; - A range of allowed sizes, which overrides     the &lt;code&gt;:min_size&lt;/code&gt; and &lt;code&gt;:max_size&lt;/code&gt; options   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:resize_to&lt;/code&gt; - An array of width/height values, or a      geometry string for resizing the image   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:thumbnails&lt;/code&gt; - A set of thumbnails to generate, specified     by a hash of filename suffixes and resizing options.  This option     can be omitted if you don't need thumbnails, and you can generate more     than one thumbnail simply by adding names and sizes to the hash.    &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:thumbnail_class&lt;/code&gt; - Sets what class (model) to use for     thumbnails, which defaults to the current class (MugShot, in this example).     You could, for example, use a different model class with a different set of     validations.   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:storage&lt;/code&gt; - Sets where the actual image data is stored.     Options include &lt;code&gt;:file_system&lt;/code&gt;, &lt;code&gt;:db_file&lt;/code&gt;, and     &lt;code&gt;:s3&lt;/code&gt;.   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:processor&lt;/code&gt; - Sets what image processor to use.        Options include &lt;code&gt;ImageScience&lt;/code&gt;, &lt;code&gt;Rmagick&lt;/code&gt;, and     &lt;code&gt;MiniMagick&lt;/code&gt;.  By default, it will use whatever you have installed.   &lt;/li&gt;&lt;li&gt;     &lt;code&gt;:path_prefix&lt;/code&gt; - Path to store the uploaded files, which     defaults to &lt;code&gt;public/#{table_name}&lt;/code&gt; by default for the filesystem.     If you're using the S3 backend, it defaults to just &lt;code&gt;#{table_name}&lt;/code&gt;.   &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt; We don't really want folks uploading life-sized mugshots, so calling  &lt;code&gt;validates_as_attachment&lt;/code&gt; prevents image sizes out of range from being saved. (They're still uploaded in memory, mind you.) As well, because we set an image content type, WinZip files won't be welcome, for example. &lt;/p&gt;  &lt;h5&gt;6. The Most Wanted List&lt;/h5&gt;  &lt;p&gt; OK, so now we're off to the races: select a mugshot file using the &lt;em&gt;Choose File&lt;/em&gt; button on the form, the mugshot image is uploaded to the server, the file metadata is stored in the &lt;code&gt;mugshots&lt;/code&gt; database table, and the actual file data is stored in the &lt;code&gt;public/mugshots&lt;/code&gt; directory on the server. &lt;/p&gt;  &lt;p&gt; Now we can show a line-up of thumbnails, with each thumbnail linked to the full-size image.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_-xsiT-HQLy4/RuYznvjTPpI/AAAAAAAAAK8/yg7gALJfXZI/s1600-h/most.bmp"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_-xsiT-HQLy4/RuYznvjTPpI/AAAAAAAAAK8/yg7gALJfXZI/s400/most.bmp" alt="" id="BLOGGER_PHOTO_ID_5108827585170849426" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt; The &lt;code&gt;public_filename&lt;/code&gt; method gives us the public path to the full-size file or the thumbnail if passed the name of the thumbnail suffix (&lt;code&gt;:thumb&lt;/code&gt;, in our case).  Given that we're using the filesystem as storage, this code ends up generating paths such as &lt;code&gt;/mugshots/34/bad_man.png&lt;/code&gt; and &lt;code&gt;/mugshots/34/bad_man_thumb.png&lt;/code&gt;.  Those paths are relative to the &lt;code&gt;$RAILS_ROOT/public&lt;/code&gt; directory on our server, by default.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-5954722321393867288?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/5954722321393867288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/file-upload-using-plugin-attachmentfu.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5954722321393867288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5954722321393867288'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/file-upload-using-plugin-attachmentfu.html' title='File upload using plugin - attachment_fu'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-xsiT-HQLy4/RuYzJPjTPoI/AAAAAAAAAK0/V5brrvLYwLs/s72-c/new.bmp' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-2186466922637015052</id><published>2007-09-03T01:58:00.000-07:00</published><updated>2007-09-17T00:13:30.398-07:00</updated><title type='text'>file_column - Plugin</title><content type='html'>&lt;p&gt;I’ve been using the &lt;a href="http://www.kanthak.net/opensource/file_column/" title="file_column"&gt;file_column plugin for Ruby on Rails&lt;/a&gt; in the last days, so here’s some handy notes on the subject:&lt;/p&gt; &lt;p&gt;Installing is pretty straightfoward, just like the majority of Rails plugins:&lt;/p&gt; &lt;p&gt;script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk&lt;/p&gt; &lt;p&gt;The first thing we need is to tell our model which column to use:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;class Blog &lt;&gt;&lt;/pre&gt; &lt;p&gt;Now, if we want to include a upload mechanism in our form, we need to include some code like this:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;&lt;%= file_column_field "blog", "image" %&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_-xsiT-HQLy4/Ru4osMrEhiI/AAAAAAAAALk/Vw12W7nPsvQ/s1600-h/picture-1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_-xsiT-HQLy4/Ru4osMrEhiI/AAAAAAAAALk/Vw12W7nPsvQ/s400/picture-1.png" alt="" id="BLOGGER_PHOTO_ID_5111067366893323810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;On our views, we can use the following to show our image:&lt;/p&gt; &lt;code&gt;&lt;%= image_tag url_for_file_column("blog", "image") %&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_-xsiT-HQLy4/Ru4ozsrEhjI/AAAAAAAAALs/o2-5mLeCCCo/s1600-h/picture-3.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_-xsiT-HQLy4/Ru4ozsrEhjI/AAAAAAAAALs/o2-5mLeCCCo/s400/picture-3.png" alt="" id="BLOGGER_PHOTO_ID_5111067495742342706" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;We can extend things further, like for instance, I may want to upload only “jpg” and “gif” images and I want them to have a certain size:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;class Blog &lt;&gt;&lt;/pre&gt; &lt;pre&gt;&lt;code&gt; validates_file_format_of :image, :in =&gt; ["gif", "jpg"]&lt;br /&gt;validates_filesize_of :image, :in =&gt; 1.kilobytes..5000.kilobytes&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;Now let’s use RMagick (see previous post) to do some image manipulations, like creating two aditional images with different sizes based on the image we uploaded, one which we shall name “peq” with a 86×71 pixel dimensions and another named “med” with a 289×258 pixel dimensions, I found out from the wiki that the crop parameter conveniently preserves the center of an image, removing space from the edges to reach the target width/height ratio:&lt;/p&gt; &lt;pre&gt;&lt;code&gt;class Blog &lt;&gt;&lt;/pre&gt; &lt;pre&gt;&lt;code&gt;:store_dir =&gt; "public/images/my_stupid_place_to_keep_images_uploaded",&lt;br /&gt;:magick =&gt; {:versions =&gt; {&lt;br /&gt;       :thumb =&gt; {:crop =&gt; "1:1",  :size =&gt; "86x87!", :name =&gt; "peq"},&lt;br /&gt;       :normal =&gt; {:crop =&gt; "1:1", :size =&gt; "289x258!", :name=&gt;"med"}&lt;br /&gt;       }&lt;br /&gt;     }&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_-xsiT-HQLy4/Ru4o8srEhkI/AAAAAAAAAL0/YMty1e1PTqk/s1600-h/picture-4.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_-xsiT-HQLy4/Ru4o8srEhkI/AAAAAAAAAL0/YMty1e1PTqk/s400/picture-4.png" alt="" id="BLOGGER_PHOTO_ID_5111067650361165378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;So, by default  file_column will save images with the following scheme:&lt;/p&gt; &lt;code&gt;&lt;/code&gt;myApp/public/[Model name]/[file_column field name]/[record id]/[image filename]&lt;code&gt;&lt;/code&gt; &lt;p&gt;but as I showed you, it’s possible to define a different storage directory in your model.&lt;/p&gt; &lt;p&gt;Now let’s access the smaller images we saved with RMagick, on our views:&lt;/p&gt; &lt;code&gt;&lt;%= image_tag url_for_file_column("blog", "image", "peq") %&gt;&lt;/code&gt; or &lt;code&gt;&lt;%= image_tag url_for_file_column("blog", "image", "med") %&gt;&lt;/code&gt; &lt;p&gt;Other interesting information,  you can access your image information in several ways:&lt;/p&gt; &lt;p&gt;&gt;&gt; p.image&lt;br /&gt;=&gt; “public/images/my_stupid_place_to_keep_images_uploaded/267/MyPicture.jpg”&lt;/p&gt; &lt;p&gt;&gt;&gt; p.image(”peq”)&lt;br /&gt;=&gt; “public/images/my_stupid_place_to_keep_images_uploaded/267/peq/MyPicture.jpg”&lt;/p&gt; &lt;p&gt;&gt;&gt; p.image_relative_path&lt;br /&gt;=&gt; “267/MyPicture.jpg”&lt;/p&gt; &lt;p&gt;&gt;&gt; p.image_relative_path(”peq”)&lt;br /&gt;=&gt; “267/peq/MyPicture.jpg”&lt;/p&gt; &lt;p&gt;&gt;&gt; File.basename(p.image)&lt;br /&gt;=&gt; “MyPicture.jpg”&lt;/p&gt; &lt;p&gt;More information on the subject:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.rubyonrails.com/rails/pages/HowToUseFileColumn" title="wiki"&gt;File_column wiki&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.webmasterlogs.com/uploading-files-and-images-with-rails-file_column-filecolumn-plugin/" title="upload"&gt;Uploading with File_column&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;There’s other alternatives for uploading images and files but I felt file_column is a good and easy solution for most cases.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-2186466922637015052?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/2186466922637015052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/filecolumn-plugin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/2186466922637015052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/2186466922637015052'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/filecolumn-plugin.html' title='file_column - Plugin'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_-xsiT-HQLy4/Ru4osMrEhiI/AAAAAAAAALk/Vw12W7nPsvQ/s72-c/picture-1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-5289481706356352612</id><published>2007-09-03T01:18:00.000-07:00</published><updated>2007-09-03T01:57:45.404-07:00</updated><title type='text'>Plugins on rails</title><content type='html'>&lt;h1&gt;Introduction&lt;/h1&gt;    &lt;p&gt;A Rails &lt;strong&gt;plugin&lt;/strong&gt; is either an extension or a modification of the core framework.  Plugins provide:&lt;/p&gt;    &lt;ul&gt;&lt;li&gt;a way for developers to share bleeding-edge ideas without hurting the stable code base&lt;/li&gt;&lt;li&gt;a segmented architecture so that units of code can be fixed or updated on their own release schedule&lt;/li&gt;&lt;li&gt;an outlet for the core developers so that they don’t have to include every cool new feature under the sun&lt;/li&gt;&lt;/ul&gt;    &lt;blockquote&gt;   &lt;p&gt;Examples of plugin usage include an ‘acts_as_taggable’ mixin for ActiveRecord objects (makes tagging trivial), ‘file_column’ for ActiveRecord (makes file uploading and image resizing easy), and ‘globalize’ (adds multilingual and internationalization support to Rails).&lt;/p&gt;  &lt;/blockquote&gt;    &lt;h1&gt;Further Reading&lt;/h1&gt;    &lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.rubyonrails.com/rails/pages/PluginsDiscussion" class="existingWikiWord"&gt;PluginsDiscussion&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.rubyonrails.com/rails/pages/SomeImportantPluginNotes" class="existingWikiWord"&gt;SomeImportantPluginNotes&lt;/a&gt; – Check your rails version before you start&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.rubyonrails.com/rails/pages/PluginsForDummies" class="existingWikiWord"&gt;PluginsForDummies&lt;/a&gt; &lt;span class="newWikiWord"&gt;&lt;a href="http://www.usome.com/"&gt;http://www.usome.com&lt;/a&gt;&lt;a href="http://wiki.rubyonrails.com/rails/pages/%3Ca+href%3D%22http%3A%2F%2Fwww.usome.com%22%3Ehttp%3A%2F%2Fwww.usome.com%3C%2Fa%3E"&gt;?&lt;/a&gt;&lt;/span&gt; shows the essential Ruby idea behind plugins.&lt;/li&gt;&lt;li&gt;Now there are some wiki tutorials on writing plugins &lt;a href="http://wiki.rubyonrails.com/rails/pages/HowTosPlugins" class="existingWikiWord"&gt;HowTosPlugins&lt;/a&gt;&lt;/li&gt;&lt;li&gt;If you wrote some code or found it somewhere and you don’t know how to put it into &lt;a href="http://wiki.rubyonrails.com/rails/pages/Plugins" class="existingWikiWord"&gt;Plugins&lt;/a&gt; – &lt;a href="http://wiki.rubyonrails.com/rails/pages/PluginRequests" class="existingWikiWord"&gt;PluginRequests&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h1&gt;Plugin Documentation&lt;/h1&gt;    &lt;p&gt;To find out how to use a newly installed plugin navigate to your project directory and issue the following command:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;rdoc --op doc/rdoc .&lt;/pre&gt;&lt;br /&gt;this will generate complete documentation for your project, including the installed plugins it uses. You can then view the html version of this documentation by pointing your browser at yourApp/doc/rdoc.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Plugin Directory&lt;/h1&gt;    &lt;p&gt;A &lt;a href="http://www.agilewebdevelopment.com/plugins/"&gt;searchable plugin database&lt;/a&gt;&lt;br /&gt;and &lt;a href="http://www.railslodge.com/"&gt;RailsLodge plugin directory&lt;/a&gt; is also available.&lt;/p&gt;&lt;h2&gt;Plugin Repositories&lt;/h2&gt;    &lt;p&gt;svn://rubyforge.org/var/svn/expressica/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://soen.ca/svn/projects/rails/plugins/"&gt;http://soen.ca/svn/projects/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://technoweenie.stikipad.com/plugins/"&gt;http://technoweenie.stikipad.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.techno-weenie.net/projects/plugins/"&gt;http://svn.techno-weenie.net/projects/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.recentrambles.com/plugins/"&gt;http://svn.recentrambles.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://opensvn.csie.org/rails_file_column/plugins/"&gt;http://opensvn.csie.org/rails_file_column/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.protocool.com/public/plugins/"&gt;http://svn.protocool.com/public/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/"&gt;http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.pragprog.com/Public/plugins/"&gt;http://svn.pragprog.com/Public/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://source.collectiveidea.com/public/rails/plugins/"&gt;http://source.collectiveidea.com/public/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="https://secure.near-time.com/svn/plugins/"&gt;https://secure.near-time.com/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.inlet-media.de/svn/rails_extensions/plugins/"&gt;http://svn.inlet-media.de/svn/rails_extensions/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.viney.net.nz/things/rails/plugins/"&gt;http://svn.viney.net.nz/things/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.hasmanythrough.com/public/plugins/"&gt;http://svn.hasmanythrough.com/public/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.shiftnetwork.com/plugins/"&gt;http://svn.shiftnetwork.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://caboo.se/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.6brand.com/projects/plugins/"&gt;http://svn.6brand.com/projects/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://shanesbrain.net/svn/rails/plugins/"&gt;http://shanesbrain.net/svn/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://errtheblog.com/svn/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.nkryptic.com/plugins/"&gt;http://svn.nkryptic.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.thoughtbot.com/plugins/"&gt;http://svn.thoughtbot.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.webwideconsulting.com/plugins/"&gt;http://svn.webwideconsulting.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://invisible.ch/svn/projects/plugins/"&gt;http://invisible.ch/svn/projects/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://rubyforge.org/var/svn/enum-column/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://streamlinedframework.org:8079/streamlined/plugins/"&gt;http://streamlinedframework.org:8079/streamlined/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://dvisionfactory.com/rails/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://hivelogic.com/plugins/"&gt;http://hivelogic.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://mattmccray.com/svn/rails/plugins/"&gt;http://mattmccray.com/svn/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://rubyforge.org/var/svn/cartographer/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://www.svn.recentrambles.com/plugins/"&gt;http://www.svn.recentrambles.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://tanjero.com/svn/plugins/"&gt;http://tanjero.com/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://filetofsole.org/svn/public/projects/rails/plugins/"&gt;http://filetofsole.org/svn/public/projects/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://topfunky.net/svn/plugins/"&gt;http://topfunky.net/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.joshpeek.com/projects/plugins/"&gt;http://svn.joshpeek.com/projects/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://rubyforge.org/var/svn/agtools/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.aviditybytes.com/rails/plugins/"&gt;http://svn.aviditybytes.com/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://beautifulpixel.textdriven.com/svn/plugins/"&gt;http://beautifulpixel.textdriven.com/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://mabs29.googlecode.com/svn/trunk/plugins/"&gt;http://mabs29.googlecode.com/svn/trunk/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://www.codyfauser.com/svn/projects/plugins/"&gt;http://www.codyfauser.com/svn/projects/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://craz8.com/svn/trunk/plugins/"&gt;http://craz8.com/svn/trunk/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://sean.treadway.info/svn/plugins/"&gt;http://sean.treadway.info/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.thebootstrapnation.com/public/plugins/"&gt;http://svn.thebootstrapnation.com/public/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://www.mattmccray.com/svn/rails/plugins/"&gt;http://www.mattmccray.com/svn/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://rubyforge.org//var/svn/validaterequest/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://sprocket.slackworks.com/svn/rails/plugins/"&gt;http://sprocket.slackworks.com/svn/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.simpltry.com/plugins/"&gt;http://svn.simpltry.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.elctech.com/svn/public/plugins/"&gt;http://svn.elctech.com/svn/public/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://xmlblog.stikipad.com/plugins/"&gt;http://xmlblog.stikipad.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://www.xml-blog.com/svn/plugins/"&gt;http://www.xml-blog.com/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.toolbocks.com/plugins/"&gt;http://svn.toolbocks.com/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://thar.be/svn/projects/plugins/"&gt;http://thar.be/svn/projects/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://code.teytek.com/rails/plugins/"&gt;http://code.teytek.com/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://www.infused.org/svn/plugins/"&gt;http://www.infused.org/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://rubyforge.org/var/svn/apptrain/trunk/vendor/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://s3cachestore.googlecode.com/svn/trunk/plugins/"&gt;http://s3cachestore.googlecode.com/svn/trunk/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://sbecker.net/shared/plugins/"&gt;http://sbecker.net/shared/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://opensvn.csie.org/macaque/plugins/"&gt;http://opensvn.csie.org/macaque/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.designbyfront.com/rails/plugins/"&gt;http://svn.designbyfront.com/rails/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="svn://rails.bleedingtrends.com/"&gt;svn://rails.bleedingtrends.com/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.rails-engines.org/plugins/"&gt;http://svn.rails-engines.org/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://dev.fiatdev.com/svn/plugins/"&gt;http://dev.fiatdev.com/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://john.guen.in/svn/plugins/"&gt;http://john.guen.in/svn/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://www.redhillonrails.org/svn/trunk/vendor/plugins/"&gt;http://www.redhillonrails.org/svn/trunk/vendor/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://rubyforge.org/var/svn/actsdisjoint/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://ajaxmessaging.googlecode.com/svn/trunk/plugins/"&gt;http://ajaxmessaging.googlecode.com/svn/trunk/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://mod-i18n.googlecode.com/svn/trunk/plugins/"&gt;http://mod-i18n.googlecode.com/svn/trunk/plugins/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;svn://majakari.net/public/rails/plugins/&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.lightyearsoftware.com/svn/plugins"&gt;http://svn.lightyearsoftware.com/svn/plugins&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a href="http://svn.devjavu.com/malaysia-rb/plugins/"&gt;http://svn.devjavu.com/malaysia-rb/plugins/&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-5289481706356352612?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/5289481706356352612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/plugins-on-rails.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5289481706356352612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5289481706356352612'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/plugins-on-rails.html' title='Plugins on rails'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-4292570845224191489</id><published>2007-09-02T23:56:00.000-07:00</published><updated>2007-12-19T21:09:29.426-08:00</updated><title type='text'>Rails using Captcha</title><content type='html'>&lt;p&gt;SimpleCaptcha 1.0 - REVISION 14(updated) is a stable release. Please update your plugin, if you are still on previous revision.&lt;/p&gt; &lt;p&gt;SimpleCaptcha is a plugin for rubyonrails applications to provide the captcha&lt;span style="color: rgb(51, 102, 255);"&gt;(Completely Automated Public Turing Test to Tell Computers and Humans Apart)&lt;/span&gt; functionality.&lt;br /&gt;Its implementation is really simple, it requires a single line of code in view and a single line of code in controller/model. The plugin is inspired from the &lt;a href="http://tore.darell.no/"&gt;Tore Darell’s&lt;/a&gt; capthca plugin &lt;a href="http://tore.darell.no/pages/validates_captcha"&gt;validates_captcha&lt;/a&gt; (Thanks for the plugin Tore!). The SimpleCaptcha has been coded from scratch where the idea of implementation and keeping it in the simplest form(writing just a single line of code), a variety of image styles, option to select the distortion level of images shows the re-invention of wheel.&lt;/p&gt;&lt;h3&gt;Features&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;Provides eight different style of images&lt;/li&gt;&lt;li&gt;Can be implemented as controller based or model based&lt;/li&gt;&lt;li&gt;Automated removal of old(validated and non-validated both) images.&lt;/li&gt;&lt;li&gt;Now, we can add customized CSS to the image, lable and the text field&lt;/li&gt;&lt;li&gt;Simple Captcha will bypass the functional/unit/integration tests, so that there will not be any mess in our test cases.&lt;/li&gt;&lt;li&gt;Provides three levels of distortion of images as low, medium or high… so now, we have three levels for complexities of images. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;b&gt;update_attribute is now working&lt;/b&gt; which was a bug in the &lt;a href="http://expressica.com/2007/02/06/simple-captcha-released-the-captcha-for-rails-applications/"&gt;&lt;b&gt;previous version&lt;/b&gt;&lt;/a&gt;, so please update your plugin by checking it out again from the SVN repository &lt;b&gt;svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha&lt;/b&gt;&lt;/p&gt; &lt;h3&gt;Pre-requisites&lt;/h3&gt; &lt;p&gt;1.) RMagick&lt;br /&gt;RMagick is the image handling library in ruby and is required to implement the SimpleCaptcha.&lt;br /&gt;RMagick is available on &lt;a href="http://rubyforge.org/projects/rmagick/"&gt;&lt;b&gt;RubyForge&lt;/b&gt;&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;Installation&lt;/h3&gt; &lt;ul&gt;&lt;li&gt; (recommended… to sync with the latest revision.)&lt;br /&gt;SVN checkput the plugin as &lt;div class="dp-highlighter nogutter"&gt;&lt;ol class="dp-rb" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;&gt;&gt;svn co svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha simple_captcha  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="display: none;" name="code" class="ruby:nocontrols:nogutter" cols="60" rows="10"&gt;&gt;&gt;svn co svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha simple_captcha &lt;/textarea&gt; &lt;p&gt;now put this directory simple_captcha into your applications &lt;b&gt;vendor/plugins&lt;/b&gt;  directory.  &lt;/p&gt;&lt;p&gt;&lt;b&gt;OR&lt;/b&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt; SimpleCaptcha plugin can be installed by running this command from the application root &lt;div class="dp-highlighter nogutter"&gt;&lt;ol class="dp-rb" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;&gt;&gt; ruby script\plugin install svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;textarea style="display: none;" name="code" class="ruby:nocontrols:nogutter" cols="60" rows="10"&gt;&gt;&gt; ruby script\plugin install svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha &lt;/textarea&gt; &lt;p&gt;NOTE: for windows users this installation might require the &lt;a href="http://downloads-guests.open.collab.net/files/documents/61/66/CollabNet-Subversion-1.4-server-and-client-Windows.exe"&gt;&lt;b&gt;command line svn&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Simple Application Using Captcha:&lt;br /&gt;&lt;/h3&gt;  create a application namely captcha&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;$ rails captcha&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;create a model User and create table using migration using the following commands.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;$ ruby script/generate model user&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The 001_create_user.rb file should be...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;class CreateUsers &lt;&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Use following command to start migration&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;$ rake db:migrate&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Create a controller and view based on the following command&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;$ ruby script/generate controller user index update thanks&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;The Usercontroller.rb file should be&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;class UserController  ApplicationController&lt;br /&gt;&lt;br /&gt;def index&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def update&lt;br /&gt;@user = User.new(params[:user])&lt;br /&gt;if simple_captcha_valid?&lt;br /&gt;  if @user.save&lt;br /&gt;    redirect_to :action =&gt; 'thanks', :id =&gt; @user.id&lt;br /&gt;  else&lt;br /&gt;     redirect_to :action =&gt; 'error'&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def thanks&lt;br /&gt;render :text =&gt; "Thank u registration"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def error&lt;br /&gt;render :text =&gt; "R u a real user? "&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;The  index.rhtml page should be has the following code&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 153, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_-xsiT-HQLy4/RtuzlfjTPnI/AAAAAAAAAKs/31-zKGEwzkI/s1600-h/untitled.bmp"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_-xsiT-HQLy4/RtuzlfjTPnI/AAAAAAAAAKs/31-zKGEwzkI/s400/untitled.bmp" alt="" id="BLOGGER_PHOTO_ID_5105872059260681842" border="0" /&gt;&lt;/a&gt;Execute ruby script/server to run the application or click here &lt;a href="http://localhost:3000/user"&gt;http://localhost:3000/user&lt;/a&gt;&lt;br /&gt;&lt;br /&gt; The captcha image and the text typed by user will not be stored in the database.&lt;br /&gt;&lt;br /&gt;This is an article that i collected from other net resources and some of the text are my own.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-4292570845224191489?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/4292570845224191489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/rails-using-rails.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/4292570845224191489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/4292570845224191489'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/09/rails-using-rails.html' title='Rails using Captcha'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_-xsiT-HQLy4/RtuzlfjTPnI/AAAAAAAAAKs/31-zKGEwzkI/s72-c/untitled.bmp' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-8555388781452367869</id><published>2007-08-12T23:22:00.000-07:00</published><updated>2007-08-13T01:23:34.020-07:00</updated><title type='text'>Ruby on Rails with Oracle</title><content type='html'>You may have already knowledge with the ruby on rails and how to work on it along with the Mysql. This tutorial is some what useful for the developers who wants to create an application using Rails with Oracle.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Why Need for Oracle ?&lt;br /&gt;&lt;br /&gt;                              &lt;/span&gt;Every database has its own functionalities and unique speciality to handle data. Its depend upon the developer and the specifications were the main reason for shifting databases. The aim of this article is not to analyse those things and only to expose the knolwedge how to develop an application using oracle in ruby on rails. Let's go !&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Getting started&lt;br /&gt;&lt;br /&gt;                    &lt;/span&gt;Its assumed that your system has Oracle already. Now , we need to install the driver for oracle get connected with the rails. Its also a open source driver which can be downloaded from the site.&lt;br /&gt;&lt;br /&gt;               Click the following link to get the driver oci&lt;br /&gt;&lt;a href="http://rubyforge.org/projects/ruby-oci8"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;http://rubyforge.org/projects/ruby-oci8/&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;           Make sure that whether you are getting the latest driver from there. Because lots of error might be araised due to the version problems. Download the file to your system. For eg: Assume the downloaded driver file is in C: drive. The ruby command to make run the driver is&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;c:\&gt; ruby ruby-oci8-1.0.0-rc3-mswin32.rb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                   The ruby-oci8-1.0.0-rc3-mswin32 is the downloaded file name. so make sure the file name is correct.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Configuring oracle in rails :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;                                  &lt;/span&gt;&lt;/span&gt;&lt;p&gt; Different databases require different connection properties. Rails is set up to work with MySQL by default, but you want to re-configure this project to use Oracle. Change the development properties as follows. (You could change the test and production properties also, but the scope of this article doesn’t include testing or production releases.) &lt;/p&gt;       &lt;pre&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;development:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;adapter: oci&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;username: ruby&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;password: ruby&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;host: localhost&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;                 &lt;/span&gt;Open the file database.yml. As a rails programmer u must known that this file is responsible for connecting database in development , testing and in the production too. Now, in the development block make changes as per above. The username and password are the fields that you have to enter corresponding to your database.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Simple Application :&lt;br /&gt;                            &lt;/span&gt;&lt;br /&gt;                  I'm going to show u a sample application running rails with oracle. Application name is product. Its a very simple application likes a product catalog. User of the application can add a product, edit a product and view the list of the product using scaffold. It is assume that the reader of this article were known the scaffold concept already.&lt;br /&gt;&lt;br /&gt;To create an application&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;$ rails product&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;$ cd product&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      Now the product application is created. Now the database.yml file should be configured relative to our oracle database. Edit that file as shown in below the username and password field should to varied to your system.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;development:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;adapter: oci&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;username: admin &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;password: admin&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;host: localhost&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Migration :&lt;br /&gt;&lt;br /&gt;       &lt;/span&gt;Migration is a concept that a rails developer should come across before move ahead. Create a migration file products by&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;$ ruby script/generate migration products&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   It will create a migration file 001_product.rb  in the db\migrate path of the application.&lt;br /&gt;open the file and edit it as shown below&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;class Product &lt;&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;  def self.up&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;    create_table :products do |t|&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;      t.column :name, :string, :limit =&gt; 30&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;      t.column :description, :string&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;      t.column :price,  :integer, :null =&gt; false, :default =&gt; 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;    end  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;  end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;  def self.down&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;  end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;      Type the following command to make use od the migration.&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;$ rake db:migrate&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;       Now the data base is connected to rails and a tabel products is also created for our application.&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span&gt;Scaffolding :&lt;br /&gt;&lt;br /&gt;         &lt;/span&gt;The scaffolding is the basic simple concept to create a application easily. Execute the following command to create a scaffold&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;$ ruby script/generate scaffold product&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It will create codes automatically for the add, edit and list of the products. To run the application start the server as&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;$ ruby script/server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;     That's all. Type the following URl in the browser to view the list of products in our products table which is in our oracle database.&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;a href="http://localhost:3000/products/list"&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;http://localhost:3000/products/list&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Initially the table is empty and it likes to be&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_-xsiT-HQLy4/RsAEr3itJzI/AAAAAAAAAH0/_SvC__ILjGM/s1600-h/empty.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_-xsiT-HQLy4/RsAEr3itJzI/AAAAAAAAAH0/_SvC__ILjGM/s400/empty.JPG" alt="" id="BLOGGER_PHOTO_ID_5098079929873803058" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;Products adding through the application is advisible than directly add it to the database. Once some products are added it might be shown as&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 102, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_-xsiT-HQLy4/RsAFcnitJ0I/AAAAAAAAAH8/ts8PYtGpVcs/s1600-h/product.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_-xsiT-HQLy4/RsAFcnitJ0I/AAAAAAAAAH8/ts8PYtGpVcs/s400/product.JPG" alt="" id="BLOGGER_PHOTO_ID_5098080767392425794" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;The products shown here are all fake&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-8555388781452367869?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/8555388781452367869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/08/ruby-on-rails-with-oracle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/8555388781452367869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/8555388781452367869'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/08/ruby-on-rails-with-oracle.html' title='Ruby on Rails with Oracle'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_-xsiT-HQLy4/RsAEr3itJzI/AAAAAAAAAH0/_SvC__ILjGM/s72-c/empty.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-6304920700786115829</id><published>2007-08-09T21:22:00.000-07:00</published><updated>2009-05-08T02:26:43.362-07:00</updated><title type='text'>Search Table Items in AJAX and Rails</title><content type='html'>&lt;h2&gt; Introduction and warnings&lt;/h2&gt;  &lt;p&gt;&lt;a name="intro" id="intro"&gt;&lt;/a&gt; In this tutorial, we will try to use Ajax with Rails in order to display a table of items with several functionalities :&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;em&gt;pagination&lt;/em&gt; (split the table on several pages)&lt;/li&gt;&lt;li&gt;&lt;em&gt;sorting&lt;/em&gt; (table ordering by one of its column)&lt;/li&gt;&lt;li&gt;&lt;em&gt;searching&lt;/em&gt; (selecting items to be displayed with a query)&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;A live demonstration of this application is available at :&lt;/p&gt;  &lt;p style="color: rgb(51, 51, 255);"&gt;&lt;a href="http://dev.nozav.org/ajaxtable/"&gt;http://dev.nozav.org/ajaxtable/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is a very common task in web application development. The interest to use Ajax for this is to provide a dynamic interface which doesn't need to reload the entire page when the table changes. The interest of using Rails is... well, if you are reading this you should already know, but Ajax is really nicely integrated with Rails, and using it is very easier with this great framework. Nevertheless, the code in this tutorial should work the traditional way (by reloading the entire page) if javascript is not available on client side. This is very important for accessibility.&lt;/p&gt;  &lt;p&gt;The code which follows is highly inspired from several &lt;a href="http://wiki.rubyonrails.com/"&gt;Rails wiki&lt;/a&gt; pages, in particular &lt;a href="http://wiki.rubyonrails.com/rails/pages/How+to+make+a+real-time+search+box+with+the+Ajax+helpers"&gt;How to make a real-time search box with the Ajax helpers&lt;/a&gt;, and &lt;a href="http://wiki.rubyonrails.com/rails/pages/How+to+Paginate+With+Ajax"&gt;How to paginate with Ajax&lt;/a&gt;. I just put things together and sometimes slightly adapted the code.&lt;/p&gt;  &lt;p&gt;Now, the warnings. I am not a Rails guru, and far from being an Ajax expert. I am  a beginner in both areas. So take this document as a beginner introduction to beginners : code could be cleaner, explanations more accurate, and some things could probably have been designed more efficiently an elegantly. Moreover, as english is not my native language, you will find many faults and inaccuracies through this text. Please excuse me in advance.&lt;/p&gt;&lt;h2&gt;&lt;a name="sec2" id="sec2"&gt;&lt;/a&gt; Application installation and configuration&lt;/h2&gt;  &lt;p class="first"&gt;The first thing we have to do is to install and setup the application. If you already had done this before, you could probably skip this section.&lt;/p&gt;   &lt;h3&gt;&lt;a name="sec3" id="sec3"&gt;&lt;/a&gt; Requirements&lt;/h3&gt;  &lt;p class="first"&gt;In this tutorial you are supposed to have a recent Rails version installed (at least version 1.0) and a functional database system. Here we will use &lt;code&gt;sqlite&lt;/code&gt;, but you can replace it by the one you prefer without any problem.&lt;/p&gt;&lt;h3&gt; Files&lt;/h3&gt;  &lt;p class="first"&gt;First, we have to create the "skeleton" of our application in the directory of our choice&lt;sup&gt;&lt;a name="fnr.1" href="http://dev.nozav.org/rails_ajax_table.html#fn.1"&gt;1&lt;/a&gt;&lt;/sup&gt; :&lt;/p&gt;&lt;pre&gt;$ rails ajaxtable&lt;br /&gt;$ cd ajaxtable&lt;/pre&gt;&lt;p&gt;As it is a very basic application, we will use only one model, which will represent table items, and one controller for these items. We will generate the corresponding files with the Rails scripts :&lt;/p&gt;  &lt;pre&gt;$ ruby script/generate model Item&lt;br /&gt;$ ruby script/generate controller Item&lt;/pre&gt;    &lt;h3&gt;&lt;a name="sec5" id="sec5"&gt;&lt;/a&gt; Database&lt;/h3&gt;  Once we have the files, we have to setup a data source. For simplicity here we will use &lt;code&gt;Mysql&lt;/code&gt; in conjunction with Rails schema. This means that we will describe our database inside Rails and let it manage database creation.  &lt;p&gt;First, we have to update the development data source in &lt;code&gt;config/database.yml&lt;/code&gt;. Enter ur database password in password  :&lt;/p&gt;  &lt;pre&gt;development:&lt;br /&gt;adapter: mysql&lt;br /&gt;database: ajaxtable_development&lt;br /&gt;username: root&lt;br /&gt;password:&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;Next, we will create the database by using Rails migration tools.&lt;/p&gt;  &lt;pre&gt;$ ruby script/generate migration database_creation&lt;/pre&gt;  &lt;p&gt;This should have created a &lt;code&gt;db/migrate/001_database_creation.rb&lt;/code&gt; file in which we will define our database schema the following way :&lt;/p&gt;  &lt;pre&gt;&lt;br /&gt;&lt;br /&gt;class DatabaseCreation &lt; ActiveRecord::Migration&lt;br /&gt;  def self.up&lt;br /&gt;    create_table :ites do |t|&lt;br /&gt;       t.column :name, :string, :limit =&gt; 30&lt;br /&gt;       t.column :quantity, :integer, :null =&gt; false, :default =&gt;0&lt;br /&gt;       t.column :price, :integer, :null =&gt; false, :default =&gt; 0&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def self.down&lt;br /&gt;     drop_table :items&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;    This just defines one table named &lt;code&gt;items&lt;/code&gt; with three columns&lt;sup&gt;&lt;a name="fnr.2" href="http://dev.nozav.org/rails_ajax_table.html#fn.2"&gt;2&lt;/a&gt;&lt;/sup&gt; : a string field called &lt;code&gt;name&lt;/code&gt;, and two integer columns called &lt;code&gt;quantity&lt;/code&gt; and &lt;code&gt;price&lt;/code&gt; (nothing really original, yes...).&lt;/p&gt;  &lt;p&gt;Then, we just have to do a :&lt;/p&gt;  &lt;pre&gt;$ rake db:migrate&lt;/pre&gt;  &lt;p&gt;U can also use the  following command but it shows some negotiable depreciation warnings.&lt;/p&gt;&lt;pre&gt;$ rake migrate&lt;/pre&gt;&lt;p&gt;And you should now have a &lt;code&gt;development.db&lt;/code&gt; file in your &lt;code&gt;db&lt;/code&gt; directory which is your &lt;code&gt;sqlite&lt;/code&gt; database created by Rails with the &lt;code&gt;items&lt;/code&gt; table inside.&lt;/p&gt;&lt;h2&gt; Creating the model&lt;/h2&gt;  &lt;p class="first"&gt;As you probably know, a Rails application is divided into three main types of components : models, views and controllers. We will create them one by one.&lt;/p&gt;  &lt;p&gt;The &lt;em&gt;model&lt;/em&gt; of our application will be very simple here. In fact, as we don't have any complex query to send to the database, it will stay the same as generated by Rails in our application installation, &lt;em&gt;ie&lt;/em&gt; empty. So we will not touch the &lt;code&gt;app/models/item.rb&lt;/code&gt; file.&lt;/p&gt;  &lt;p&gt;Well, I hope this step has not been too difficult !&lt;/p&gt;     &lt;h2&gt;&lt;a name="sec7" id="sec7"&gt;&lt;/a&gt; Creating the view&lt;/h2&gt;  &lt;p class="first"&gt;The &lt;em&gt;view&lt;/em&gt; of our application will be split into two components : a layout, a view and a partial.&lt;/p&gt;   &lt;h3&gt;&lt;a name="sec8" id="sec8"&gt;&lt;/a&gt; Layout&lt;/h3&gt;  &lt;p class="first"&gt;The &lt;em&gt;layout&lt;/em&gt; is a page template which will be used to render several views. It contains some non-varying elements such as HTML header and footer, menus, design elements, etc. The utility of a layout is very limited in our example, as we will have only one page. But it is a tutorial, after all...&lt;/p&gt;  &lt;p&gt;Here, the layout will be located in &lt;code&gt;app/views/layouts/item.rhtml&lt;/code&gt;, and will contain something like :&lt;/p&gt;  &lt;pre&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;lt;title&amp;gt;Ajax table manipulation attempt&amp;lt;/title&amp;gt;&lt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;lt;%= stylesheet_link_tag "style" %&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;lt;%= javascript_include_tag :defaults %&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id="content"&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;%= @content_for_lauout %&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;  &lt;p&gt;An important thing here is the &lt;code&gt;javascript_include_tag&lt;/code&gt; tag which will be replaced by the javascript libraries used by Rails to provide Ajax features.&lt;/p&gt;  &lt;p&gt;Also note the &lt;code&gt;@content_for_layout&lt;/code&gt; instruction, which will be replaced by the generated content when needed.&lt;/p&gt;&lt;h3&gt; View&lt;/h3&gt;  &lt;p class="first"&gt;The &lt;em&gt;view&lt;/em&gt; component will be used to render a particular action of our controller, which we will describe immediately after this. As it is a &lt;code&gt;list&lt;/code&gt; action of our &lt;code&gt;item&lt;/code&gt; controller, the view will be located in &lt;code&gt;app/views/item/list.rhtml&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;The content of the file will be the following :&lt;/p&gt;  &lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;h1&amp;gt;Welcome to my wondeful items list&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&lt;br /&gt;&amp;lt;form name="sform" action="" style="display:inline;"&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;lt;label for="item_name"&amp;gt;Filter on item name : &amp;lt;/label&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;lt;%= text_field_tag("query", @params['query'], :size =&amp;gt; 10)%&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;%= image_tag("spinner.gif",&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; :align =&amp;gt; 'absmide',&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; :border =&amp;gt; 0,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; id =&amp;gt; "spinner",&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; :style =&amp;gt; "display: none;") %&amp;gt;&lt;br /&gt;&amp;lt;%= observe_field 'query, :frequency =&amp;gt; 2,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;:update =&amp;gt; 'table',&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;:before =&amp;gt; "Element.show('spinner')",&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;:success =&amp;gt; "Element.hide('spinner')",&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;:url =&amp;gt; {:action =&amp;gt; 'list'},&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;:with =&amp;gt; 'query' %&amp;gt;&lt;br /&gt;&amp;lt;div id="table"&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;%= render :partial =&amp;gt; "items_list" %&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;There is nothing really complicated in the beginning. A stupid introduction text and a search form which will be used to filter items on their names.&lt;/p&gt;  &lt;p&gt;Then, we have an image element whose &lt;code&gt;id&lt;/code&gt; is &lt;code&gt;spinner&lt;/code&gt; and which is hidden by default. This image will be shown briefly during Ajax operations on the page, and then hidden again when everything is finished. You can get some public domain images here :&lt;/p&gt;  &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://mentalized.net/activity-indicators/"&gt;http://mentalized.net/activity-indicators/&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You have to put the chosen image file in the &lt;code&gt;public/images&lt;/code&gt; directory of your application.&lt;/p&gt;  &lt;p&gt;The following &lt;code&gt;observe_field&lt;/code&gt; instruction is a bit more unusual. What this instruction does here is to add a new Ajax &lt;em&gt;observer&lt;/em&gt; on the &lt;code&gt;query&lt;/code&gt; field. This observer will periodically (here, every 2 seconds, look at the &lt;code&gt;frequency&lt;/code&gt; parameter) check the content of this field and will react if this content has changed.&lt;/p&gt;  &lt;p&gt;The action to be taken is described by the remaining parameters :&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;strong&gt;update&lt;/strong&gt; gives the id of the page element which will be updated. Here it is the &lt;code&gt;table&lt;/code&gt; &lt;div&gt; which encloses our partial call just a bit further in the code.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;url&lt;/strong&gt; gives the action that will render the new HTML content to be inserted. Here the &lt;code&gt;list&lt;/code&gt; action of our controller will handle every request.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;with&lt;/strong&gt; indicates the way the field content will be passed to the &lt;code&gt;url&lt;/code&gt; action. Here we will add a &lt;code&gt;query&lt;/code&gt; parameter to our Ajax request with value equals to the content of the observed field.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;before&lt;/strong&gt; indicates an action to be performed during the time the Ajax request is treated.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;success&lt;/strong&gt; indicates an action to be performed when the Ajax request has been succesfully treated.&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;The concrete effect of all this stuff is quite simple. When the user type something in the &lt;code&gt;query&lt;/code&gt; field, the observer will detect the new content of the field, and then generate an Ajax request sent to the server with the &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;with&lt;/code&gt; parameters. As soon as the request is sent, the &lt;code&gt;before&lt;/code&gt; action toggles the visibility of the &lt;code&gt;spinner&lt;/code&gt; XHTML element, and the user can see the image. When the request answer his received, the &lt;code&gt;table&lt;/code&gt; XHTML element is updated, and the &lt;code&gt;success&lt;/code&gt; action hides the spinner image again.&lt;/p&gt;  &lt;p&gt;Just for information, here is what the &lt;code&gt;observe_field&lt;/code&gt; function returns with the given parameters :&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;&lt;script type="text/javascript"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;//&lt;![CDATA[&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;new Form.Element.Observer('query', 2, function(element, value) {Element.show('spinner'); new Ajax.Updater('table', '/item/list', {asynchronous:true, evalScripts:true, onSuccess:function(request){Element.hide('spinner')}, parameters:'query=' + value})})&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;//]]&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;&lt;/script&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;We spent some time here to detail the different options because we will meet them again in nearly all the other Ajax methods in this tutorial.&lt;/p&gt;  &lt;p&gt;And, to finish this view description, we have a call to a &lt;em&gt;partial&lt;/em&gt; element called &lt;code&gt;items_list&lt;/code&gt;. We will describe this concept and its content in detail after setting up our controller.&lt;/p&gt;&lt;h2&gt; Creating the controller&lt;/h2&gt;  &lt;p class="first"&gt;The controller will handle different kinds of requests in order to update the view by calling the model depending on the request type and its parameters.&lt;/p&gt;  &lt;p&gt;Our &lt;code&gt;Item&lt;/code&gt; controller will be very simple here, and will only include one action called &lt;code&gt;list&lt;/code&gt;. We will not implement any other CRUD (Create, read, update, delete) action in this tutorial.&lt;/p&gt;  &lt;p&gt;So here is the content of &lt;code&gt;app/controllers/item_controller.rb&lt;/code&gt; :&lt;/p&gt;  &lt;p&gt;&lt;a name="controller" id="controller"&gt;&lt;/a&gt; &lt;/p&gt;&lt;pre&gt;&lt;br /&gt;class ItemController &amp;lt; ApplicationController&lt;br /&gt;&amp;#160;&amp;#160;def list&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;items_per_page = 10&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;sort = case @params['sort']&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;when "name" then "name"&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;when "qty" then "quantity"&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;when "price" then "price"&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;when "name_reverse" then "name DESC"&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;when "qty_reverse" then "quantity DESC"&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;when "price_reverse" then "price DESC"&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;end&lt;br /&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;conditions = ["name LIKE ?", "%#{@params[:query]}%"] unless @params[:query].nil?&lt;br /&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @total = Item.count(:conditions =&amp;gt; conditiond)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @items_pages, @items = paginate :items, :order =&amp;gt; sort, :conditions =&amp;gt; conditions, :per_page = items_per_page&lt;br /&gt;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if request.xml_http_request?&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;render :partial =&amp;gt; "items_list", :layout =&amp;gt; false&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; end&lt;br /&gt;&amp;#160;&amp;#160;end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;Let's explain this a bit.&lt;/p&gt;  &lt;p&gt;Our controller only defines one action, called &lt;code&gt;list&lt;/code&gt;. This action will have to handle every request sent to our application.&lt;/p&gt;  &lt;p&gt;First, we define a variable called &lt;code&gt;items_per_page&lt;/code&gt; which will represent the number of lines our table will show on each page.&lt;/p&gt;  &lt;p&gt;Next, we define another variable called &lt;code&gt;sort&lt;/code&gt;, depending on the request parameter of the same name. The &lt;code&gt;case&lt;/code&gt; can be used to mask the real fields name in our database, which can be more suitable for security reasons. The &lt;code&gt;reverse&lt;/code&gt; string in the &lt;code&gt;sort&lt;/code&gt; parameter indicates that sorting should be made in descending order.&lt;/p&gt;  &lt;p&gt;Then, a &lt;code&gt;conditions&lt;/code&gt; variable is constructed if a &lt;code&gt;query&lt;/code&gt; request parameter is present. It is an SQL-like instruction which will be used to filter our database query results based on the content of the &lt;code&gt;name&lt;/code&gt; field.&lt;/p&gt;  &lt;p&gt;After that, we assign the total number of items in our database matching the &lt;code&gt;conditions&lt;/code&gt; to the &lt;code&gt;@total&lt;/code&gt; variable.&lt;/p&gt;  &lt;p&gt;And eventually, we find a call to the Rails &lt;code&gt;paginate&lt;/code&gt; instruction. We give to this instruction the model it should be associated to (&lt;code&gt;:items&lt;/code&gt;), a sort field, conditions to be applied to the query, and the number of items we want on each page. And it automagically returns us a paginator object called &lt;code&gt;@items_pages&lt;/code&gt; and the items for the current page number (this page number is passed as a &lt;code&gt;page&lt;/code&gt; request parameter, which is transparent here). The paginator object will be used later to display pagination links.&lt;/p&gt;  &lt;p&gt;All we have seen for the controller until now applied to every request passed to the application, whatever its type. The most used kinds of HTTP requests are the traditional GET and POST, but Rails and Ajax can make an important use of a third type, whose name is XmlHttpRequest&lt;sup&gt;&lt;a name="fnr.4" href="http://dev.nozav.org/rails_ajax_table.html#fn.4"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;  &lt;p&gt;This kind of request is launched by javascript, which will send it in the background via HTTP to the server. One use of the kind of request is to get a fragment of XHTML page used to update a part of the browser display, without reloading the entire page. This can give the user the impression of a fastest and more responsive interface.&lt;/p&gt;  &lt;p&gt;That is what the final part of our controller deals with : it tests if the request it has received is of type &lt;code&gt;xml_http_request&lt;/code&gt;&lt;sup&gt;&lt;a name="fnr.5" href="http://dev.nozav.org/rails_ajax_table.html#fn.5"&gt;5&lt;/a&gt;&lt;/sup&gt;. In this case, it will not render the entire &lt;code&gt;list&lt;/code&gt; view, but only a fragment of it, the now famous partial whose name is &lt;code&gt;items_list&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;So, as we can see, this &lt;code&gt;xml_http_request&lt;/code&gt; test is the only "really Ajax" thing we met in the controller. That is because Ajax things are linked to the interface of our application, &lt;em&gt;ie&lt;/em&gt; the view, and more specifically the part of it which will be managed with Ajax, &lt;em&gt;ie&lt;/em&gt; the partial.&lt;/p&gt;  &lt;p&gt;So, could you guess what we are going to do now ?&lt;/p&gt;&lt;h2&gt; Creating the partial&lt;/h2&gt;  &lt;p class="first"&gt;A &lt;em&gt;partial&lt;/em&gt; view component is used to render only a part of a page. It is very useful to separate some repeated view constructions in order to reuse them and to follow the &lt;em&gt;Don't Repeat Yourself&lt;/em&gt; (DRY) Rails principle. But it is also really useful with Ajax.&lt;/p&gt;  &lt;p&gt;Indeed, the effect of our Ajax actions in this tutorial will always be to redisplay the table of items, whereas it is to change the page, the order or the search. So we will have to refresh the table, but not the entire page, otherwise an Ajax call is of very limited utility. That's why we will separate all the elements which will have to be updated in a &lt;em&gt;partial&lt;/em&gt; file&lt;sup&gt;&lt;a name="fnr.6" href="http://dev.nozav.org/rails_ajax_table.html#fn.6"&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;  &lt;p&gt;Partial filenames always begin with an underscore, so here our partial will be in &lt;code&gt;app/views/item/_items_list.rhtml&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;Its content will be the following :&lt;/p&gt;  &lt;pre&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_-xsiT-HQLy4/RrvzQXitJxI/AAAAAAAAAHk/zOWezvJ36C4/s1600-h/partial.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_-xsiT-HQLy4/RrvzQXitJxI/AAAAAAAAAHk/zOWezvJ36C4/s400/partial.JPG" alt="" id="BLOGGER_PHOTO_ID_5096934865822885650" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;Some explanations may be needed here. The partial contains the table pagination and sorting management. We will see both in a more detailed way.&lt;/p&gt;   &lt;h3&gt;&lt;a name="sec12" id="sec12"&gt;&lt;/a&gt; Pagination helpers&lt;/h3&gt;  &lt;p class="first"&gt;In the beginning, we have a test to see if the total number of items found is greater than zero. In this case, we display this total number and then a paragraph which will be empty if there is only one page in our items pagination.&lt;/p&gt;  &lt;p&gt;If we have more than one page of results, we clearly have to display &lt;em&gt;pagination links&lt;/em&gt;. Rails already have methods to help dealing with them, but we will have to customize them a little. For this, we will create a &lt;em&gt;helper&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;A helper is a Ruby function which is used to help generating the view. The aim is to separate the code in these functions from the view itself, and to make this code reusable.&lt;/p&gt;  &lt;p&gt;Our helpers will all be located in &lt;code&gt;app/helpers/item_helper.rb&lt;/code&gt;. Each method in this file will be accessible from our view. If we wanted them to be usable by every view of our application, we could have put them in &lt;code&gt;application_helper.rb&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;Well, enough blabla, here is the code of our &lt;code&gt;pagination_links_remote&lt;/code&gt; helper :&lt;/p&gt;  &lt;p&gt;&lt;a name="pagination_links_remote" id="pagination_links_remote"&gt;&lt;/a&gt; &lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_-xsiT-HQLy4/RrvzYXitJyI/AAAAAAAAAHs/TdyMNNVODM0/s1600-h/summa.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_-xsiT-HQLy4/RrvzYXitJyI/AAAAAAAAAHs/TdyMNNVODM0/s400/summa.JPG" alt="" id="BLOGGER_PHOTO_ID_5096935003261839138" border="0" /&gt;&lt;/a&gt;&lt;p&gt;This method takes a paginator object as argument. This is a Rails object which keeps information about the current pagination state (number of pages, current page, etc.).&lt;/p&gt;  &lt;p&gt;We then define a &lt;code&gt;page_options&lt;/code&gt; hash which contains only one item called &lt;code&gt;window_size&lt;/code&gt;. This is a parameter which tells Rails how many pages it has to show around the current one. For example, if &lt;code&gt;window_size&lt;/code&gt; equals one, we will have something like :&lt;/p&gt;  &lt;blockquote&gt; &lt;p class="quoted"&gt;1 ... 5 6 7 ... 13&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If &lt;code&gt;window_size&lt;/code&gt; equals 2 :&lt;/p&gt;  &lt;blockquote&gt; &lt;p class="quoted"&gt;1 ... 4 5 6 7 8 ... 13&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We could then make a call to the &lt;code&gt;pagination_links&lt;/code&gt; function, which would generate the correct XHTML code for our links. But the problem is that it will generate "classic" XHTML links, but not the Ajax one. So we will have to redefine the links ourselves. This is done with the &lt;code&gt;pagination_links_each&lt;/code&gt; method.&lt;/p&gt;  &lt;p&gt;This method iterates over the pages to be displayed and then applies the block passed as its argument. Our block first defines two kinds of options :&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;strong&gt;options&lt;/strong&gt; are defined for the Ajax link generation. These are very similar to those defined in the &lt;code&gt;observe_field&lt;/code&gt; element. The only new thing is the call to &lt;code&gt;@params.merge&lt;/code&gt;, which will add the current request parameters to the link by replacing an existing page param by the page number in the block.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;html_options&lt;/strong&gt; are just defined to generate the "classic" XHTML link, in order to let pagination work if javascript is not available.&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;Then, there is just a call to the &lt;code&gt;link_to_remote&lt;/code&gt; function, which will generate the complete XHTML for our link, including the javascript and the classic XHTML &lt;code&gt;href&lt;/code&gt; part.&lt;/p&gt;&lt;h3&gt; Sorting helpers&lt;/h3&gt;  &lt;p class="first"&gt;Back to our partial. After the pagination links we start to define the table by itself. The definition of the table header is a bit complicated, because that is where we define the links to sort our data by a column or another. Each header cell makes use of two helpers.&lt;/p&gt;  &lt;p&gt;The first helper is nothing but necessary. It is called &lt;code&gt;sort_td_class_helper&lt;/code&gt;, and his only goal is to add a &lt;code&gt;class="sortup"&lt;/code&gt; if the column is currently the one used to sort the table, or a &lt;code&gt;class="sortdown"&lt;/code&gt; if it is used to sort in reverse order. The only utility is to allow, with CSS, to indicates to the user which column is currently used as a sorting field.&lt;/p&gt;  &lt;p&gt;The code is nothing interesting which is already shown in the figure  &lt;code&gt;pagination_links_remote&lt;/code&gt; helper&lt;br /&gt;&lt;/p&gt;Then, we have a second helper, called &lt;code&gt;sort_link_helper&lt;/code&gt; which is also in that.    &lt;p&gt;This helper is in fact very similar to the &lt;code&gt;pagination_links_remote&lt;/code&gt; one, &lt;a href="http://dev.nozav.org/rails_ajax_table.html#pagination_links_remote"&gt;seen above&lt;/a&gt;. It takes two arguments :&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;strong&gt;text&lt;/strong&gt;, which is just the text to be displayed as the column header and sort link&lt;/li&gt;&lt;li&gt;&lt;strong&gt;param&lt;/strong&gt;, which is the name of the request parameter associated with the column.&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;The first two lines define a new variable, called &lt;code&gt;key&lt;/code&gt;, which gets the value of the &lt;code&gt;param&lt;/code&gt; argument, &lt;em&gt;ie&lt;/em&gt; the sort key. The string &lt;code&gt;_reverse&lt;/code&gt; is concatenated to it if &lt;code&gt;param&lt;/code&gt; is already the sorting key. This is used to implement sorting in both ascending and descending order. If the user select a sort link, it will sort by ascending order ; if it selects the same link again, it will sort by descending order, and so on. You can &lt;a href="http://dev.nozav.org/rails_ajax_table.html#controller"&gt;look at the controller&lt;/a&gt; if you don't find these explanations clear enough.&lt;/p&gt;  &lt;p&gt;The rest of the helper is to define the options for the final call to the &lt;code&gt;link_to_remote&lt;/code&gt; function. They are very similar to those of &lt;code&gt;pagination_links_remote&lt;/code&gt; :&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;the &lt;strong&gt;options&lt;/strong&gt; hash, used for the javascript Ajax link, contains the &lt;code&gt;url&lt;/code&gt; to be called to generate the new HTML, the id of the element to update, and two &lt;code&gt;before&lt;/code&gt; and &lt;code&gt;success&lt;/code&gt; actions to show/hide the spinner image.&lt;/li&gt;&lt;li&gt;the &lt;strong&gt;html_options&lt;/strong&gt; hash, used for the HTML link. It generates the content of the &lt;code&gt;href&lt;/code&gt; attribute with the &lt;code&gt;url_for&lt;/code&gt; Rails function.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt; Table body&lt;/h3&gt;  &lt;p class="first"&gt;The end of the partial just displayed our table body, with one item on each line. The only thing which may be noted here is the use of the &lt;code&gt;cycle&lt;/code&gt; Rails function, which will automatically and alternatively add a "odd" or "even" style class to our table rows, which can be very useful to display it in a more visible way.&lt;/p&gt;&lt;h2&gt; That's all folks !&lt;/h2&gt;  &lt;p class="first"&gt;We have now seen every pieces of our application more or less in detail. In theory you could see the result by starting the WebRick server and point your browser to :&lt;/p&gt;  &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://localhost:3000/item/list"&gt;http://localhost:3000/item/list&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-6304920700786115829?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/6304920700786115829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/08/search-table-items-in-ajax-and-rails.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/6304920700786115829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/6304920700786115829'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/08/search-table-items-in-ajax-and-rails.html' title='Search Table Items in AJAX and Rails'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-xsiT-HQLy4/RrvzQXitJxI/AAAAAAAAAHk/zOWezvJ36C4/s72-c/partial.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1611524385965097078.post-5972273360067748706</id><published>2007-08-09T05:13:00.000-07:00</published><updated>2007-09-12T23:31:34.992-07:00</updated><title type='text'>Ruby - An Intro</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_-xsiT-HQLy4/RujZOMrEheI/AAAAAAAAALE/DcOW8I_X5IE/s1600-h/logo.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_-xsiT-HQLy4/RujZOMrEheI/AAAAAAAAALE/DcOW8I_X5IE/s400/logo.gif" alt="" id="BLOGGER_PHOTO_ID_5109572615195100642" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://longdistance-t1.com/"&gt;&lt;img src="http://longdistance-t1.com/images/InternetCalls_88.gif" align="bottom" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Ruby an Introduction&lt;br /&gt;&lt;/h3&gt; &lt;p&gt;                         Ruby is the interpreted scripting language for quick and easy object-oriented programming. It has many features to process text files and to do system management tasks (as in Perl). It is simple, straight-forward, extensible, and portable.&lt;/p&gt; &lt;p&gt;Oh, I need to mention, it's totally free, which means not only free of charge, but also freedom to use, copy, modify, and distribute it.&lt;/p&gt; &lt;h3&gt;Features of Ruby&lt;br /&gt;&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;Ruby has simple syntax, partially inspired by Eiffel and Ada.&lt;/li&gt;&lt;li&gt;Ruby has exception handling features, like Java or Python, to make it easy to handle errors.&lt;/li&gt;&lt;li&gt;Ruby's operators are syntax sugar for the methods. You can redefine them easily.&lt;/li&gt;&lt;li&gt;Ruby is a complete, full, pure object oriented language: OOL. This means all data in Ruby is an object, in the sense of Smalltalk: no exceptions. Example: In Ruby, the number 1 is an instance of class Fixnum.&lt;/li&gt;&lt;li&gt;Ruby's OO is carefully designed to be both complete and open for improvements. Example: Ruby has the ability to add methods to a class, or even to an instance during runtime. So, if needed, an instance of one class *can* behave differently from other instances of the same class.&lt;/li&gt;&lt;li&gt;Ruby features single inheritance only, *on purpose*. But Ruby knows the concept of modules (called Categories in Objective-C). Modules are collections of methods. Every class can import a module and so gets all its methods for free. Some of us think that this is a much clearer way than multiple inheritance, which is complex, and not used very often compared with single inheritance (don't count C++ here, as it has often no other choice due to strong type checking!).&lt;/li&gt;&lt;li&gt;Ruby features true closures. Not just unnamed function, but with present variable bindings.&lt;/li&gt;&lt;li&gt;Ruby features blocks in its syntax (code surrounded by '{' ... '}' or 'do' ... 'end'). These blocks can be passed to methods, or converted into closures.&lt;/li&gt;&lt;li&gt;Ruby features a true mark-and-sweep garbage collector. It works with all Ruby objects. You don't have to care about maintaining reference counts in extension libraries. This is better for your health. ;-)&lt;/li&gt;&lt;li&gt;Writing C extensions in Ruby is easier than in Perl or Python, due partly to the garbage collector, and partly to the fine extension API. SWIG interface is also available.&lt;/li&gt;&lt;li&gt;Integers in Ruby can (and should) be used without counting their internal representation. There *are* small integers (instances of class Fixnum) and large integers (Bignum), but you need not worry over which one is used currently. If a value is small enough, an integer is a Fixnum, otherwise it is a Bignum. Conversion occurs automatically.&lt;/li&gt;&lt;li&gt;Ruby needs no variable declarations. It uses simple naming conventions to denote the scope of variables. Examples: simple 'var' = local variable, '@var' = instance variable, '$var' = global variable. So it is also not necessary to use a tiresome 'self.' prepended to every instance member.&lt;/li&gt;&lt;li&gt;Ruby can load extension libraries dynamically if an OS allows.&lt;/li&gt;&lt;li&gt;Ruby features OS independent threading. Thus, for all platforms on which Ruby runs, you also have multithreading, regardless of if the OS supports it or not, even on MS-DOS! ;-)&lt;/li&gt;&lt;li&gt;Ruby is highly portable: it is developed mostly on Linux, but works on many types of UNIX, DOS, Windows 95/98/Me/NT/2000/XP, MacOS, BeOS, OS/2, etc.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Ruby Download&lt;/h3&gt;&lt;h3&gt;How to get Ruby&lt;/h3&gt;  &lt;ul&gt;&lt;li&gt;The stable release &lt;a href="ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5.tar.gz"&gt;ruby-1.8.5&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The CVS branch for the development version is available. See &lt;a href="http://www.ruby-lang.org/en/20020106.html"&gt;CVS Repository Guide&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Downloadable Items&lt;br /&gt;&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;&lt;a href="ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5.tar.gz"&gt;Ruby version 1.8.5 source (stable release)&lt;/a&gt; and its &lt;a href="http://rubyforge.org/frs/?group_id=426"&gt;rubyforge mirror &lt;img class="ext" src="http://www2.ruby-lang.org/ext.png" alt="" height="9" width="9" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="ftp://ftp.ruby-lang.org/pub/ruby/stable-snapshot.tar.gz"&gt;Stable snapshot&lt;/a&gt; (Thu Aug 09 04:00:52 JST 2007) is available. This is tar'ed and gzip'ed file of the latest stable CVS. It should be better than the last stable release.&lt;/li&gt;&lt;li&gt;&lt;a href="ftp://ftp.ruby-lang.org/pub/ruby/snapshot.tar.gz"&gt;Nightly snapshot&lt;/a&gt; (Thu Aug 09 04:00:29 JST 2007) is available. This is tar'ed and gzip'ed file of the latest CVS. It may contain unfixed problems. (as usual ;-)&lt;/li&gt;&lt;li&gt;&lt;a href="ftp://ftp.ruby-lang.org/pub/ruby/snapshot-1.6.tar.gz"&gt;1.6 snapshot&lt;/a&gt; (Fri Dec 29 04:00:54 JST 2006) is available. This is tar'ed and gzip'ed file of the latest 1.6 CVS. If you cannot shift to 1.8 for some reasons and you want better version than last 1.6 release, use this snapshot.&lt;/li&gt;&lt;li&gt;You can get &lt;a href="http://www.garbagecollect.jp/ruby/mswin32/"&gt;Ruby-mswin32 &lt;img class="ext" src="http://www2.ruby-lang.org/ext.png" alt="" height="9" width="9" /&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://rubyinstaller.rubyforge.org/wiki/wiki.pl"&gt;Install Ruby under Windows &lt;img class="ext" src="http://www2.ruby-lang.org/ext.png" alt="" height="9" width="9" /&gt;&lt;/a&gt; ... A single download that contains everything you need to run Ruby under various Windows operating systems.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ruby-lang.org/%7Eeban/ruby/binaries/"&gt;Ruby on Windows&lt;/a&gt; (cygwin setup, djgpp, mingw)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1611524385965097078-5972273360067748706?l=ramesh-rubyonrails.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramesh-rubyonrails.blogspot.com/feeds/5972273360067748706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/08/ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5972273360067748706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1611524385965097078/posts/default/5972273360067748706'/><link rel='alternate' type='text/html' href='http://ramesh-rubyonrails.blogspot.com/2007/08/ruby.html' title='Ruby - An Intro'/><author><name>Ramesh</name><uri>http://www.blogger.com/profile/17517926508987992520</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_-xsiT-HQLy4/RujZOMrEheI/AAAAAAAAALE/DcOW8I_X5IE/s72-c/logo.gif' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
