<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Rubyonrailstricks's Weblog</title>
	<atom:link href="http://rubyonrailstricks.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://rubyonrailstricks.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Wed, 19 Sep 2007 09:56:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='rubyonrailstricks.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Rubyonrailstricks's Weblog</title>
		<link>http://rubyonrailstricks.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://rubyonrailstricks.wordpress.com/osd.xml" title="Rubyonrailstricks&#039;s Weblog" />
	<atom:link rel='hub' href='http://rubyonrailstricks.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Ruby on rails &#8211; An introduction</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/09/19/ruby-on-rails-an-introduction/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/09/19/ruby-on-rails-an-introduction/#comments</comments>
		<pubDate>Wed, 19 Sep 2007 07:38:34 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/09/19/ruby-on-rails-an-introduction/</guid>
		<description><![CDATA[Ruby an Introduction 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. Oh, I need to mention, it&#8217;s totally free, which means not only free of charge, but [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=3&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://bp2.blogger.com/_-xsiT-HQLy4/RujZOMrEheI/AAAAAAAAALE/DcOW8I_X5IE/s1600-h/logo.gif"><img src="http://bp2.blogger.com/_-xsiT-HQLy4/RujZOMrEheI/AAAAAAAAALE/DcOW8I_X5IE/s400/logo.gif" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></p>
<h3>Ruby an Introduction</h3>
<p>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.</p>
<p>Oh, I need to mention, it&#8217;s totally free, which means not only free of charge, but also freedom to use, copy, modify, and distribute it.</p>
<h3>Features of Ruby</h3>
<ul>
<li>Ruby has simple syntax, partially inspired by Eiffel and Ada.</li>
<li>Ruby has exception handling features, like Java or Python, to make it easy to handle errors.</li>
<li>Ruby&#8217;s operators are syntax sugar for the methods. You can redefine them easily.</li>
<li>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.</li>
<li>Ruby&#8217;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.</li>
<li>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&#8217;t count C++ here, as it has often no other choice due to strong type checking!).</li>
<li>Ruby features true closures. Not just unnamed function, but with present variable bindings.</li>
<li>Ruby features blocks in its syntax (code surrounded by &#8216;{&#8216; &#8230; &#8216;}&#8217; or &#8216;do&#8217; &#8230; &#8216;end&#8217;). These blocks can be passed to methods, or converted into closures.</li>
<li>Ruby features a true mark-and-sweep garbage collector. It works with all Ruby objects. You don&#8217;t have to care about maintaining reference counts in extension libraries. This is better for your health. ;-)</li>
<li>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.</li>
<li>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.</li>
<li>Ruby needs no variable declarations. It uses simple naming conventions to denote the scope of variables. Examples: simple &#8216;var&#8217; = local variable, &#8216;@var&#8217; = instance variable, &#8216;$var&#8217; = global variable. So it is also not necessary to use a tiresome &#8216;self.&#8217; prepended to every instance member.</li>
<li>Ruby can load extension libraries dynamically if an OS allows.</li>
<li>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! ;-)</li>
<li>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.</li>
</ul>
<h3>Ruby Download</h3>
<h3>How to get Ruby</h3>
<ul>
<li>The stable release <a href="ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5.tar.gz">ruby-1.8.5</a>.</li>
<li>The CVS branch for the development version is available. See <a href="http://www.ruby-lang.org/en/20020106.html">CVS Repository Guide</a></li>
</ul>
<h3>Downloadable Items</h3>
<ul>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5.tar.gz">Ruby version 1.8.5 source (stable release)</a> and its <a href="http://rubyforge.org/frs/?group_id=426">rubyforge mirror <img src="http://www2.ruby-lang.org/ext.png" class="ext" height="9" width="9" /></a></li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/stable-snapshot.tar.gz">Stable snapshot</a> (Thu Aug 09 04:00:52 JST 2007) is available. This is tar&#8217;ed and gzip&#8217;ed file of the latest stable CVS. It should be better than the last stable release.</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/snapshot.tar.gz">Nightly snapshot</a> (Thu Aug 09 04:00:29 JST 2007) is available. This is tar&#8217;ed and gzip&#8217;ed file of the latest CVS. It may contain unfixed problems. (as usual ;-)</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/snapshot-1.6.tar.gz">1.6 snapshot</a> (Fri Dec 29 04:00:54 JST 2006) is available. This is tar&#8217;ed and gzip&#8217;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.</li>
<li>You can get <a href="http://www.garbagecollect.jp/ruby/mswin32/">Ruby-mswin32 <img src="http://www2.ruby-lang.org/ext.png" class="ext" height="9" width="9" /></a>.</li>
<li><a href="http://rubyinstaller.rubyforge.org/wiki/wiki.pl">Install Ruby under Windows <img src="http://www2.ruby-lang.org/ext.png" class="ext" height="9" width="9" /></a> &#8230; A single download that contains everything you need to run Ruby under various Windows operating systems.</li>
<li><a href="http://www.ruby-lang.org/%7Eeban/ruby/binaries/">Ruby on Windows</a> (cygwin setup, djgpp, mingw)</li>
</ul>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/3/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/3/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=3&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/09/19/ruby-on-rails-an-introduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>

		<media:content url="http://bp2.blogger.com/_-xsiT-HQLy4/RujZOMrEheI/AAAAAAAAALE/DcOW8I_X5IE/s400/logo.gif" medium="image" />

		<media:content url="http://www2.ruby-lang.org/ext.png" medium="image" />

		<media:content url="http://www2.ruby-lang.org/ext.png" medium="image" />

		<media:content url="http://www2.ruby-lang.org/ext.png" medium="image" />
	</item>
		<item>
		<title>File upload using plugin &#8211; attachment_fu</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/09/11/file-upload-using-plugin-attachment_fu/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/09/11/file-upload-using-plugin-attachment_fu/#comments</comments>
		<pubDate>Tue, 11 Sep 2007 06:10:00 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[Ruby on rails - Plugins]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/09/11/file-upload-using-plugin-attachment_fu/</guid>
		<description><![CDATA[Listed : Web Directory Top Sites Free _uacct = &#8220;UA-2597032-1&#8243;; urchinTracker(); 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&#8217;s upload some mug shots. You know, to identify the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=11&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Listed : <a href="http://www.dmegs.com/">Web Directory Top Sites Free</a></p>
<p>_uacct = &#8220;UA-2597032-1&#8243;;<br />
urchinTracker();</p>
<p>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&#8217;s upload some mug shots. You know, to identify the goofballs around the office.</p>
<h5>1. Install an Image Processor</h5>
<p>We&#8217;ll need to resize the mugshots during the upload process, and we&#8217;ll also want to generate thumbnails of the mugshots to use around the site.</p>
<p>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&#8217;s the least fun step of the entire process, so let&#8217;s get it out of the way early.</p>
<p>Choose from one of the following libraries:</p>
<ul>
<li>     <a href="http://seattlerb.rubyforge.org/ImageScience.html">ImageScience</a>:      A light inline-Ruby library that <em>only</em> resizes images.       (Wraps the FreeImage library.)</li>
<li>     <a href="http://rmagick.rubyforge.org/">RMagick</a>: The grand-daddy,     both in terms of advanced image processing features and memory usage.       (Wraps the ImageMagick library.)</li>
<li>     <a href="http://rubyforge.org/projects/mini-magick/">minimagick</a>:      It&#8217;s much easier on memory than RMagick because it runs the ImageMagick      command in a shell.</li>
</ul>
<p>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 <a href="http://seattlerb.rubyforge.org/ImageScience.html">instructions</a>  for installing ImageScience and FreeImage.</p>
<h5>2. Download the attachment_fu Plugin</h5>
<p>To make light work of the rest of this task, we&#8217;re going to use  <a href="http://techno-weenie.net/">Rick Olson&#8217;s</a> <code>attachment_fu</code> plugin.  It&#8217;s a significant rewrite of his original <code>acts_as_attachment</code> plugin. That&#8217;s right, this isn&#8217;t Rick&#8217;s first rodeo, and it&#8217;s probably not his second. Seriously, I don&#8217;t know of a more experienced person then Rick when it comes to uploading files into Rails applications. (And he&#8217;s the king of good plugins!)</p>
<p>If you&#8217;re using <code>acts_as_attachment</code>, you might be wondering if it&#8217;s time to upgrade. It&#8217;s probably not one of those high-priority chores, but it&#8217;s definitely something you want to consider doing soon. Rick&#8217;s been working on <code>attachment_fu</code> 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&#8217;ll see, it&#8217;s more flexible than its worthy predecessor. To top it off, the public API hasn&#8217;t changed. I converted an app this morning simply by renaming one declaration in a model from <code>acts_as_attachment</code> to <code>has_attachment</code>.  Well worth the price of admission.  One caveat: <code>attachment_fu</code> requires Rails 1.2+.</p>
<p>Here&#8217;s how to get it:</p>
<pre>script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/</pre>
<h5>3. Write an Upload Form</h5>
<p>Having installed all the supporting software, it&#8217;s time to write our app.  Let&#8217;s start with the upload form in the <code>new.rhtml</code> file:</p>
<p><a href="http://bp3.blogger.com/_-xsiT-HQLy4/RuYzJPjTPoI/AAAAAAAAAK0/V5brrvLYwLs/s1600-h/new.bmp"><img src="http://bp3.blogger.com/_-xsiT-HQLy4/RuYzJPjTPoI/AAAAAAAAAK0/V5brrvLYwLs/s400/new.bmp" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></p>
<p>Pretty standard form stuff, with a couple important bits.  First, I&#8217;m using RESTful named routes (<code>mugshots_paths</code>), but it works just as well with traditional routes.  Second, the form uses the <code>file_field</code> helper.  That helper generates a <em>Choose File</em> button on the form.  It&#8217;s important that we call the attribute <code>:uploaded_data</code>, as its the attribute name that <code>attachment_fu</code> looks for when storing the image.  Third, to allow the form to accept files as POST data, the form is generated with <code>:multipart =&gt; true</code>.  Forget either of those finer points and you&#8217;re in for a long afternoon.</p>
<h5>4. Write a Controller</h5>
<p>The controller is oblivious to the fact that we&#8217;re uploading images, so it&#8217;s your typical overpaid middleman.  The <code>new</code> action displays the upload form and the <code>create</code> action accepts the POST data.</p>
<pre><span style="font-weight:bold;color:#006600;">def new</span><span style="font-weight:bold;color:#006600;"> @mugshot = Mugshot.new</span><span style="font-weight:bold;color:#006600;">end</span>

<span style="font-weight:bold;color:#006600;">def create</span><span style="font-weight:bold;color:#006600;"> @mugshot = Mugshot.new(params[:mugshot])</span><span style="font-weight:bold;color:#006600;"> if @mugshot.save</span><span style="font-weight:bold;color:#006600;">   flash[:notice] = 'Mugshot was successfully created.'</span><span style="font-weight:bold;color:#006600;">   redirect_to mugshot_url(@mugshot)    </span><span style="font-weight:bold;color:#006600;"> else</span><span style="font-weight:bold;color:#006600;">   render :action =&gt; :new</span><span style="font-weight:bold;color:#006600;"> end</span><span style="font-weight:bold;color:#006600;">end</span></pre>
<h5>5. Write a Migration and Model</h5>
<p>Next we need a <code>MugShot</code> model (and a corresponding database table) to store the uploaded file information. Let&#8217;s start with the migration file for the <code>mugshots</code> database table.</p>
<pre>class CreateMugshots

 How did we come up with those column names?  Well, we didn't.  By convention, <code>attachment_fu</code> 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 <code>MugShot</code> model.
<pre>class Mugshot  :image,           :storage =&gt; :file_system,           :max_size =&gt; 500.kilobytes,           :resize_to =&gt; '320x200&gt;',           :thumbnails =&gt; { :thumb =&gt; '100x100&gt;' }

validates_as_attachment

end</pre>
<p>Here's where the <code>attachment_fu</code> 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 <em>implementation details</em> when our boss is listening.)</p>
<p>In the <code>has_attachment</code> method we tell <code>attachment_fu</code> what to do with the uploaded image.  The options are as follows:</p>
<ul>
<li>     <code>:content_type</code> - The content types that are allowed, which     defaults to all content types.  Using <code>:image</code> allows all     standard image types.</li>
<li>     <code>:min_size</code> - The minimum size allowed, which defaults     to 1 byte</li>
<li>     <code>:max_size</code> - The maximum size allowed, which defaults     to 1 megabyte</li>
<li>     <code>:size</code> - A range of allowed sizes, which overrides     the <code>:min_size</code> and <code>:max_size</code> options</li>
<li>     <code>:resize_to</code> - An array of width/height values, or a      geometry string for resizing the image</li>
<li>     <code>:thumbnails</code> - 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.</li>
<li>     <code>:thumbnail_class</code> - 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.</li>
<li>     <code>:storage</code> - Sets where the actual image data is stored.     Options include <code>:file_system</code>, <code>:db_file</code>, and     <code>:s3</code>.</li>
<li>     <code>:processor</code> - Sets what image processor to use.        Options include <code>ImageScience</code>, <code>Rmagick</code>, and     <code>MiniMagick</code>.  By default, it will use whatever you have installed.</li>
<li>     <code>:path_prefix</code> - Path to store the uploaded files, which     defaults to <code>public/#{table_name}</code> by default for the filesystem.     If you're using the S3 backend, it defaults to just <code>#{table_name}</code>.</li>
</ul>
<p>We don't really want folks uploading life-sized mugshots, so calling  <code>validates_as_attachment</code> 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.</p>
<h5>6. The Most Wanted List</h5>
<p>OK, so now we're off to the races: select a mugshot file using the <em>Choose File</em> button on the form, the mugshot image is uploaded to the server, the file metadata is stored in the <code>mugshots</code> database table, and the actual file data is stored in the <code>public/mugshots</code> directory on the server.</p>
<p>Now we can show a line-up of thumbnails, with each thumbnail linked to the full-size image.</p>
<p><a href="http://bp1.blogger.com/_-xsiT-HQLy4/RuYznvjTPpI/AAAAAAAAAK8/yg7gALJfXZI/s1600-h/most.bmp"><img src="http://bp1.blogger.com/_-xsiT-HQLy4/RuYznvjTPpI/AAAAAAAAAK8/yg7gALJfXZI/s400/most.bmp" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></p>
<p>The <code>public_filename</code> method gives us the public path to the full-size file or the thumbnail if passed the name of the thumbnail suffix (<code>:thumb</code>, in our case).  Given that we're using the filesystem as storage, this code ends up generating paths such as <code>/mugshots/34/bad_man.png</code> and <code>/mugshots/34/bad_man_thumb.png</code>.  Those paths are relative to the <code>$RAILS_ROOT/public</code> directory on our server, by default.</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/11/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/11/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=11&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/09/11/file-upload-using-plugin-attachment_fu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>

		<media:content url="http://bp3.blogger.com/_-xsiT-HQLy4/RuYzJPjTPoI/AAAAAAAAAK0/V5brrvLYwLs/s400/new.bmp" medium="image" />

		<media:content url="http://bp1.blogger.com/_-xsiT-HQLy4/RuYznvjTPpI/AAAAAAAAAK8/yg7gALJfXZI/s400/most.bmp" medium="image" />
	</item>
		<item>
		<title>Asynchronous Messaging using Rails</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/09/10/asynchronous-messaging-using-rails/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/09/10/asynchronous-messaging-using-rails/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 11:18:00 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[AP4R]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/09/10/asynchronous-messaging-using-rails/</guid>
		<description><![CDATA[When asked how to integrate with other applications, the vast majority of Rails developers would answer &#8220;REST&#8220;. And when they answer REST, they almost always mean synchronously. Now I have nothing against REST per se, but I will always favour asynchronous communication over synchronous. An asynchronous messaging solution such as JMS has well-documented advantages such [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=10&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When asked how to integrate with other applications, the vast majority of Rails developers would answer &#8220;<a href="http://en.wikipedia.org/wiki/REST">REST</a>&#8220;. And when they answer REST, they almost always mean synchronously. Now I have nothing against REST per se, but I will always favour asynchronous communication over synchronous. An asynchronous messaging solution such as JMS has well-documented advantages such as:</p>
<ul>
<li>The message producer can &#8220;fire and forget&#8221;, sending the message and then moving on to more important work.</li>
<li>The mechanisms required for reliability are relatively simple in the producer and consumer, and the more difficult tasks (such as persistence) can be handled in the message broker.</li>
<li>It is easy to add redundancy into the messaging infrastructure</li>
</ul>
<p>For further reference, a good book on the topic is Gregor Hohpe&#8217;s <a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Addison-Wesley/dp/0321200683">Enterprise Integration Patterns</a></p>
<p>On a number of occasions I&#8217;ve started out with synchronous messaging, only to say to myself &#8220;I really want this to be reliable&#8221;. So I fire off an http request and wait for a 200. If I don&#8217;t receive a 200 after a certain amount of time, then I try again. I&#8217;ll repeat this for a few times, then I&#8217;ll give up, and log the failure somewhere.</p>
<p>Then I say to myself &#8220;It would be really nice to have this re-trying out-of-process&#8221;. So I add another process that receives a request for a message to be sent, sends the message, and performs any re-trying that is required. And all of a sudden, I have asynchronous messaging. Now, there&#8217;s nothing about REST that prevents asynchronous messaging, but I rarely see anyone from the Rails community talking about anything but synchronous messaging. So I thought I&#8217;d talk about how we&#8217;ve solved the problem on our project. We&#8217;ve used the <a href="http://code.google.com/p/activemessaging/wiki/ActiveMessaging">ActiveMessaging</a> plugin, originally written by some people from Thoughtworks. I&#8217;ll demonstrate ActiveMessaging here, and then over the next week or two I&#8217;ll contrast it with a JMS JRuby solution I&#8217;ve been playing around with.</p>
<p>Let&#8217;s say we have two Rails applications &#8211; a Customer Management application and an Order Management application. The Customer application is responsible for managing all things to do with Customers &#8211; their personal details, any communications between our business and the customers, and the customer&#8217;s user preferences. The Customer Management app has a rich view of a customer with fields such as:</p>
<ul>
<li>Name</li>
<li>Address</li>
<li>Telephone Number, etc.</li>
</ul>
<p>The Order Management application needs to associate Orders with Customers, so that even when the Customer application is down for scheduled maintenance, orders can still be taken. The Orders app has a simple view of a Customer, with just a name and an id.</p>
<p>We will make the Customer application responsible for creating, updating and deleting Customers. Whenever any of these actions are performed, the Customer application notifies the Orders application with a message. The message indicates the type of action performed (create, update, or delete), and the id of the customer, so that the two &#8216;views&#8217; of the Customer object (in the two different applications) can be kept in sync. The Orders application then creates, updates, or deletes its view of the customer according to the type of message that is sent.</p>
<p>First, we will need to setup an ActiveMQ Server. I&#8217;ve set it up locally on my machine using these instructions (I used the Linux instructions for my Macbook Pro):</p>
<p><a href="http://activemq.apache.org/getting-started.html">http://activemq.apache.org/getting-started.html</a></p>
<p>In both of our Rails applications we will need to install the ActiveMessaging plugin:</p>
<p>script/plugin install http://activemessaging.googlecode.com/svn/trunk/plugins/activemessaging</p>
<p>ActiveMessaging provides the ability to send and receive messages. Our Customer application will send messages, and our Orders application will receive them.</p>
<p>For the purposes of this discussion, I will only show the &#8216;create&#8217; messages, though the process would be very similar for &#8216;update&#8217; and &#8216;delete&#8217;.</p>
<h4>Customer application</h4>
<p>Our Customer application has a Customer object that inherits from ActiveRecord::Base:</p>
<pre><span class="source source_ruby source_ruby_rails"><span class="meta meta_rails meta_rails_model"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Customer<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby">&lt;</span> ActiveRecord::Base</span></span></span></span><span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>It has the following fields:</p>
<pre><span class="source source_ruby source_ruby_rails"><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>name</span>, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>string</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>address</span>, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>string</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>telephone_number</span>, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>string</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>created_at</span>, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>date_time</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>updated_at</span>, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>date_time</span></span></pre>
<p>Our message will be a YAML serialized message of the following simple data object:</p>
<pre><span class="source source_ruby source_ruby_rails"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">CustomerPayload</span></span> <span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">attr_accessor</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>id</span>, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>name</span>

 <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">initialize</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">params</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>   <span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>id</span> = params[<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>id</span>]   <span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>name</span> = params[<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>name</span>] <span class="keyword keyword_control keyword_control_ruby">end</span><span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>We use a rails observer to observe the &#8216;create&#8217; event of the Customer object, construct a CustomerPayload object, serialize it, and send it via ActiveMessaging:</p>
<p align="center"><span class="source source_ruby source_ruby_rails"><span class="meta meta_require meta_require_ruby"><span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">require</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">&#8216;</span>activemessaging/processor<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">&#8216;</span></span></span><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">CustomerObserver<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby">&lt;</span> ActiveRecord::Observer</span></span></span>  <span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">include</span> <span class="support support_class support_class_ruby">ActiveMessaging</span>::<span class="variable variable_other variable_other_constant variable_other_constant_ruby">MessageSender</span> observe <span class="variable variable_other variable_other_constant variable_other_constant_ruby">Customer</span></span><br />
<span class="source source_ruby source_ruby_rails"></span></p>
<pre><span class="source source_ruby source_ruby_rails">
 publishes_to <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer_queue</span>

 <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">after_create</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">customer</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>   payload = <span class="variable variable_other variable_other_constant variable_other_constant_ruby">YAML</span>.dump(<span class="support support_class support_class_ruby">CustomerPayload</span>.<span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">new</span>(<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>id</span> =&gt; customer.id, <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>name</span> =&gt; customer.name))   publish <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer_queue</span>, payload <span class="keyword keyword_control keyword_control_ruby">end</span><span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>To configure connection to the ActiveMQ server, I&#8217;ll need the following configuration files in both of my rails applications:</p>
<pre><span class="source source_ruby source_ruby_rails"><span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span>config/broker.yml</span>development:   adapter: stomp   login: <span class="string string_quoted string_quoted_double string_quoted_double_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">"</span><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">"</span></span>   passcode: <span class="string string_quoted string_quoted_double string_quoted_double_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">"</span><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">"</span></span>   host: localhost   port: <span class="constant constant_numeric constant_numeric_ruby">61613</span>   reliable: <span class="constant constant_language constant_language_ruby">false</span></span></pre>
<pre><span class="source source_ruby source_ruby_rails"><span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span>config/messaging.rb</span><span class="support support_class support_class_ruby">ActiveMessaging</span>::<span class="support support_class support_class_ruby">Gateway</span>.define <span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block">do </span>|s|  s.queue <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer_queue</span>, <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>/queue/Customer<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span><span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>And to get the observer to work, I&#8217;ll need this line in environment.rb</p>
<pre><span class="source source_ruby source_ruby_rails"><span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span> Activate observers that should always be running</span>config.active_record.observers = <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer_observer</span></span></pre>
<h4>Orders application</h4>
<p>For consuming messages, ActiveMessaging provides a directory under app called &#8216;processors&#8217;. In this directory of my Orders application I place my CustomerMessageProcessor:</p>
<pre><span class="source source_ruby source_ruby_rails"><span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span>customer_message_processor.rb</span><span class="meta meta_require meta_require_ruby"><span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">require</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>processors/application<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span></span><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">CustomerMessageProcessor<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby">&lt;</span> ApplicationProcessor</span></span></span>

 subscribes_to <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer_queue</span>

 <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">on_message</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">serialized_message</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>   customer_payload = <span class="variable variable_other variable_other_constant variable_other_constant_ruby">YAML</span>.load(serialized_message)   customer = <span class="support support_class support_class_ruby">Customer</span>.<span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">new</span>(<span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>name</span> =&gt; customer_payload.name)   customer.id = customer_payload.id   customer.save! <span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>This class will need access to the same CustomerPayload object as the Customers application for deserialization.</p>
<p>In ActiveMessaging, a poller is used to poll the queue and trigger the on_message method shown above. We&#8217;ll need to start the poller in the Orders application using the following command:</p>
<p>script/poller run</p>
<p>And that&#8217;s it. If both the Orders and Customer applications are running, and have access to the ActiveMQ server, then when we create a Customer in the Customer application, it should show up in the Orders application a few moments later.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/10/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/10/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/10/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=10&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/09/10/asynchronous-messaging-using-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>
	</item>
		<item>
		<title>file_column &#8211; Plugin</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/09/03/file_column-plugin/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/09/03/file_column-plugin/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 08:58:00 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[Ruby on rails - Plugins]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/09/03/file_column-plugin/</guid>
		<description><![CDATA[I’ve been using the file_column plugin for Ruby on Rails in the last days, so here’s some handy notes on the subject: Installing is pretty straightfoward, just like the majority of Rails plugins: script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk The first thing we need is to tell our model which column to use: class Blog Now, if we [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=9&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I’ve been using the <a href="http://www.kanthak.net/opensource/file_column/" title="file_column">file_column plugin for Ruby on Rails</a> in the last days, so here’s some handy notes on the subject:</p>
<p>Installing is pretty straightfoward, just like the majority of Rails plugins:</p>
<p>script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk</p>
<p>The first thing we need is to tell our model which column to use:</p>
<pre><code>class Blog </code></pre>
<p>Now, if we want to include a upload mechanism in our form, we need to include some code like this:</p>
<pre><code>

</code><a href="http://bp0.blogger.com/_-xsiT-HQLy4/Ru4osMrEhiI/AAAAAAAAALk/Vw12W7nPsvQ/s1600-h/picture-1.png"><img src="http://bp0.blogger.com/_-xsiT-HQLy4/Ru4osMrEhiI/AAAAAAAAALk/Vw12W7nPsvQ/s400/picture-1.png" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></pre>
<p>On our views, we can use the following to show our image:</p>
<p><code></code></p>
<p><a href="http://bp2.blogger.com/_-xsiT-HQLy4/Ru4ozsrEhjI/AAAAAAAAALs/o2-5mLeCCCo/s1600-h/picture-3.png"><img src="http://bp2.blogger.com/_-xsiT-HQLy4/Ru4ozsrEhjI/AAAAAAAAALs/o2-5mLeCCCo/s400/picture-3.png" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></p>
<p>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:</p>
<pre><code>class Blog </code></pre>
<pre><code> validates_file_format_of :image, :in =&gt; ["gif", "jpg"]validates_filesize_of :image, :in =&gt; 1.kilobytes..5000.kilobytesend</code></pre>
<p>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:</p>
<pre><code>class Blog </code></pre>
<pre><code>:store_dir =&gt; "public/images/my_stupid_place_to_keep_images_uploaded",:magick =&gt; {:versions =&gt; {       :thumb =&gt; {:crop =&gt; "1:1",  :size =&gt; "86x87!", :name =&gt; "peq"},       :normal =&gt; {:crop =&gt; "1:1", :size =&gt; "289x258!", :name=&gt;"med"}       }     }end</code><a href="http://bp2.blogger.com/_-xsiT-HQLy4/Ru4o8srEhkI/AAAAAAAAAL0/YMty1e1PTqk/s1600-h/picture-4.png"><img src="http://bp2.blogger.com/_-xsiT-HQLy4/Ru4o8srEhkI/AAAAAAAAAL0/YMty1e1PTqk/s400/picture-4.png" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></pre>
<p>So, by default  file_column will save images with the following scheme:</p>
<p><code></code>myApp/public/[Model name]/[file_column field name]/[record id]/[image filename]<code></code></p>
<p>but as I showed you, it’s possible to define a different storage directory in your model.</p>
<p>Now let’s access the smaller images we saved with RMagick, on our views:</p>
<p><code></code> or <code></code></p>
<p>Other interesting information,  you can access your image information in several ways:</p>
<p>&gt;&gt; p.image<br />
=&gt; “public/images/my_stupid_place_to_keep_images_uploaded/267/MyPicture.jpg”</p>
<p>&gt;&gt; p.image(”peq”)<br />
=&gt; “public/images/my_stupid_place_to_keep_images_uploaded/267/peq/MyPicture.jpg”</p>
<p>&gt;&gt; p.image_relative_path<br />
=&gt; “267/MyPicture.jpg”</p>
<p>&gt;&gt; p.image_relative_path(”peq”)<br />
=&gt; “267/peq/MyPicture.jpg”</p>
<p>&gt;&gt; File.basename(p.image)<br />
=&gt; “MyPicture.jpg”</p>
<p>More information on the subject:</p>
<ul>
<li><a href="http://wiki.rubyonrails.com/rails/pages/HowToUseFileColumn" title="wiki">File_column wiki</a></li>
<li><a href="http://www.webmasterlogs.com/uploading-files-and-images-with-rails-file_column-filecolumn-plugin/" title="upload">Uploading with File_column</a></li>
</ul>
<p>There’s other alternatives for uploading images and files but I felt file_column is a good and easy solution for most cases.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/9/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/9/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=9&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/09/03/file_column-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>

		<media:content url="http://bp0.blogger.com/_-xsiT-HQLy4/Ru4osMrEhiI/AAAAAAAAALk/Vw12W7nPsvQ/s400/picture-1.png" medium="image" />

		<media:content url="http://bp2.blogger.com/_-xsiT-HQLy4/Ru4ozsrEhjI/AAAAAAAAALs/o2-5mLeCCCo/s400/picture-3.png" medium="image" />

		<media:content url="http://bp2.blogger.com/_-xsiT-HQLy4/Ru4o8srEhkI/AAAAAAAAAL0/YMty1e1PTqk/s400/picture-4.png" medium="image" />
	</item>
		<item>
		<title>Plugins on rails</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/09/03/plugins-on-rails/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/09/03/plugins-on-rails/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 08:18:00 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[Ruby on rails - Plugins]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/09/03/plugins-on-rails/</guid>
		<description><![CDATA[Introduction A Rails plugin is either an extension or a modification of the core framework. Plugins provide: a way for developers to share bleeding-edge ideas without hurting the stable code base a segmented architecture so that units of code can be fixed or updated on their own release schedule an outlet for the core developers [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=8&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h1>Introduction</h1>
<p>A Rails <strong>plugin</strong> is either an extension or a modification of the core framework.  Plugins provide:</p>
<ul>
<li>a way for developers to share bleeding-edge ideas without hurting the stable code base</li>
<li>a segmented architecture so that units of code can be fixed or updated on their own release schedule</li>
<li>an outlet for the core developers so that they don’t have to include every cool new feature under the sun</li>
</ul>
<blockquote><p>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).</p></blockquote>
<h1>Further Reading</h1>
<ul>
<li><a href="http://wiki.rubyonrails.com/rails/pages/PluginsDiscussion" class="existingWikiWord">PluginsDiscussion</a></li>
<li><a href="http://wiki.rubyonrails.com/rails/pages/SomeImportantPluginNotes" class="existingWikiWord">SomeImportantPluginNotes</a> – Check your rails version before you start</li>
<li><a href="http://wiki.rubyonrails.com/rails/pages/PluginsForDummies" class="existingWikiWord">PluginsForDummies</a> <span class="newWikiWord"><a href="http://www.usome.com/">http://www.usome.com</a><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">?</a></span> shows the essential Ruby idea behind plugins.</li>
<li>Now there are some wiki tutorials on writing plugins <a href="http://wiki.rubyonrails.com/rails/pages/HowTosPlugins" class="existingWikiWord">HowTosPlugins</a></li>
<li>If you wrote some code or found it somewhere and you don’t know how to put it into <a href="http://wiki.rubyonrails.com/rails/pages/Plugins" class="existingWikiWord">Plugins</a> – <a href="http://wiki.rubyonrails.com/rails/pages/PluginRequests" class="existingWikiWord">PluginRequests</a></li>
</ul>
<h1>Plugin Documentation</h1>
<p>To find out how to use a newly installed plugin navigate to your project directory and issue the following command:</p>
<pre>rdoc --op doc/rdoc .</pre>
<p>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.</p>
<h1>Plugin Directory</h1>
<p>A <a href="http://www.agilewebdevelopment.com/plugins/">searchable plugin database</a><br />
and <a href="http://www.railslodge.com/">RailsLodge plugin directory</a> is also available.</p>
<h2>Plugin Repositories</h2>
<p>svn://rubyforge.org/var/svn/expressica/plugins/</p>
<p><a href="http://soen.ca/svn/projects/rails/plugins/">http://soen.ca/svn/projects/rails/plugins/</a></p>
<p><a href="http://technoweenie.stikipad.com/plugins/">http://technoweenie.stikipad.com/plugins/</a></p>
<p><a href="http://svn.techno-weenie.net/projects/plugins/">http://svn.techno-weenie.net/projects/plugins/</a></p>
<p><a href="http://svn.recentrambles.com/plugins/">http://svn.recentrambles.com/plugins/</a></p>
<p><a href="http://opensvn.csie.org/rails_file_column/plugins/">http://opensvn.csie.org/rails_file_column/plugins/</a></p>
<p><a href="http://svn.protocool.com/public/plugins/">http://svn.protocool.com/public/plugins/</a></p>
<p><a href="http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/">http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/</a></p>
<p><a href="http://svn.pragprog.com/Public/plugins/">http://svn.pragprog.com/Public/plugins/</a></p>
<p><a href="http://source.collectiveidea.com/public/rails/plugins/">http://source.collectiveidea.com/public/rails/plugins/</a></p>
<p><a href="https://secure.near-time.com/svn/plugins/">https://secure.near-time.com/svn/plugins/</a></p>
<p><a href="http://svn.inlet-media.de/svn/rails_extensions/plugins/">http://svn.inlet-media.de/svn/rails_extensions/plugins/</a></p>
<p><a href="http://svn.viney.net.nz/things/rails/plugins/">http://svn.viney.net.nz/things/rails/plugins/</a></p>
<p><a href="http://svn.hasmanythrough.com/public/plugins/">http://svn.hasmanythrough.com/public/plugins/</a></p>
<p><a href="http://svn.shiftnetwork.com/plugins/">http://svn.shiftnetwork.com/plugins/</a></p>
<p>svn://caboo.se/plugins/</p>
<p><a href="http://svn.6brand.com/projects/plugins/">http://svn.6brand.com/projects/plugins/</a></p>
<p><a href="http://shanesbrain.net/svn/rails/plugins/">http://shanesbrain.net/svn/rails/plugins/</a></p>
<p>svn://errtheblog.com/svn/plugins/</p>
<p><a href="http://svn.nkryptic.com/plugins/">http://svn.nkryptic.com/plugins/</a></p>
<p><a href="http://svn.thoughtbot.com/plugins/">http://svn.thoughtbot.com/plugins/</a></p>
<p><a href="http://svn.webwideconsulting.com/plugins/">http://svn.webwideconsulting.com/plugins/</a></p>
<p><a href="http://invisible.ch/svn/projects/plugins/">http://invisible.ch/svn/projects/plugins/</a></p>
<p>svn://rubyforge.org/var/svn/enum-column/plugins/</p>
<p><a href="http://streamlinedframework.org:8079/streamlined/plugins/">http://streamlinedframework.org:8079/streamlined/plugins/</a></p>
<p>svn://dvisionfactory.com/rails/plugins/</p>
<p><a href="http://hivelogic.com/plugins/">http://hivelogic.com/plugins/</a></p>
<p><a href="http://mattmccray.com/svn/rails/plugins/">http://mattmccray.com/svn/rails/plugins/</a></p>
<p>svn://rubyforge.org/var/svn/cartographer/plugins/</p>
<p><a href="http://www.svn.recentrambles.com/plugins/">http://www.svn.recentrambles.com/plugins/</a></p>
<p><a href="http://tanjero.com/svn/plugins/">http://tanjero.com/svn/plugins/</a></p>
<p><a href="http://filetofsole.org/svn/public/projects/rails/plugins/">http://filetofsole.org/svn/public/projects/rails/plugins/</a></p>
<p><a href="http://topfunky.net/svn/plugins/">http://topfunky.net/svn/plugins/</a></p>
<p><a href="http://svn.joshpeek.com/projects/plugins/">http://svn.joshpeek.com/projects/plugins/</a></p>
<p>svn://rubyforge.org/var/svn/agtools/plugins/</p>
<p><a href="http://svn.aviditybytes.com/rails/plugins/">http://svn.aviditybytes.com/rails/plugins/</a></p>
<p><a href="http://beautifulpixel.textdriven.com/svn/plugins/">http://beautifulpixel.textdriven.com/svn/plugins/</a></p>
<p><a href="http://mabs29.googlecode.com/svn/trunk/plugins/">http://mabs29.googlecode.com/svn/trunk/plugins/</a></p>
<p><a href="http://www.codyfauser.com/svn/projects/plugins/">http://www.codyfauser.com/svn/projects/plugins/</a></p>
<p><a href="http://craz8.com/svn/trunk/plugins/">http://craz8.com/svn/trunk/plugins/</a></p>
<p><a href="http://sean.treadway.info/svn/plugins/">http://sean.treadway.info/svn/plugins/</a></p>
<p><a href="http://svn.thebootstrapnation.com/public/plugins/">http://svn.thebootstrapnation.com/public/plugins/</a></p>
<p><a href="http://www.mattmccray.com/svn/rails/plugins/">http://www.mattmccray.com/svn/rails/plugins/</a></p>
<p>svn://rubyforge.org//var/svn/validaterequest/plugins/</p>
<p><a href="http://sprocket.slackworks.com/svn/rails/plugins/">http://sprocket.slackworks.com/svn/rails/plugins/</a></p>
<p><a href="http://svn.simpltry.com/plugins/">http://svn.simpltry.com/plugins/</a></p>
<p><a href="http://svn.elctech.com/svn/public/plugins/">http://svn.elctech.com/svn/public/plugins/</a></p>
<p><a href="http://xmlblog.stikipad.com/plugins/">http://xmlblog.stikipad.com/plugins/</a></p>
<p><a href="http://www.xml-blog.com/svn/plugins/">http://www.xml-blog.com/svn/plugins/</a></p>
<p><a href="http://svn.toolbocks.com/plugins/">http://svn.toolbocks.com/plugins/</a></p>
<p><a href="http://thar.be/svn/projects/plugins/">http://thar.be/svn/projects/plugins/</a></p>
<p><a href="http://code.teytek.com/rails/plugins/">http://code.teytek.com/rails/plugins/</a></p>
<p><a href="http://www.infused.org/svn/plugins/">http://www.infused.org/svn/plugins/</a></p>
<p>svn://rubyforge.org/var/svn/apptrain/trunk/vendor/plugins/</p>
<p><a href="http://s3cachestore.googlecode.com/svn/trunk/plugins/">http://s3cachestore.googlecode.com/svn/trunk/plugins/</a></p>
<p><a href="http://sbecker.net/shared/plugins/">http://sbecker.net/shared/plugins/</a></p>
<p><a href="http://opensvn.csie.org/macaque/plugins/">http://opensvn.csie.org/macaque/plugins/</a></p>
<p><a href="http://svn.designbyfront.com/rails/plugins/">http://svn.designbyfront.com/rails/plugins/</a></p>
<p><a href="//rails.bleedingtrends.com/">svn://rails.bleedingtrends.com/</a></p>
<p><a href="http://svn.rails-engines.org/plugins/">http://svn.rails-engines.org/plugins/</a></p>
<p><a href="http://dev.fiatdev.com/svn/plugins/">http://dev.fiatdev.com/svn/plugins/</a></p>
<p><a href="http://john.guen.in/svn/plugins/">http://john.guen.in/svn/plugins/</a></p>
<p><a href="http://www.redhillonrails.org/svn/trunk/vendor/plugins/">http://www.redhillonrails.org/svn/trunk/vendor/plugins/</a></p>
<p>svn://rubyforge.org/var/svn/actsdisjoint/plugins/</p>
<p><a href="http://ajaxmessaging.googlecode.com/svn/trunk/plugins/">http://ajaxmessaging.googlecode.com/svn/trunk/plugins/</a></p>
<p><a href="http://mod-i18n.googlecode.com/svn/trunk/plugins/">http://mod-i18n.googlecode.com/svn/trunk/plugins/</a></p>
<p>svn://majakari.net/public/rails/plugins/</p>
<p><a href="http://svn.lightyearsoftware.com/svn/plugins">http://svn.lightyearsoftware.com/svn/plugins</a></p>
<p><a href="http://svn.devjavu.com/malaysia-rb/plugins/">http://svn.devjavu.com/malaysia-rb/plugins/</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=8&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/09/03/plugins-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>
	</item>
		<item>
		<title>Rails using Captcha</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/09/03/rails-using-captcha/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/09/03/rails-using-captcha/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 06:56:00 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[Ruby on rails]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/09/03/rails-using-captcha/</guid>
		<description><![CDATA[SimpleCaptcha 1.0 &#8211; REVISION 14(updated) is a stable release. Please update your plugin, if you are still on previous revision. SimpleCaptcha is a plugin for rubyonrails applications to provide the captcha functionality. Its implementation is really simple, it requires a single line of code in view and a single line of code in controller/model. The [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=7&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>SimpleCaptcha 1.0 &#8211; REVISION 14(updated) is a stable release. Please update your plugin, if you are still on previous revision.</p>
<p>SimpleCaptcha is a plugin for rubyonrails applications to provide the captcha functionality.<br />
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 <a href="http://tore.darell.no/">Tore Darell’s</a> capthca plugin <a href="http://tore.darell.no/pages/validates_captcha">validates_captcha</a> (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.</p>
<h3>Features</h3>
<ul>
<li>Provides eight different style of images</li>
<li>Can be implemented as controller based or model based</li>
<li>Automated removal of old(validated and non-validated both) images.</li>
<li>Now, we can add customized CSS to the image, lable and the text field</li>
<li>Simple Captcha will bypass the functional/unit/integration tests, so that there will not be any mess in our test cases.</li>
<li>Provides three levels of distortion of images as low, medium or high… so now, we have three levels for complexities of images.</li>
</ul>
<p><strong>update_attribute is now working</strong> which was a bug in the <a href="http://expressica.com/2007/02/06/simple-captcha-released-the-captcha-for-rails-applications/"><strong>previous version</strong></a>, so please update your plugin by checking it out again from the SVN repository <strong>svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha</strong></p>
<h3>Pre-requisites</h3>
<p>1.) RMagick<br />
RMagick is the image handling library in ruby and is required to implement the SimpleCaptcha.<br />
RMagick is available on <a href="http://rubyforge.org/projects/rmagick/"><strong>RubyForge</strong></a></p>
<h3>Installation</h3>
<ul>
<li> (recommended… to sync with the latest revision.)<br />
SVN checkput the plugin as</p>
<p class="dp-highlighter nogutter">
<ol class="dp-rb">
<li class="alt"><span><span>&gt;&gt;svn co svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha simple_captcha  </span></span></li>
</ol>
<p><textarea name="code" cols="60" rows="10">&gt;&gt;svn co svn://rubyforge.org/var/svn/expressica/plugins/simple_captcha simple_captcha </textarea></li>
</ul>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/7/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/7/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=7&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/09/03/rails-using-captcha/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>
	</item>
		<item>
		<title>Ruby on Rails with Oracle</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/08/13/ruby-on-rails-with-oracle/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/08/13/ruby-on-rails-with-oracle/#comments</comments>
		<pubDate>Mon, 13 Aug 2007 06:22:00 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[Ruby on rails]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/08/13/ruby-on-rails-with-oracle/</guid>
		<description><![CDATA[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. Why Need for Oracle ? Every database has its own functionalities and unique speciality to handle [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=6&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p><span style="font-weight:bold;">Why Need for Oracle ?</span></p>
<p>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&#8217;s go !</p>
<p><span style="font-weight:bold;">Getting started</span></p>
<p>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.</p>
<p>Click the following link to get the driver oci<br />
<a href="http://rubyforge.org/projects/ruby-oci8"><span style="color:#3366ff;">http://rubyforge.org/projects/ruby-oci8/</span></a></p>
<p>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</p>
<p><span style="font-weight:bold;color:#006600;">c:\&gt; ruby ruby-oci8-1.0.0-rc3-mswin32.rb</span></p>
<p>The ruby-oci8-1.0.0-rc3-mswin32 is the downloaded file name. so make sure the file name is correct.<br />
<span style="font-weight:bold;"></span><br />
<span style="font-weight:bold;">Configuring oracle in rails :</span></p>
<p><span style="font-weight:bold;">                                  </span></p>
<p>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.)</p>
<pre><span style="font-weight:bold;color:#006600;">development:</span><span style="font-weight:bold;color:#006600;">adapter: oci</span><span style="font-weight:bold;color:#006600;">username: ruby</span><span style="font-weight:bold;color:#006600;">password: ruby</span><span style="font-weight:bold;color:#006600;">host: localhost</span></pre>
<p><span style="font-weight:bold;"><span style="font-weight:bold;"></span>                 </span>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.</p>
<p><span style="font-weight:bold;">Simple Application :<br />
</span><br />
I&#8217;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.</p>
<p>To create an application</p>
<p><span style="font-weight:bold;color:#006600;">$ rails product</span><br />
<span style="font-weight:bold;color:#006600;">$ cd product</span></p>
<p>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.</p>
<p><span style="font-weight:bold;color:#006600;">development:</span><br />
<span style="font-weight:bold;color:#006600;">adapter: oci</span><br />
<span style="font-weight:bold;color:#006600;">username: admin </span><br />
<span style="font-weight:bold;color:#006600;">password: admin</span><br />
<span style="font-weight:bold;color:#006600;">host: localhost</span></p>
<p><span style="font-weight:bold;">Migration :</span></p>
<p>Migration is a concept that a rails developer should come across before move ahead. Create a migration file products by</p>
<p><span style="font-weight:bold;color:#006600;">$ ruby script/generate migration products</span></p>
<p>It will create a migration file 001_product.rb  in the db\migrate path of the application.<br />
open the file and edit it as shown below</p>
<p><span style="font-weight:bold;color:#006600;">class Product<br />
<span style="font-weight:bold;color:#006600;">  def self.up</span><br />
<span style="font-weight:bold;color:#006600;">    create_table :products do |t|</span><br />
<span style="font-weight:bold;color:#006600;">      t.column :name, :string, :limit =&gt; 30</span><br />
<span style="font-weight:bold;color:#006600;">      t.column :description, :string</span><br />
<span style="font-weight:bold;color:#006600;">      t.column :price,  :integer, :null =&gt; false, :default =&gt; 0</span><br />
<span style="font-weight:bold;color:#006600;">    end  </span><br />
<span style="font-weight:bold;color:#006600;">  end</span></span></p>
<p><span style="font-weight:bold;color:#006600;">  def self.down</span><br />
<span style="font-weight:bold;color:#006600;">  end</span><br />
<span style="font-weight:bold;color:#006600;">end</span></p>
<p><span style="color:#000000;">      Type the following command to make use od the migration.</span><span style="font-weight:bold;color:#006600;"></span></p>
<p><span style="font-weight:bold;color:#006600;">$ rake db:migrate</span></p>
<p><span style="color:#000000;">       Now the data base is connected to rails and a tabel products is also created for our application.</span><span style="font-weight:bold;color:#006600;"></span></p>
<p><span style="color:#000000;"><span>Scaffolding :</span></span></p>
<p>The scaffolding is the basic simple concept to create a application easily. Execute the following command to create a scaffold</p>
<p><span style="color:#006600;">$ ruby script/generate scaffold product</span></p>
<p>It will create codes automatically for the add, edit and list of the products. To run the application start the server as<br />
<span style="font-weight:bold;color:#006600;"><br />
<span style="font-weight:bold;color:#006600;">$ ruby script/server</span></span></p>
<p><span style="color:#000000;">     That&#8217;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.</span><span style="font-weight:bold;color:#006600;"><br />
<a href="http://localhost:3000/products/list"><br />
<span style="color:#3333ff;">http://localhost:3000/products/list</span></a></span></p>
<p><span style="color:#000000;">Initially the table is empty and it likes to be</span><span style="font-weight:bold;color:#006600;"></span></p>
<p><a href="http://bp2.blogger.com/_-xsiT-HQLy4/RsAEr3itJzI/AAAAAAAAAH0/_SvC__ILjGM/s1600-h/empty.JPG"><img src="http://bp2.blogger.com/_-xsiT-HQLy4/RsAEr3itJzI/AAAAAAAAAH0/_SvC__ILjGM/s400/empty.JPG" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a><span style="color:#000000;"><br />
Products adding through the application is advisible than directly add it to the database. Once some products are added it might be shown as</span><span style="font-weight:bold;color:#006600;"></span></p>
<p><a href="http://bp1.blogger.com/_-xsiT-HQLy4/RsAFcnitJ0I/AAAAAAAAAH8/ts8PYtGpVcs/s1600-h/product.JPG"><img src="http://bp1.blogger.com/_-xsiT-HQLy4/RsAFcnitJ0I/AAAAAAAAAH8/ts8PYtGpVcs/s400/product.JPG" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a><br />
<span style="color:#000000;">The products shown here are all fake</span></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/6/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/6/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=6&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/08/13/ruby-on-rails-with-oracle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>

		<media:content url="http://bp2.blogger.com/_-xsiT-HQLy4/RsAEr3itJzI/AAAAAAAAAH0/_SvC__ILjGM/s400/empty.JPG" medium="image" />

		<media:content url="http://bp1.blogger.com/_-xsiT-HQLy4/RsAFcnitJ0I/AAAAAAAAAH8/ts8PYtGpVcs/s400/product.JPG" medium="image" />
	</item>
		<item>
		<title>Search Table Items in AJAX and Rails</title>
		<link>http://rubyonrailstricks.wordpress.com/2007/08/10/search-table-items-in-ajax-and-rails/</link>
		<comments>http://rubyonrailstricks.wordpress.com/2007/08/10/search-table-items-in-ajax-and-rails/#comments</comments>
		<pubDate>Fri, 10 Aug 2007 04:22:00 +0000</pubDate>
		<dc:creator>rubyonrailstricks</dc:creator>
				<category><![CDATA[Rails with AJAX]]></category>

		<guid isPermaLink="false">http://rubyonrailstricks.wordpress.com/2007/08/10/search-table-items-in-ajax-and-rails/</guid>
		<description><![CDATA[Introduction and warnings In this tutorial, we will try to use Ajax with Rails in order to display a table of items with several functionalities : pagination (split the table on several pages) sorting (table ordering by one of its column) searching (selecting items to be displayed with a query) A live demonstration of this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=5&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2> Introduction and warnings</h2>
<p><a title="intro" name="intro" id="intro"></a> In this tutorial, we will try to use Ajax with Rails in order to display a table of items with several functionalities :</p>
<ul>
<li><em>pagination</em> (split the table on several pages)</li>
<li><em>sorting</em> (table ordering by one of its column)</li>
<li><em>searching</em> (selecting items to be displayed with a query)</li>
</ul>
<p>A live demonstration of this application is available at :</p>
<p style="color:#3333ff;"><a href="http://dev.nozav.org/ajaxtable/">http://dev.nozav.org/ajaxtable/</a></p>
<p>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&#8217;t need to reload the entire page when the table changes. The interest of using Rails is&#8230; 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.</p>
<p>The code which follows is highly inspired from several <a href="http://wiki.rubyonrails.com/">Rails wiki</a> pages, in particular <a href="http://wiki.rubyonrails.com/rails/pages/How+to+make+a+real-time+search+box+with+the+Ajax+helpers">How to make a real-time search box with the Ajax helpers</a>, and <a href="http://wiki.rubyonrails.com/rails/pages/How+to+Paginate+With+Ajax">How to paginate with Ajax</a>. I just put things together and sometimes slightly adapted the code.</p>
<p>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.</p>
<h2><a title="sec2" name="sec2" id="sec2"></a> Application installation and configuration</h2>
<p class="first">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.</p>
<h3><a title="sec3" name="sec3" id="sec3"></a> Requirements</h3>
<p class="first">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 <code>sqlite</code>, but you can replace it by the one you prefer without any problem.</p>
<h3> Files</h3>
<p class="first">First, we have to create the &#8220;skeleton&#8221; of our application in the directory of our choice<sup><a href="http://dev.nozav.org/rails_ajax_table.html#fn.1" title="fnr.1" name="fnr.1">1</a></sup> :</p>
<pre style="font-weight:bold;color:#006600;">$ rails ajaxtable$ cd ajaxtable</pre>
<p>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 :</p>
<pre style="font-weight:bold;color:#006600;">$ ruby script/generate model Item$ ruby script/generate controller Item</pre>
<h3><a title="sec5" name="sec5" id="sec5"></a> Database</h3>
<p>Once we have the files, we have to setup a data source. For simplicity here we will use <code>Mysql</code> in conjunction with Rails schema. This means that we will describe our database inside Rails and let it manage database creation.</p>
<p>First, we have to update the development data source in <code>config/database.yml</code>. Enter ur database password in password  :</p>
<pre style="font-weight:bold;color:#006600;">development: adapter: mysql database: ajaxtable_development username: root password:</pre>
<p>Next, we will create the database by using Rails migration tools.</p>
<pre style="font-weight:bold;color:#006600;">$ ruby script/generate migration database_creation</pre>
<p>This should have created a <code>db/migrate/001_database_creation.rb</code> file in which we will define our database schema the following way :</p>
<pre style="font-weight:bold;color:#006600;"><a href="http://bp2.blogger.com/_-xsiT-HQLy4/Rrvv_HitJsI/AAAAAAAAAG8/NsbU9qkffKs/s1600-h/DatabaseCreation.JPG"><img src="http://bp2.blogger.com/_-xsiT-HQLy4/Rrvv_HitJsI/AAAAAAAAAG8/NsbU9qkffKs/s400/DatabaseCreation.JPG" style="float:left;cursor:pointer;margin:0 10px 10px 0;" border="0" /></a></pre>
<p>This just defines one table named <code>items</code> with three columns<sup><a href="http://dev.nozav.org/rails_ajax_table.html#fn.2" title="fnr.2" name="fnr.2">2</a></sup> : a string field called <code>name</code>, and two integer columns called <code>quantity</code> and <code>price</code> (nothing really original, yes&#8230;).</p>
<p>Then, we just have to do a :</p>
<pre style="font-weight:bold;color:#006600;">$ rake db:migrate</pre>
<p>U can also use the  following command but it shows some negotiable depreciation warnings.</p>
<pre style="font-weight:bold;color:#006600;">$ rake migrate</pre>
<p>And you should now have a <code>development.db</code> file in your <code>db</code> directory which is your <code>sqlite</code> database created by Rails with the <code>items</code> table inside.</p>
<h2> Creating the model</h2>
<p class="first">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.</p>
<p>The <em>model</em> of our application will be very simple here. In fact, as we don&#8217;t have any complex query to send to the database, it will stay the same as generated by Rails in our application installation, <em>ie</em> empty. So we will not touch the <code>app/models/item.rb</code> file.</p>
<p>Well, I hope this step has not been too difficult !</p>
<h2><a title="sec7" name="sec7" id="sec7"></a> Creating the view</h2>
<p class="first">The <em>view</em> of our application will be split into two components : a layout, a view and a partial.</p>
<h3><a title="sec8" name="sec8" id="sec8"></a> Layout</h3>
<p class="first">The <em>layout</em> 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&#8230;</p>
<p>Here, the layout will be located in <code>app/views/layouts/item.rhtml</code>, and will contain something like :</p>
<pre><a href="http://bp0.blogger.com/_-xsiT-HQLy4/RrvxTnitJtI/AAAAAAAAAHE/mZ9E7dkOyUU/s1600-h/itemrhtml.JPG"><img src="http://bp0.blogger.com/_-xsiT-HQLy4/RrvxTnitJtI/AAAAAAAAAHE/mZ9E7dkOyUU/s400/itemrhtml.JPG" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a><span style="font-size:130%;"><span style="font-weight:bold;color:#ff0000;">  </span><span style="font-weight:bold;color:#ff0000;">  </span></span></pre>
<p>An important thing here is the <code>javascript_include_tag</code> tag which will be replaced by the javascript libraries used by Rails to provide Ajax features.</p>
<p>Also note the <code>@content_for_layout</code> instruction, which will be replaced by the generated content when needed.</p>
<h3> View</h3>
<p class="first">The <em>view</em> component will be used to render a particular action of our controller, which we will describe immediately after this. As it is a <code>list</code> action of our <code>item</code> controller, the view will be located in <code>app/views/item/list.rhtml</code>.</p>
<p>The content of the file will be the following :</p>
<pre><span style="font-size:130%;"><span style="font-weight:bold;color:#ff0000;"><a href="http://bp3.blogger.com/_-xsiT-HQLy4/RrvxlXitJuI/AAAAAAAAAHM/W1-v85kUrp8/s1600-h/listrhtml.JPG"><img src="http://bp3.blogger.com/_-xsiT-HQLy4/RrvxlXitJuI/AAAAAAAAAHM/W1-v85kUrp8/s400/listrhtml.JPG" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a><span style="font-weight:bold;color:#ff0000;"></span>

</span></span></pre>
<p>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.</p>
<p>Then, we have an image element whose <code>id</code> is <code>spinner</code> 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 :</p>
<blockquote><p><a href="http://mentalized.net/activity-indicators/">http://mentalized.net/activity-indicators/</a></p></blockquote>
<p>You have to put the chosen image file in the <code>public/images</code> directory of your application.</p>
<p>The following <code>observe_field</code> instruction is a bit more unusual. What this instruction does here is to add a new Ajax <em>observer</em> on the <code>query</code> field. This observer will periodically (here, every 2 seconds, look at the <code>frequency</code> parameter) check the content of this field and will react if this content has changed.</p>
<p>The action to be taken is described by the remaining parameters :</p>
<ul>
<li><strong>update</strong> gives the id of the page element which will be updated. Here it is the <code>table</code> which encloses our partial call just a bit further in the code.</li>
<li><strong>url</strong> gives the action that will render the new HTML content to be inserted. Here the <code>list</code> action of our controller will handle every request.</li>
<li><strong>with</strong> indicates the way the field content will be passed to the <code>url</code> action. Here we will add a <code>query</code> parameter to our Ajax request with value equals to the content of the observed field.</li>
<li><strong>before</strong> indicates an action to be performed during the time the Ajax request is treated.</li>
<li><strong>success</strong> indicates an action to be performed when the Ajax request has been succesfully treated.</li>
</ul>
<p>The concrete effect of all this stuff is quite simple. When the user type something in the <code>query</code> field, the observer will detect the new content of the field, and then generate an Ajax request sent to the server with the <code>url</code> and <code>with</code> parameters. As soon as the request is sent, the <code>before</code> action toggles the visibility of the <code>spinner</code> XHTML element, and the user can see the image. When the request answer his received, the <code>table</code> XHTML element is updated, and the <code>success</code> action hides the spinner image again.</p>
<p>Just for information, here is what the <code>observe_field</code> function returns with the given parameters :</p>
<pre><span style="font-size:130%;"><span style="font-weight:bold;color:#ff0000;"></span><span style="font-weight:bold;color:#ff0000;">//&lt;![CDATA[</span><span style="font-weight:bold;color:#ff0000;">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})})</span><span style="font-weight:bold;color:#ff0000;">//]]&gt;</span><span style="font-weight:bold;color:#ff0000;"></span></span></pre>
<p>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.</p>
<p>And, to finish this view description, we have a call to a <em>partial</em> element called <code>items_list</code>. We will describe this concept and its content in detail after setting up our controller.</p>
<h2> Creating the controller</h2>
<p class="first">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.</p>
<p>Our <code>Item</code> controller will be very simple here, and will only include one action called <code>list</code>. We will not implement any other CRUD (Create, read, update, delete) action in this tutorial.</p>
<p>So here is the content of <code>app/controllers/item_controller.rb</code> :</p>
<p><a title="controller" name="controller" id="controller"></a></p>
<pre><a href="http://bp2.blogger.com/_-xsiT-HQLy4/RrvyOHitJwI/AAAAAAAAAHc/CRk5oJzl9kY/s1600-h/itemcontroller.JPG"><img src="http://bp2.blogger.com/_-xsiT-HQLy4/RrvyOHitJwI/AAAAAAAAAHc/CRk5oJzl9kY/s400/itemcontroller.JPG" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></pre>
<p>Let&#8217;s explain this a bit.</p>
<p>Our controller only defines one action, called <code>list</code>. This action will have to handle every request sent to our application.</p>
<p>First, we define a variable called <code>items_per_page</code> which will represent the number of lines our table will show on each page.</p>
<p>Next, we define another variable called <code>sort</code>, depending on the request parameter of the same name. The <code>case</code> can be used to mask the real fields name in our database, which can be more suitable for security reasons. The <code>reverse</code> string in the <code>sort</code> parameter indicates that sorting should be made in descending order.</p>
<p>Then, a <code>conditions</code> variable is constructed if a <code>query</code> 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 <code>name</code> field.</p>
<p>After that, we assign the total number of items in our database matching the <code>conditions</code> to the <code>@total</code> variable.</p>
<p>And eventually, we find a call to the Rails <code>paginate</code> instruction. We give to this instruction the model it should be associated to (<code>:items</code>), 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 <code>@items_pages</code> and the items for the current page number (this page number is passed as a <code>page</code> request parameter, which is transparent here). The paginator object will be used later to display pagination links.</p>
<p>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<sup><a href="http://dev.nozav.org/rails_ajax_table.html#fn.4" title="fnr.4" name="fnr.4">4</a></sup>.</p>
<p>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.</p>
<p>That is what the final part of our controller deals with : it tests if the request it has received is of type <code>xml_http_request</code><sup><a href="http://dev.nozav.org/rails_ajax_table.html#fn.5" title="fnr.5" name="fnr.5">5</a></sup>. In this case, it will not render the entire <code>list</code> view, but only a fragment of it, the now famous partial whose name is <code>items_list</code>.</p>
<p>So, as we can see, this <code>xml_http_request</code> test is the only &#8220;really Ajax&#8221; thing we met in the controller. That is because Ajax things are linked to the interface of our application, <em>ie</em> the view, and more specifically the part of it which will be managed with Ajax, <em>ie</em> the partial.</p>
<p>So, could you guess what we are going to do now ?</p>
<h2> Creating the partial</h2>
<p class="first">A <em>partial</em> 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 <em>Don&#8217;t Repeat Yourself</em> (DRY) Rails principle. But it is also really useful with Ajax.</p>
<p>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&#8217;s why we will separate all the elements which will have to be updated in a <em>partial</em> file<sup><a href="http://dev.nozav.org/rails_ajax_table.html#fn.6" title="fnr.6" name="fnr.6">6</a></sup>.</p>
<p>Partial filenames always begin with an underscore, so here our partial will be in <code>app/views/item/_items_list.rhtml</code>.</p>
<p>Its content will be the following :</p>
<pre><a href="http://bp3.blogger.com/_-xsiT-HQLy4/RrvzQXitJxI/AAAAAAAAAHk/zOWezvJ36C4/s1600-h/partial.JPG"><img src="http://bp3.blogger.com/_-xsiT-HQLy4/RrvzQXitJxI/AAAAAAAAAHk/zOWezvJ36C4/s400/partial.JPG" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a><span style="font-size:130%;"></span></pre>
<p>Some explanations may be needed here. The partial contains the table pagination and sorting management. We will see both in a more detailed way.</p>
<h3><a title="sec12" name="sec12" id="sec12"></a> Pagination helpers</h3>
<p class="first">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.</p>
<p>If we have more than one page of results, we clearly have to display <em>pagination links</em>. Rails already have methods to help dealing with them, but we will have to customize them a little. For this, we will create a <em>helper</em>.</p>
<p>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.</p>
<p>Our helpers will all be located in <code>app/helpers/item_helper.rb</code>. 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 <code>application_helper.rb</code>.</p>
<p>Well, enough blabla, here is the code of our <code>pagination_links_remote</code> helper :</p>
<p><a title="pagination_links_remote" name="pagination_links_remote" id="pagination_links_remote"></a></p>
<p><a href="http://bp3.blogger.com/_-xsiT-HQLy4/RrvzYXitJyI/AAAAAAAAAHs/TdyMNNVODM0/s1600-h/summa.JPG"><img src="http://bp3.blogger.com/_-xsiT-HQLy4/RrvzYXitJyI/AAAAAAAAAHs/TdyMNNVODM0/s400/summa.JPG" style="display:block;text-align:center;cursor:pointer;margin:0 auto 10px;" border="0" /></a></p>
<p>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.).</p>
<p>We then define a <code>page_options</code> hash which contains only one item called <code>window_size</code>. This is a parameter which tells Rails how many pages it has to show around the current one. For example, if <code>window_size</code> equals one, we will have something like :</p>
<blockquote>
<p class="quoted">1 &#8230; 5 6 7 &#8230; 13</p>
</blockquote>
<p>If <code>window_size</code> equals 2 :</p>
<blockquote>
<p class="quoted">1 &#8230; 4 5 6 7 8 &#8230; 13</p>
</blockquote>
<p>We could then make a call to the <code>pagination_links</code> function, which would generate the correct XHTML code for our links. But the problem is that it will generate &#8220;classic&#8221; XHTML links, but not the Ajax one. So we will have to redefine the links ourselves. This is done with the <code>pagination_links_each</code> method.</p>
<p>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 :</p>
<ul>
<li><strong>options</strong> are defined for the Ajax link generation. These are very similar to those defined in the <code>observe_field</code> element. The only new thing is the call to <code>@params.merge</code>, which will add the current request parameters to the link by replacing an existing page param by the page number in the block.</li>
<li><strong>html_options</strong> are just defined to generate the &#8220;classic&#8221; XHTML link, in order to let pagination work if javascript is not available.</li>
</ul>
<p>Then, there is just a call to the <code>link_to_remote</code> function, which will generate the complete XHTML for our link, including the javascript and the classic XHTML <code>href</code> part.</p>
<h3> Sorting helpers</h3>
<p class="first">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.</p>
<p>The first helper is nothing but necessary. It is called <code>sort_td_class_helper</code>, and his only goal is to add a <code>class="sortup"</code> if the column is currently the one used to sort the table, or a <code>class="sortdown"</code> 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.</p>
<p>The code is nothing interesting which is already shown in the figure  <code>pagination_links_remote</code> helper</p>
<p>Then, we have a second helper, called <code>sort_link_helper</code> which is also in that.</p>
<p>This helper is in fact very similar to the <code>pagination_links_remote</code> one, <a href="http://dev.nozav.org/rails_ajax_table.html#pagination_links_remote">seen above</a>. It takes two arguments :</p>
<ul>
<li><strong>text</strong>, which is just the text to be displayed as the column header and sort link</li>
<li><strong>param</strong>, which is the name of the request parameter associated with the column.</li>
</ul>
<p>The first two lines define a new variable, called <code>key</code>, which gets the value of the <code>param</code> argument, <em>ie</em> the sort key. The string <code>_reverse</code> is concatenated to it if <code>param</code> 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 <a href="http://dev.nozav.org/rails_ajax_table.html#controller">look at the controller</a> if you don&#8217;t find these explanations clear enough.</p>
<p>The rest of the helper is to define the options for the final call to the <code>link_to_remote</code> function. They are very similar to those of <code>pagination_links_remote</code> :</p>
<ul>
<li>the <strong>options</strong> hash, used for the javascript Ajax link, contains the <code>url</code> to be called to generate the new HTML, the id of the element to update, and two <code>before</code> and <code>success</code> actions to show/hide the spinner image.</li>
<li>the <strong>html_options</strong> hash, used for the HTML link. It generates the content of the <code>href</code> attribute with the <code>url_for</code> Rails function.</li>
</ul>
<h3> Table body</h3>
<p class="first">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 <code>cycle</code> Rails function, which will automatically and alternatively add a &#8220;odd&#8221; or &#8220;even&#8221; style class to our table rows, which can be very useful to display it in a more visible way.</p>
<h2> That&#8217;s all folks !</h2>
<p class="first">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 :</p>
<blockquote><p><a href="http://localhost:3000/item/list">http://localhost:3000/item/list</a></p></blockquote>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rubyonrailstricks.wordpress.com/5/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rubyonrailstricks.wordpress.com/5/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rubyonrailstricks.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rubyonrailstricks.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rubyonrailstricks.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rubyonrailstricks.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rubyonrailstricks.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rubyonrailstricks.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rubyonrailstricks.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rubyonrailstricks.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rubyonrailstricks.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rubyonrailstricks.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rubyonrailstricks.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rubyonrailstricks.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rubyonrailstricks.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rubyonrailstricks.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rubyonrailstricks.wordpress.com&amp;blog=1748499&amp;post=5&amp;subd=rubyonrailstricks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rubyonrailstricks.wordpress.com/2007/08/10/search-table-items-in-ajax-and-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5c32a9b9fda0f0719f948ca6b9d985e5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ramesh Pillai</media:title>
		</media:content>

		<media:content url="http://bp2.blogger.com/_-xsiT-HQLy4/Rrvv_HitJsI/AAAAAAAAAG8/NsbU9qkffKs/s400/DatabaseCreation.JPG" medium="image" />

		<media:content url="http://bp0.blogger.com/_-xsiT-HQLy4/RrvxTnitJtI/AAAAAAAAAHE/mZ9E7dkOyUU/s400/itemrhtml.JPG" medium="image" />

		<media:content url="http://bp3.blogger.com/_-xsiT-HQLy4/RrvxlXitJuI/AAAAAAAAAHM/W1-v85kUrp8/s400/listrhtml.JPG" medium="image" />

		<media:content url="http://bp2.blogger.com/_-xsiT-HQLy4/RrvyOHitJwI/AAAAAAAAAHc/CRk5oJzl9kY/s400/itemcontroller.JPG" medium="image" />

		<media:content url="http://bp3.blogger.com/_-xsiT-HQLy4/RrvzQXitJxI/AAAAAAAAAHk/zOWezvJ36C4/s400/partial.JPG" medium="image" />

		<media:content url="http://bp3.blogger.com/_-xsiT-HQLy4/RrvzYXitJyI/AAAAAAAAAHs/TdyMNNVODM0/s400/summa.JPG" medium="image" />
	</item>
	</channel>
</rss>
