<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>hemju</title> <link>http://hemju.com</link> <description /> <lastBuildDate>Sat, 21 Jan 2012 11:52:43 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/hemju" /><feedburner:info uri="hemju" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Face Recognition with Ruby</title><link>http://feedproxy.google.com/~r/hemju/~3/9KyeelKdSGI/</link> <comments>http://hemju.com/2011/03/14/face-recognition-with-ruby/#comments</comments> <pubDate>Mon, 14 Mar 2011 08:59:37 +0000</pubDate> <dc:creator>hemali</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[Face Recognition]]></category> <category><![CDATA[Ruby]]></category> <category><![CDATA[Tips]]></category><guid isPermaLink="false">http://hemju.com/?p=1643</guid> <description><![CDATA[We all know that we can search web pages for text, but there are services that go beyond a simple text search and use features like location and or image data. The hurdle relying on these features is that normally the end users have to enter manually the appropriate data. When was the last time [...] No related posts.]]></description> <content:encoded><![CDATA[<p>We all know that we can search web pages for text, but there are services that go beyond a simple text search and use features like location and or image data. The hurdle relying on these features is that normally the end users have to enter manually the appropriate data. When was the last time you tagged people Facebook? Now think what if we have a system that helps us to automate the process of face recognition. Lets understand face recognition and how you can use it with Ruby.</p><h3>What is Face Recognition?</h3><p><img src="http://www.face-rec.org/0snova/index-pic.jpg" alt="" /><br /> Face Recognition uses feature extraction from facial points (like detecting where the eyes, nose, mouth etc are) within images or videos to recognize people. As you can image such a task isn&#8217;t trivial and requires a lot of know how. But the good news are that facial recognition just got a lot easier for developers to include in their applications. <a href="http://face.com/">Face.com</a>, a company that specializes in facial recognition, opened its platform APIs, allowing developers to integrate its facial recognition technology in third-party websites and applications.</p><h4>Developers Get Facial  Recognition API from Face.com</h4><p>The face.com API uses REST-like interface. This means that all calls to   the API are made over the Internet, using <a href="http://en.wikipedia.org/wiki/HTTP_GET">HTTP GET</a> and POST   requests to the face.com <a href="http://api.face.com">API server</a>. Hence, any <a href="http://en.wikipedia.org/wiki/Programming_language">programming   language</a> that supports HTTP can be used to communicate with the service. <a href="http://face.com/">Face.com</a> has some <a href="http://developers.face.com/docs/api/download">common libraries</a> to get you started.</p><h3>How to use it with Ruby ?</h3><p>Step 1: Get your API Key from <a href="http://developers.face.com/account">http://developers.face.com/account</a>. Don&#8217;t forget to add Facebook API and Secret Key as well as Twitter API Key And Secret Key. Keep them handy to use in your application.</p><p>Step 2: To use Face Recogonition API in Ruby we have to install the gem called <strong>&#8216;<a href="https://github.com/rociiu/face">face</a>&#8216;</strong>.<br /> <strong>sudo gem install face</strong></p><p>Step 3: Now using api_key and api_secret, you can access get_client method of API.<br /> &gt;&gt; client = Face.get_client(:api_key =&gt; &#8216;your_api_key&#8217;, :api_secret =&gt; &#8216;your_api_secret&#8217;)</p><h4>Face Detection using Face gem in Ruby</h4><p>Face gem provides three different ways to detect faces in an image.</p><ol><li> Detect Faces with Urls</li><li> Detect Faces with Raw image data</li><li>Detect and Recognize faces with user auth</li></ol><p>Lets understand with examples.</p><p><strong>Detect Faces with Urls:</strong></p><p>Suppose we want to detect face in the image located at this <a href="http://babybathreviews.com/wp-content/uploads/2011/01/How-to-choose-a-baby-bath.png">url</a>. You will have to use faces_detect method as given below.<div id="gist-865770" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="o">&gt;&gt;</span><span class="n">client</span><span class="o">.</span><span class="n">faces_detect</span><span class="p">(</span><span class="ss">:urls</span> <span class="o">=&gt;</span> <span class="o">[</span><span class="s1">&#39;http://babybathreviews.com/wp-content/uploads/2011/01/How-to-choose-a-baby-bath.png&#39;</span><span class="o">]</span><span class="p">)</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/865770/aac3de0b7804946e61ce11eb7af5fda0d73b2628/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/865770#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/865770">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>It will return photo detection output in the following way. Notice that you here you get face related information in a JSON format.</p><div id="gist-865789" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>=&gt; {&quot;usage&quot;=&gt;{&quot;remaining&quot;=&gt;4998, &quot;used&quot;=&gt;2, &quot;reset_time_text&quot;=&gt;&quot;Fri, 04 Mar 2011 12:28:29 +0000&quot;, &quot;reset_time&quot;=&gt;1299241709, &quot;limit&quot;=&gt;5000}, &quot;photos&quot;=&gt;[{&quot;pid&quot;=&gt;&quot;F@1ef2734600dc723985bcd35f477b07d2_2c40d987c43374fb6e8c2a7d095d3260&quot;, &quot;url&quot;=&gt;&quot;http://babybathreviews.com/wp-content/uploads/2011/01/How-to-choose-a-baby-bath.png&quot;, &quot;tags&quot;=&gt;[{&quot;pitch&quot;=&gt;5.14, &quot;roll&quot;=&gt;7.08, &quot;mouth_left&quot;=&gt;{&quot;x&quot;=&gt;20.87, &quot;y&quot;=&gt;75.51}, &quot;tagger_id&quot;=&gt;nil, &quot;label&quot;=&gt;&quot;&quot;, &quot;eye_left&quot;=&gt;{&quot;x&quot;=&gt;21.62, &quot;y&quot;=&gt;34.37}, &quot;center&quot;=&gt;{&quot;x&quot;=&gt;41.65, &quot;y&quot;=&gt;56.8}, &quot;mouth_center&quot;=&gt;{&quot;x&quot;=&gt;29.86, &quot;y&quot;=&gt;77.53}, &quot;confirmed&quot;=&gt;false, &quot;gid&quot;=&gt;nil, &quot;threshold&quot;=&gt;nil, &quot;attributes&quot;=&gt;{&quot;glasses&quot;=&gt;{&quot;confidence&quot;=&gt;95, &quot;value&quot;=&gt;&quot;false&quot;}, &quot;gender&quot;=&gt;{&quot;confidence&quot;=&gt;15, &quot;value&quot;=&gt;&quot;male&quot;}, &quot;smiling&quot;=&gt;{&quot;confidence&quot;=&gt;83, &quot;value&quot;=&gt;&quot;false&quot;}, &quot;face&quot;=&gt;{&quot;confidence&quot;=&gt;75, &quot;value&quot;=&gt;&quot;true&quot;}}, &quot;yaw&quot;=&gt;-34.34, &quot;tid&quot;=&gt;&quot;TEMP_F@1ef2734600dc723985bcd35f477b07d2_2c40d987c43374fb6e8c2a7d095d3260_41.65_56.80_0_0&quot;, &quot;eye_right&quot;=&gt;{&quot;x&quot;=&gt;54.74, &quot;y&quot;=&gt;38.45}, &quot;uids&quot;=&gt;[], &quot;mouth_right&quot;=&gt;{&quot;x&quot;=&gt;42.46, &quot;y&quot;=&gt;78.29}, &quot;crop_jpeg&quot;=&gt;nil, &quot;ear_left&quot;=&gt;nil, &quot;height&quot;=&gt;86, &quot;ear_right&quot;=&gt;nil, &quot;nose&quot;=&gt;{&quot;x&quot;=&gt;25.61, &quot;y&quot;=&gt;56.81}, &quot;manual&quot;=&gt;false, &quot;recognizable&quot;=&gt;false, &quot;chin&quot;=&gt;nil, &quot;width&quot;=&gt;86.52}], &quot;height&quot;=&gt;500, &quot;width&quot;=&gt;497}], &quot;status&quot;=&gt;&quot;success&quot;}</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/865789/8b2bbfed8c563da810915520a8c6721bfec888b3/gistfile1.js" style="float:right;">view raw</a> <a href="https://gist.github.com/865789#file_gistfile1.js" style="float:right;margin-right:10px;color:#666">gistfile1.js</a> <a href="https://gist.github.com/865789">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Detect Faces with Raw image data:</strong></p><p>To detect faces from Raw image data, you will have to use following.</p><div id="gist-865790" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="o">&gt;&gt;</span> <span class="n">client</span><span class="o">.</span><span class="n">faces_detect</span><span class="p">(</span><span class="ss">:file</span> <span class="o">=&gt;</span> <span class="no">File</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;image.jpg&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">))</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/865790/bb8f39d9f147bc9a8eb964ec317bc7a3be3ed51c/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/865790#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/865790">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Detect and Recognize faces with user auth:</strong><br /><div id="gist-865791" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="o">&gt;&gt;</span> <span class="n">client</span><span class="o">.</span><span class="n">twitter_credentials</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">:twitter_username</span> <span class="o">=&gt;</span> <span class="s1">&#39;twitter_screen_name&#39;</span><span class="p">,</span> <span class="ss">:twitter_password</span> <span class="o">=&gt;</span> <span class="s1">&#39;twitter_password&#39;</span> <span class="p">}</span></div><div class='line' id='LC2'><span class="o">&gt;&gt;</span> <span class="n">client</span><span class="o">.</span><span class="n">faces_recognize</span><span class="p">(</span><span class="ss">:urls</span> <span class="o">=&gt;</span> <span class="o">[</span><span class="s1">&#39;http://test.com/1.jpg&#39;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:uids</span> <span class="o">=&gt;</span> <span class="o">[</span><span class="s1">&#39;uiicor&#39;</span><span class="o">]</span><span class="p">)</span> <span class="c1"># will make request with twitter credentials</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/865791/be44f27503e557de6cc21568c569b6ca8914dc6c/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/865791#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/865791">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Hereby we are trying to recognize face with twitter credentials.</p><p>First we will have to initialize twitter credentials like this:</p><div id="gist-865796" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="o">&gt;&gt;</span> <span class="n">client</span><span class="o">.</span><span class="n">twitter_credentials</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">:twitter_username</span> <span class="o">=&gt;</span> <span class="s1">&#39;twitter_screen_name&#39;</span><span class="p">,</span> <span class="ss">:twitter_password</span> <span class="o">=&gt;</span> <span class="s1">&#39;twitter_password&#39;</span> <span class="p">}</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/865796/a959c4d24e2b04d8feaea096646b29bfa9565688/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/865796#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/865796">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Step 2: To send the face recoginze request , write in the following way.</p><div id="gist-865799" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="c1"># will make request with twitter credentials</span></div><div class='line' id='LC2'><span class="o">&gt;&gt;</span> <span class="n">client</span><span class="o">.</span><span class="n">faces_recognize</span><span class="p">(</span><span class="ss">:urls</span> <span class="o">=&gt;</span> <span class="o">[</span><span class="s1">&#39;http://www.allfunnyfaces.com/pictures/Baby_Faces.jpg&#39;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:uid</span> <span class="o">=&gt;</span> <span class="o">[</span><span class="s1">&#39;uiicor&#39;</span><span class="o">]</span><span class="p">)</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/865799/7684b91524ce203fa6812315d7131d72edb98d80/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/865799#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/865799">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Note that uid is the id of the user on twitter.</p><h2>Conclusion</h2><p>The face gem provides facilty to detect faces from multi or single face images. Face gem is still under development. You can test it on face.com site. To get a feel for what is possible with the API you can browse some of   the <a href="http://developers.face.com/examples/">online examples</a>,   complete with source code, or play in the <a href="http://developers.face.com/tools/#faces/detect">API sandbox</a>.   The face.com API has some decent <a href="http://developers.face.com/docs/">documentation</a> for those   looking to dig deeper into the service, although the <a href="http://developers.face.com/forums/">forums</a> are fairly  quiet at the moment.</p><div class="shr-publisher-1643"></div><p>No related posts.</p><img src="http://feeds.feedburner.com/~r/hemju/~4/9KyeelKdSGI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/03/14/face-recognition-with-ruby/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://hemju.com/2011/03/14/face-recognition-with-ruby/</feedburner:origLink></item> <item><title>Rails: Cron Job Scheduling using Redis, Resque and Rufus</title><link>http://feedproxy.google.com/~r/hemju/~3/z08fONxs6KM/</link> <comments>http://hemju.com/2011/03/04/rails-cron-job-scheduling-using-redis-resque-and-rufus/#comments</comments> <pubDate>Fri, 04 Mar 2011 11:26:48 +0000</pubDate> <dc:creator>hemali</dc:creator> <category><![CDATA[development]]></category><guid isPermaLink="false">http://hemju.com/?p=1531</guid> <description><![CDATA[What is scheduling? In simple terms we can define scheduling as &#8220;the process of deciding how to commit resources between a variety of possible tasks&#8220;. The scheduling is basically a function which enables us to perform routine tasks at some predefined time or as part of a sequence. These tasks are normally executed in the [...] <b>Related posts:</b><ol><li><a href='http://hemju.com/2010/07/26/resque-jobs-automatisch-environment-und-lib-klassen-laden/' rel='bookmark' title='Resque Jobs automatically require Rails environment and Lib Classes'>Resque Jobs automatically require Rails environment and Lib Classes</a></li><li><a href='http://hemju.com/2009/10/08/adding-whenever-gem-to-rails-environment-caused-warning/' rel='bookmark' title='Adding &#8216;whenever&#8217; gem to Rails environment caused warning'>Adding &#8216;whenever&#8217; gem to Rails environment caused warning</a></li><li><a href='http://hemju.com/2010/07/22/rake-task-um-resque-worker-zu-beenden/' rel='bookmark' title='Rake task for quitting Resque workers'>Rake task for quitting Resque workers</a></li></ol>]]></description> <content:encoded><![CDATA[<h2>What is scheduling?</h2><p><img style="margin-right: 10px;" src="http://www.touch-couture.com/wp-content/uploads/2010/07/uboat-flightdeck-white-wristwatch-300x300.jpg" alt="Job Scheduler" align="left" />In simple terms we can define scheduling as &#8220;<strong>the process of deciding how to commit resources between a variety of possible tasks</strong>&#8220;. The scheduling is basically a function which enables us to perform routine tasks at some predefined time or as part of a sequence. These tasks are normally executed in the background by so called &#8220;workers&#8221;.</p><p>Now the question is what&#8217;s the best way to run scheduled tasks in a Rails environment? Generally, Rails developers can use an application specific crontab to run application tasks. “<strong>Cron</strong>” is a time-based job scheduler in Unix-like operating systems (Linux, FreeBSD, Mac OS etc…). And these jobs or tasks are referred to as “<strong>Cron Jobs</strong>”. Downsides of Cron are:</p><ul><li>Cron works well on a single server but what if you need to scale to multiple app servers? You’ll need to introduce some kind of lock to avoid concurrency problems. Also, you need to maintain these shared locks.</li><li>The other problem with Cron is that they are difficult to debug.</li><li>Cron is for scheduling things, not doing them.</li></ul><p>This can almost always be better to place jobs in queue and place the worker system to perform or to execute those jobs. Luckily there is a very good gem named &#8216;<a href="https://github.com/defunkt/resque">resque</a>&#8216; available in Ruby on Rails.</p><h2>Introduction to Resque</h2><p>Resque is a Redis-backed Ruby library for creating background jobs,  placing those jobs on multiple queues and processing them later. The main benefit withResque is that it allows you to create jobs and place them on a queue, then, later, pull those jobs off the queue and process them.</p><p>For the backstory, philosophy, and history of Resque&#8217;s beginnings, please see <a href="http://github.com/blog/542-introducing-resque">the blog post</a>. Besides that recently I came to know about other two plugins which are available in Ruby on Rails for job scheduling. <strong>One of them is <a href="https://github.com/bvandenbos/resque-scheduler">resque-scheduler</a> and the other is <a href="https://github.com/jmettraux/rufus-scheduler">rufus-scheduler</a>.</strong> Lets have a look at both both in detail.</p><h4>Resque Scheduler &#8211; A light-weight job scheduling system</h4><p>Resque Scheduler is an extension to Resque that provides both scheduled and delayed jobs. This service can replace cron and bring the ability to schedule task to execute at certain times. Resque Scheduler support job scheduling in two different ways: Recurring or Scheduled (a standard cron job) and Delayed.</p><h3>Recurring or Scheduled job</h3><p>A recurring/scheduled job is a task that is specified to be run at a certain time. For example you may want to update any indexes at midnight everyday; this is a scheduled job that runs based on a fixed schedule which is set at startup. The schedule is just a hash, but is most likely stored in a YAML.<br /> <strong>Delayed job</strong><br /> A delayed job is a job that gets put on the queue with a specified time in the future to run at. For example you may want to schedule a followup email to go out a few days after a user has signed up.</p><h4>How To use Resque-scheduler?</h4><p>First of all <strong>Install Resque Scheduler</strong>. Create sample application or you can get the sample application from the github.<br /><div id="gist-853347" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="err">$</span> <span class="n">rails</span> <span class="kp">new</span> <span class="n">rescue_jobs</span> <span class="o">-</span><span class="n">d</span> <span class="n">mysql</span></div><div class='line' id='LC2'><span class="err">$</span> <span class="n">cd</span> <span class="n">rescue_jobs</span><span class="o">/</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853347/7cbdb2f8ce752d4f86a8732eb321a3f54e941fca/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853347#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/853347">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Next step is to modify Gemfile to include<br /><div id="gist-853350" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="n">gem</span> <span class="s1">&#39;rails&#39;</span><span class="p">,</span> <span class="s1">&#39;3.0.3&#39;</span></div><div class='line' id='LC2'><span class="n">gem</span> <span class="s1">&#39;mysql2&#39;</span></div><div class='line' id='LC3'><span class="n">gem</span> <span class="s1">&#39;resque&#39;</span></div><div class='line' id='LC4'><span class="n">gem</span> <span class="s1">&#39;resque-scheduler&#39;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853350/9571a75692f31f853bb30918d5873dceacd36a5b/Gemfile.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853350#file_gemfile.rb" style="float:right;margin-right:10px;color:#666">Gemfile.rb</a> <a href="https://gist.github.com/853350">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Run $ bundle install. Now its time to <strong>Configure Resque Scheduler</strong>. In our sample we use a Redis service, of course you can use your own Redis Server as well. Go to <a href="http://redistogo.com/">Redis To Go</a> and sign up for the free plan. Once you have an instance, grab the URL given to you and modify the config/initializers/resque.rb as follows:<br /><div id="gist-853360" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">ENV</span><span class="o">[</span><span class="s2">&quot;REDISTOGO_URL&quot;</span><span class="o">]</span> <span class="o">||=</span> <span class="s2">&quot;redis://username:password@host:1234/&quot;</span></div><div class='line' id='LC2'><span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="no">ENV</span><span class="o">[</span><span class="s2">&quot;REDISTOGO_URL&quot;</span><span class="o">]</span><span class="p">)</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="no">Resque</span><span class="o">.</span><span class="n">redis</span> <span class="o">=</span> <span class="no">Redis</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:host</span> <span class="o">=&gt;</span> <span class="n">uri</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="ss">:port</span> <span class="o">=&gt;</span> <span class="n">uri</span><span class="o">.</span><span class="n">port</span><span class="p">,</span> <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">uri</span><span class="o">.</span><span class="n">password</span><span class="p">)</span></div><div class='line' id='LC5'><span class="nb">require</span> <span class="s1">&#39;resque_scheduler&#39;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853360/6bd66149f41e74ee9a5dcac65669858ad42872be/resque.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853360#file_resque.rb" style="float:right;margin-right:10px;color:#666">resque.rb</a> <a href="https://gist.github.com/853360">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Create a job named eat in app/jobs/eat.rb<br /><div id="gist-853368" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">module</span> <span class="nn">Eat</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="vi">@queue</span> <span class="o">=</span> <span class="ss">:food</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">perform</span><span class="p">(</span><span class="n">food</span><span class="p">)</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">puts</span> <span class="s2">&quot;Ate </span><span class="si">#{</span><span class="n">food</span><span class="si">}</span><span class="s2">!&quot;</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC6'><span class="k">end</span></div><div class='line' id='LC7'><br/></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853368/4ed1a7a7292a82afcfd411529f5d925f8b6437e6/app/jobs/eat.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853368#file_app/jobs/eat.rb" style="float:right;margin-right:10px;color:#666">app/jobs/eat.rb</a> <a href="https://gist.github.com/853368">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Inside config/initializers/resque.rb place the following code so that app/jobs/eat.rb is loaded.<br /><div id="gist-853372" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">Dir</span><span class="o">[</span><span class="s2">&quot;</span><span class="si">#{</span><span class="no">Rails</span><span class="o">.</span><span class="n">root</span><span class="si">}</span><span class="s2">/app/jobs/*.rb&quot;</span><span class="o">].</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span> <span class="nb">require</span> <span class="n">file</span> <span class="p">}</span></div><div class='line' id='LC2'><br/></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853372/46cd18afc8d08edb15c34d1276fd0dcfffd6b3fa/config/initializers/resque.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853372#file_config/initializers/resque.rb" style="float:right;margin-right:10px;color:#666">config/initializers/resque.rb</a> <a href="https://gist.github.com/853372">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Create controller file and add code<br /><div id="gist-853375" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">EatController</span> </div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="s2">&quot;Put </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:food</span><span class="o">]</span><span class="si">}</span><span class="s2"> in fridge to eat later.&quot;</span></div><div class='line' id='LC3'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853375/0d0fbe20f3275e40f66b8601965ba7e080a88240/EatController%20.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853375#file_eat_controller .rb" style="float:right;margin-right:10px;color:#666">EatController .rb</a> <a href="https://gist.github.com/853375">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Add following line in routes.rb file<br /><div id="gist-853377" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="n">match</span> <span class="s1">&#39;eat/:food&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;eat#food&#39;</span></div><div class='line' id='LC2'><br/></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853377/25d21517049be54d1fd2ff0bdfd53ad2ff199335/routes.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853377#file_routes.rb" style="float:right;margin-right:10px;color:#666">routes.rb</a> <a href="https://gist.github.com/853377">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>You also need to add file tasks/resque.rake<br /><div id="gist-853378" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="vg">$LOAD_PATH</span><span class="o">.</span><span class="n">unshift</span> <span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;/../lib&#39;</span></div><div class='line' id='LC2'><span class="nb">require</span> <span class="s1">&#39;resque_scheduler/tasks&#39;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853378/9e0df22f44051d758efd0c0c12bbdcb244428de6/tasks/resque.rake" style="float:right;">view raw</a> <a href="https://gist.github.com/853378#file_tasks/resque.rake" style="float:right;margin-right:10px;color:#666">tasks/resque.rake</a> <a href="https://gist.github.com/853378">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Finally create the crontab for Resque Scheduler. Create file config/resque_schedule.yml and insert the following text:<br /><div id="gist-853381" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="l-Scalar-Plain">breakfast</span><span class="p-Indicator">:</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="l-Scalar-Plain">cron</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">0 8 * * *</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="l-Scalar-Plain">class</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Eat</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="l-Scalar-Plain">args</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">scrambled egg</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Breakfast</span></div><div class='line' id='LC6'><span class="l-Scalar-Plain">lunch</span><span class="p-Indicator">:</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="l-Scalar-Plain">cron</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">0 12 * * *</span></div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="l-Scalar-Plain">class</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Eat</span></div><div class='line' id='LC9'>&nbsp;&nbsp;<span class="l-Scalar-Plain">args</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">penut-butter and jelly sandwich</span></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Lunch</span></div><div class='line' id='LC11'><span class="l-Scalar-Plain">dinner</span><span class="p-Indicator">:</span></div><div class='line' id='LC12'>&nbsp;&nbsp;<span class="l-Scalar-Plain">cron</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">0 6 * * *</span></div><div class='line' id='LC13'>&nbsp;&nbsp;<span class="l-Scalar-Plain">class</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Eat</span></div><div class='line' id='LC14'>&nbsp;&nbsp;<span class="l-Scalar-Plain">args</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Steak</span></div><div class='line' id='LC15'>&nbsp;&nbsp;<span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Dinner</span></div><div class='line' id='LC16'><span class="l-Scalar-Plain">midnight_snack</span><span class="p-Indicator">:</span></div><div class='line' id='LC17'>&nbsp;&nbsp;<span class="l-Scalar-Plain">cron</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">0 0 * * *</span></div><div class='line' id='LC18'>&nbsp;&nbsp;<span class="l-Scalar-Plain">class</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Eat</span></div><div class='line' id='LC19'>&nbsp;&nbsp;<span class="l-Scalar-Plain">args</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Milk &amp; Cookies</span></div><div class='line' id='LC20'>&nbsp;&nbsp;<span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">Midnight Snack</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853381/89ca3f833a2bc257fc525a3c0e389522d0f5c756/config/resque_schedule.yml" style="float:right;">view raw</a> <a href="https://gist.github.com/853381#file_config/resque_schedule.yml" style="float:right;margin-right:10px;color:#666">config/resque_schedule.yml</a> <a href="https://gist.github.com/853381">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>To load the schedule when we initialize Resque add the following line to config/initializers/resque.rb<br /><div id="gist-853385" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">Resque</span><span class="o">.</span><span class="n">schedule</span> <span class="o">=</span> <span class="no">YAML</span><span class="o">.</span><span class="n">load_file</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">#{</span><span class="no">Rails</span><span class="o">.</span><span class="n">root</span><span class="si">}</span><span class="s2">/config/resque_schedule.yml&quot;</span><span class="p">)</span></div><div class='line' id='LC2'><br/></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853385/5ebd906ec558e834c3c0999daaea6ca6a1bee15d/config/initializers/resque.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853385#file_config/initializers/resque.rb" style="float:right;margin-right:10px;color:#666">config/initializers/resque.rb</a> <a href="https://gist.github.com/853385">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>At the end <strong>Start the Scheduler Process</strong><br /><div id="gist-853392" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="err">$</span> <span class="n">rake</span> <span class="n">resque</span><span class="ss">:scheduler</span></div><div class='line' id='LC2'><br/></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/853392/751740cc9613a31c6f022b02fd979abb039f3b4a/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/853392#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/853392">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><h3>Rufus Scheduler &#8211; scheduler for Ruby (at, in, cron and every jobs)</h3><p>Rufus-Scheduler  is the latest version of a scheduler previously known as openwferu-scheduler. It is a Ruby gem for scheduling pieces of code (jobs). Rufus-Scheduler understands running a job AT a certain time, IN a certain time, EVERY x time or simply via a CRON statement. But we must note that rufus-scheduler is no replacement for cron since it runs inside of Ruby. The scheduler doesn&#8217;t do any server-side tasks to get jobs to run, but relies on its scheduler being run up and maintained persistently (or semi-persistently, as with Rails app processes that will tip the scheduler into action).</p><p>It doesn&#8217;t require any database table, queueing mechanism, or separate process to manage.  Just a simple scheduler to call out to your existing ruby code. No need to register at anything. You have to include only one file in config/initializers and add the task you want to schedule. Whenever you start your server that tasks are done or performed at specific time. So ultimately it saves the time of queuing and you get the work done.</p><h4>How To use Rufus-Scheduler?</h4><p>First of all create a sample application.<br /> rails new sample_app</p><p>Then add rufus_scheduler in Gemfile<br /> gem &#8216;rufus-scheduler&#8217;</p><p>Install the gem with bundle<br /> $ bundle install.</p><p>Add following lines in config/initializers/task_scheduler.rb<br /><div id="gist-854252" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="err">‘</span><span class="n">rubygems</span><span class="err">’</span></div><div class='line' id='LC2'><span class="nb">require</span> <span class="err">‘</span><span class="n">rufus</span><span class="o">/</span><span class="n">scheduler</span><span class="err">’</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="c1">## to start scheduler</span></div><div class='line' id='LC5'><span class="n">scheduler</span> <span class="o">=</span> <span class="no">Rufus</span><span class="o">::</span><span class="no">Scheduler</span><span class="o">.</span><span class="n">start_new</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="c1">## It will print message every i minute</span></div><div class='line' id='LC8'><span class="n">scheduler</span><span class="o">.</span><span class="n">every</span><span class="p">(</span><span class="s2">&quot;1m&quot;</span><span class="p">)</span> <span class="k">do</span></div><div class='line' id='LC9'>&nbsp;&nbsp;<span class="nb">puts</span><span class="p">(</span><span class="s2">&quot;HELLO </span><span class="si">#{</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span></div><div class='line' id='LC10'><span class="k">end</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'><span class="c1">## Prints the message every day at noon</span></div><div class='line' id='LC13'><span class="n">scheduler</span><span class="o">.</span><span class="n">cron</span><span class="p">(</span><span class="s2">&quot;0,2 * * * *&quot;</span><span class="p">)</span> <span class="k">do</span></div><div class='line' id='LC14'>&nbsp;&nbsp;<span class="nb">puts</span><span class="p">(</span><span class="s2">&quot;HI </span><span class="si">#{</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span></div><div class='line' id='LC15'><span class="k">end</span></div><div class='line' id='LC16'><br/></div><div class='line' id='LC17'><span class="n">scheduler</span><span class="o">.</span><span class="n">in</span> <span class="s1">&#39;20m&#39;</span> <span class="k">do</span></div><div class='line' id='LC18'>&nbsp;&nbsp;<span class="nb">puts</span> <span class="s2">&quot;order butter&quot;</span></div><div class='line' id='LC19'><span class="k">end</span></div><div class='line' id='LC20'><br/></div><div class='line' id='LC21'><span class="n">scheduler</span><span class="o">.</span><span class="n">at</span> <span class="s1">&#39;Thu Mar 26 07:31:43 +0900 2009&#39;</span> <span class="k">do</span></div><div class='line' id='LC22'>&nbsp;&nbsp;<span class="nb">puts</span> <span class="s1">&#39;order pizza&#39;</span></div><div class='line' id='LC23'><span class="k">end</span></div><div class='line' id='LC24'><br/></div><div class='line' id='LC25'><span class="n">scheduler</span><span class="o">.</span><span class="n">cron</span> <span class="s1">&#39;0 22 * * 1-5&#39;</span> <span class="k">do</span></div><div class='line' id='LC26'>&nbsp;&nbsp;<span class="c1"># every day of the week at 22:00 (10pm)</span></div><div class='line' id='LC27'>&nbsp;&nbsp;<span class="nb">puts</span> <span class="s1">&#39;activate security system&#39;</span></div><div class='line' id='LC28'><span class="k">end</span></div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'><span class="n">scheduler</span><span class="o">.</span><span class="n">every</span> <span class="s1">&#39;5m&#39;</span> <span class="k">do</span></div><div class='line' id='LC31'>&nbsp;&nbsp;<span class="nb">puts</span> <span class="s1">&#39;check status report&#39;</span></div><div class='line' id='LC32'><span class="k">end</span></div><div class='line' id='LC33'><br/></div><div class='line' id='LC34'><br/></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/854252/5e1d39ae3346baaa8eb79d42cd345a744d815479/task_scheduler.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/854252#file_task_scheduler.rb" style="float:right;margin-right:10px;color:#666">task_scheduler.rb</a> <a href="https://gist.github.com/854252">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>You can also test above code on console.</p><h3>Conclusion</h3><p>Rescue Scheduler offers a simple and easy way to add scheduling abilities to any queueing system and is well worth the move from cron. But if you do&#8217;t want queuing and want only some scheduled jobs than rufus-scheduler is the best option.</p><div class="shr-publisher-1531"></div><p><b>Related posts:</b><ol><li><a href='http://hemju.com/2010/07/26/resque-jobs-automatisch-environment-und-lib-klassen-laden/' rel='bookmark' title='Resque Jobs automatically require Rails environment and Lib Classes'>Resque Jobs automatically require Rails environment and Lib Classes</a></li><li><a href='http://hemju.com/2009/10/08/adding-whenever-gem-to-rails-environment-caused-warning/' rel='bookmark' title='Adding &#8216;whenever&#8217; gem to Rails environment caused warning'>Adding &#8216;whenever&#8217; gem to Rails environment caused warning</a></li><li><a href='http://hemju.com/2010/07/22/rake-task-um-resque-worker-zu-beenden/' rel='bookmark' title='Rake task for quitting Resque workers'>Rake task for quitting Resque workers</a></li></ol></p><img src="http://feeds.feedburner.com/~r/hemju/~4/z08fONxs6KM" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/03/04/rails-cron-job-scheduling-using-redis-resque-and-rufus/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://hemju.com/2011/03/04/rails-cron-job-scheduling-using-redis-resque-and-rufus/</feedburner:origLink></item> <item><title>Rails 3.1 release, rumors and news about features</title><link>http://feedproxy.google.com/~r/hemju/~3/7DTjVIAHxIA/</link> <comments>http://hemju.com/2011/02/23/rails-3-1-release-rumors-and-news-about-features/#comments</comments> <pubDate>Wed, 23 Feb 2011 15:18:33 +0000</pubDate> <dc:creator>hemali</dc:creator> <category><![CDATA[development]]></category><guid isPermaLink="false">http://hemju.com/?p=1473</guid> <description><![CDATA[What is the current status of  Ruby on Rails 3.1? We all know that there isn&#8217;t a fixed roadmap/release date for Ruby on Rails 3.1, but there are definitely rumors about the new features and improvements. Yehuda Katz, a member of the Ruby on Rails core team, said &#8220;With 3.1 we&#8217;ll go back to basics [...] No related posts.]]></description> <content:encoded><![CDATA[<p><strong>What is the current status of  Ruby on Rails 3.1?</strong></p><p>We all know that there isn&#8217;t a fixed roadmap/release date for Ruby on Rails 3.1, but there are definitely rumors about the new features and improvements. Yehuda Katz, a member of the Ruby on Rails core team, said &#8220;With 3.1 we&#8217;ll go back to basics and look at things that are less invasive internally, but could have a big impact on developers. If you want to check latest updates then <a href="https://rails.lighthouseapp.com/projects/8994/milestones/71470-31">click here</a> and check milestones for Rails 3.1. It&#8217;s really a good news that just 26 tickets are remaining out of 68 total tickets.</p><p>Lets talk about new <strong>features</strong> which will be integrated with RoR 3.1.</p><h1><span style="font-size: medium;">Object Scopes in Rails 3.1</span></h1><p>The change that is made to object scope is :</p><div id="gist-840395" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="o">-</span> <span class="n">options</span> <span class="o">=</span> <span class="n">scope_options</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Proc</span><span class="p">)</span> <span class="p">?</span> <span class="n">scope_options</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="p">:</span> <span class="n">scope_options</span></div><div class='line' id='LC2'><span class="o">+</span> <span class="n">options</span> <span class="o">=</span> <span class="n">scope_options</span><span class="o">.</span><span class="n">respond_to?</span><span class="p">(</span><span class="ss">:call</span><span class="p">)</span> <span class="p">?</span> <span class="n">scope_options</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="p">:</span> <span class="n">scope_options</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/840395/68da8f82d8f2035750e17c9c37cc933a2aa8fcd3/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/840395#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/840395">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>The above code describes that with Rails 3.1 it is possible to pass objects to scope methods that responds to the method &#8216;call&#8217;. Let&#8217;s understand what it means. Currently, with Rails 3 or Rails 3.0.x, scope works in the following way. For example, if we want to get all the products with name &#8220;Nokia&#8221; and with category &#8220;Mobile&#8221;, we used to create its scope method as given below.</p><div id="gist-840404" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Product</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:nokia</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">where</span><span class="p">(</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;Nokia&#39;</span><span class="p">)</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:category</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">value</span><span class="o">|</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">where</span><span class="p">(</span><span class="ss">:category</span> <span class="o">=&gt;</span> <span class="n">value</span><span class="p">)</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:combined</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="o">|</span><span class="n">value</span><span class="o">|</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">nokia</span><span class="o">.</span><span class="n">category</span><span class="p">(</span><span class="n">value</span><span class="p">)</span></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC11'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/840404/a03d556f4532964585699f08f91ac7806a7c3a1c/Product.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/840404#file_product.rb" style="float:right;margin-right:10px;color:#666">Product.rb</a> <a href="https://gist.github.com/840404">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Now to get required data, we use it like</p><div id="gist-840405" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>$ @nokia = Product.nokia.all # to get all the products with name Nokia</div><div class='line' id='LC2'>$ Product.category(&quot;Mobile&quot;).all # to get all the products with category Mobile</div><div class='line' id='LC3'>$ Product.nokia.category(&quot;Mobile&quot;).all #Combined : to get all the products with name = Nokia and category = Mobile.</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/840405/085105f5509fa5cc3bc9905a5230b3ee4f07b877/gistfile1.txt" style="float:right;">view raw</a> <a href="https://gist.github.com/840405#file_gistfile1.txt" style="float:right;margin-right:10px;color:#666">gistfile1.txt</a> <a href="https://gist.github.com/840405">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>But what if we have multiple classes that share the same logic for a named scope?? Suppose we want to get all the users with name = &#8220;John&#8221; and category = &#8220;Manager&#8221;. Think for a moment. In such cases it is obvious that we should be able to reuse same filter/scope code. Luckily, RoR 3.1 will provide exactly that kind of reusability. It will be possible to create classes that acts as scopes/filters.</p><p>In Rails 3.1, scope will be reused in other modules like this:</p><div id="gist-840410" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Filter</span> <span class="o">&lt;</span> <span class="no">Struct</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:klass</span><span class="p">)</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">);</span> <span class="k">end</span></div><div class='line' id='LC3'><span class="k">end</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="k">module</span> <span class="nn">NameFilter</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">klass</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="n">args</span><span class="o">.</span><span class="n">shift</span><span class="p">)</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">super</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span></div><div class='line' id='LC9'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC10'><span class="k">end</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'><span class="k">module</span> <span class="nn">CategoryFilter</span></div><div class='line' id='LC13'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="n">category</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">klass</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="ss">:category</span> <span class="o">=&gt;</span> <span class="n">args</span><span class="o">.</span><span class="n">shift</span><span class="p">)</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">super</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span></div><div class='line' id='LC16'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC17'><span class="k">end</span></div><div class='line' id='LC18'><br/></div><div class='line' id='LC19'><span class="k">class</span> <span class="nc">Product</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span></div><div class='line' id='LC20'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:combined</span><span class="p">,</span> <span class="no">Filter</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">CategoryFilter</span><span class="p">)</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">NameFilter</span><span class="p">)</span></div><div class='line' id='LC21'><span class="k">end</span></div><div class='line' id='LC22'><br/></div><div class='line' id='LC23'><span class="k">class</span> <span class="nc">User</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span></div><div class='line' id='LC24'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:combined</span><span class="p">,</span> <span class="no">Filter</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">CategoryFilter</span><span class="p">)</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">NameFilter</span><span class="p">)</span></div><div class='line' id='LC25'><span class="k">end</span></div><div class='line' id='LC26'><br/></div><div class='line' id='LC27'><span class="no">Product</span><span class="o">.</span><span class="n">combined</span><span class="p">(</span><span class="s1">&#39;Nokia&#39;</span><span class="p">,</span><span class="s1">&#39;Mobile&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">all</span></div><div class='line' id='LC28'><span class="no">User</span><span class="o">.</span><span class="n">combined</span><span class="p">(</span><span class="s1">&#39;John&#39;</span><span class="p">,</span><span class="s1">&#39;Manager&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">all</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/840410/b00c12ed956a162dd675ecce85c55186164ec918/Models.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/840410#file_models.rb" style="float:right;margin-right:10px;color:#666">Models.rb</a> <a href="https://gist.github.com/840410">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Its simply great !! Changing a simple is_a? to a respond_to? can unlock quite a power.</p><h1><span style="font-size: medium;">Automatic Flushing</span></h1><p>The Rails 3.1 will have new feature named “Auto Flushing” which helps to boost the performance of Ruby on Rails application. Normally whenever we are downloading any page, there is a two step process: first, all the code gets compiled to generate html view and second, all necessary files like css, javascripts, images are being loaded one by one.</p><p>As you’ve probably seen, DHH announced that they try to add flushing in Rails 3.1 to improve the client-side performance of a typical Rails applications. The most obvious solution, and one that already exists in plugin form, is to allow a layout to have a new flush method, which would immediately flush the contents of the layout to the browser. By putting the flush method below the JavaScript and CSS includes, the browser could begin downloading and evaluating those static assets while the server continues building the page. For more information regarding this feature, you can <a href="http://hemju.com/2010/09/08/how-rails-3-1-will-speed-up-your-application-with-automatic-flushing/">check here</a> .</p><h1><span style="font-size: medium;">Rails 3.1 &gt; Integration of Spriting</span></h1><p>One thing DHH mentioned in his keynote was that Rails 3.1 should improve the way Rails handles JavaScript, Style Sheets, icons and images. Rails 3.1 will support a technique called Sprite Generation which is basically a method for combining many graphics into a single image. That single image will be then displayed using CSS.</p><p>&lt;% sprite_css(“icons”) %&gt; this code does two things. First is to combine all the images within a single folder and second is to generating its CSS. The advantage of using such technique is to reduce dozens of HTTP requests into one cache-friendly image file.</p><h1><span style="font-size: medium;">Keep js/css close to the code in view folder</span></h1><p>Guess  what !! With Rails on Rails 3.1, we will be able to write the code for stylesheets and javascripts in the  app/ *  folder like this :<br /><div id="gist-840416" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="c1">#Preprocess:</span></div><div class='line' id='LC2'><span class="n">app</span><span class="o">/</span><span class="n">views</span><span class="o">/</span><span class="n">js</span><span class="o">/</span><span class="n">item</span><span class="o">.</span><span class="n">js</span><span class="o">.</span><span class="n">erb</span></div><div class='line' id='LC3'><span class="n">app</span><span class="o">/</span><span class="n">views</span><span class="o">/</span><span class="n">css</span><span class="o">/</span><span class="n">style</span><span class="o">.</span><span class="n">css</span><span class="o">.</span><span class="n">erb</span></div><div class='line' id='LC4'><span class="c1">#This code will be compiled to the files like this:</span></div><div class='line' id='LC5'><span class="c1">#Compiles:</span></div><div class='line' id='LC6'><span class="kp">public</span><span class="o">/</span><span class="n">application</span><span class="o">.</span><span class="n">js</span></div><div class='line' id='LC7'><span class="kp">public</span><span class="o">/</span><span class="n">style</span><span class="o">.</span><span class="n">css</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/840416/b0fb3541a7d420a955122ff835d4d15780bd3684/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/840416#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/840416">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>The advantage of using the above feature is that after compilation of these files, your Ruby on Rails application will run on single CSS and javascript file which is neatly compressed without any kind of extra efforts.</p><h1><span style="font-size: medium;">What is going to be deprecated in Rails 3.1??</span></h1><p>Passing options hash containing :conditions, :include, :joins, :limit, : offset, : order, :select, :readonly, :group, :having, :from, :lock etc inshort, finder methods which are provided by any ActiveRecord class will now be deprecated in Rails 3.1.</p><p>We used to write finder methods in this way</p><div id="gist-840420" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">User</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:conditions</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;David&#39;</span> <span class="p">}</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:age</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span><span class="o">|</span><span class="n">age</span><span class="o">|</span> <span class="p">{</span><span class="ss">:conditions</span> <span class="o">=&gt;</span> <span class="o">[</span><span class="s2">&quot;age &gt; ?&quot;</span><span class="p">,</span> <span class="n">age</span><span class="o">]</span> <span class="p">}}</span></div><div class='line' id='LC4'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/840420/bfc027c1b0b11698d86ea9973122412dc1fa2656/User.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/840420#file_user.rb" style="float:right;margin-right:10px;color:#666">User.rb</a> <a href="https://gist.github.com/840420">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>In RoR 3.1 it will be :</p><div id="gist-840422" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">User</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:name</span><span class="p">,</span> <span class="n">where</span><span class="p">(</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;David&#39;</span><span class="p">)</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="n">scope</span> <span class="ss">:age</span><span class="p">,</span> <span class="nb">lambda</span> <span class="p">{</span><span class="o">|</span><span class="n">age</span><span class="o">|</span> <span class="n">where</span><span class="p">(</span><span class="s2">&quot;age &gt; ?&quot;</span><span class="p">,</span> <span class="n">age</span><span class="p">)</span> <span class="p">}</span></div><div class='line' id='LC4'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/840422/cb1315dc82ba698c545ba85d5aaaf1397ea9476b/User.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/840422#file_user.rb" style="float:right;margin-right:10px;color:#666">User.rb</a> <a href="https://gist.github.com/840422">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>For more information you can <a href="http://m.onkey.org/active-record-query-interface">check here</a>.</p><p>From the above news about Rails 3.1 features, we can feel that Rails 3.1 will be another great release. Any guesses when we will see 3.1?</p><div class="shr-publisher-1473"></div><p>No related posts.</p><img src="http://feeds.feedburner.com/~r/hemju/~4/7DTjVIAHxIA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/02/23/rails-3-1-release-rumors-and-news-about-features/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://hemju.com/2011/02/23/rails-3-1-release-rumors-and-news-about-features/</feedburner:origLink></item> <item><title>Quicktip: Finding deprecated constants/methods easily</title><link>http://feedproxy.google.com/~r/hemju/~3/HXd0oJdV3D8/</link> <comments>http://hemju.com/2011/02/21/quicktip-finding-deprecated-constantsmethods-easily/#comments</comments> <pubDate>Mon, 21 Feb 2011 06:43:47 +0000</pubDate> <dc:creator>Helmut M. Juskewycz</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[Development]]></category> <category><![CDATA[Quicktip]]></category> <category><![CDATA[Rails]]></category> <category><![CDATA[Rails3]]></category> <category><![CDATA[ruby on rails]]></category> <category><![CDATA[Tips]]></category><guid isPermaLink="false">http://hemju.com/?p=1469</guid> <description><![CDATA[In Rails 3 a couple of constants/methods were set deprecated. However, there are still plugins which use them. This ends normally in the annoying log message: DEPRECATION WARNING: RAILS_ROOT is deprecated. Please use ::Rails.root.to_s. (called from &#60;top (required)&#62; at /Users/heli/hemju/programming/workspace/rubymine/linguist/config/application.rb:12) So what to do when you want to get rid of them? Find them, (optional) [...] <b>Related posts:</b><ol><li><a href='http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/' rel='bookmark' title='Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading'>Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading</a></li><li><a href='http://hemju.com/2010/10/06/quicktip-generating-entity-relationship-diagrams-for-ruby-on-rails/' rel='bookmark' title='Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails'>Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails</a></li><li><a href='http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/' rel='bookmark' title='Rails 3 Quicktip: Auto reload lib folders in development mode'>Rails 3 Quicktip: Auto reload lib folders in development mode</a></li></ol>]]></description> <content:encoded><![CDATA[<p>In Rails 3 a couple of constants/methods were set deprecated. However, there are still plugins which use them. This ends normally in the annoying log message:</p><p style="text-align: center;"><strong>DEPRECATION WARNING: RAILS_ROOT is deprecated. Please use ::Rails.root.to_s. (called from &lt;top (required)&gt; at /Users/heli/hemju/programming/workspace/rubymine/linguist/config/application.rb:12)</strong></p><p>So what to do when you want to get rid of them? Find them, (optional) create a patch, and report them to the plugin maintainer. One easy way to find deprecated elements is to override them and let them throw an exception or set them to nil. So in the above case, I would add <em>RAILS_ROOT = nil</em> to an initializer. At the next startup there will probably be an exception thrown and you know exactly where to find the deprecated method. Now start patching.</p> <a style="visibility:hidden;color:white;" href="http://www.lingui.st">Lingui.st - Online Resource Editor, Manage your Ruby/Rails, Java, .Net and C++ language files with ease</a><div class="shr-publisher-1469"></div><p><b>Related posts:</b><ol><li><a href='http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/' rel='bookmark' title='Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading'>Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading</a></li><li><a href='http://hemju.com/2010/10/06/quicktip-generating-entity-relationship-diagrams-for-ruby-on-rails/' rel='bookmark' title='Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails'>Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails</a></li><li><a href='http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/' rel='bookmark' title='Rails 3 Quicktip: Auto reload lib folders in development mode'>Rails 3 Quicktip: Auto reload lib folders in development mode</a></li></ol></p><img src="http://feeds.feedburner.com/~r/hemju/~4/HXd0oJdV3D8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/02/21/quicktip-finding-deprecated-constantsmethods-easily/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://hemju.com/2011/02/21/quicktip-finding-deprecated-constantsmethods-easily/</feedburner:origLink></item> <item><title>Rails 3 Quicktip: Auto reload lib folders in development mode</title><link>http://feedproxy.google.com/~r/hemju/~3/E9bMlbXmT2U/</link> <comments>http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/#comments</comments> <pubDate>Fri, 11 Feb 2011 09:40:18 +0000</pubDate> <dc:creator>Helmut M. Juskewycz</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[Directory]]></category> <category><![CDATA[Quicktip]]></category> <category><![CDATA[Rails3]]></category> <category><![CDATA[ruby on rails]]></category> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://hemju.com/?p=1450</guid> <description><![CDATA[One of our most popular article is &#8220;Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading&#8221; in which we describe how autoloading the lib directory in Rails 3 can be done. However, one problem was still there, Rails 3 loads the lib directory on startup, but doesn&#8217;t reload the lib directory after [...] <b>Related posts:</b><ol><li><a href='http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/' rel='bookmark' title='Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading'>Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading</a></li><li><a href='http://hemju.com/2010/10/06/quicktip-generating-entity-relationship-diagrams-for-ruby-on-rails/' rel='bookmark' title='Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails'>Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails</a></li><li><a href='http://hemju.com/2011/02/21/quicktip-finding-deprecated-constantsmethods-easily/' rel='bookmark' title='Quicktip: Finding deprecated constants/methods easily'>Quicktip: Finding deprecated constants/methods easily</a></li></ol>]]></description> <content:encoded><![CDATA[<p>One of our most popular article is &#8220;<a href="http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/">Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading</a>&#8221; in which we describe how autoloading the lib directory in Rails 3 can be done. However, one problem was still there, Rails 3 loads the lib directory on startup, but doesn&#8217;t reload the lib directory after that. Hence, if you change a lib file the server has to be restarted (which is quite annoying).</p><p>Here is how we can force Rails 3 to reload these files in Development Mode:</p><p>First we need to know which files we want to reload. For this purpose we create an initializer that goes through the lib directory and stores the path of all Ruby files:</p><div id="gist-822103" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">RELOAD_LIBS</span> <span class="o">=</span> <span class="no">Dir</span><span class="o">[</span><span class="no">Rails</span><span class="o">.</span><span class="n">root</span> <span class="o">+</span> <span class="s1">&#39;lib/**/*.rb&#39;</span><span class="o">]</span> <span class="k">if</span> <span class="no">Rails</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">development?</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/822103/3bf82657da8a32ab3e11d9e9bf14a2b145ceafbf/reload_lib.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/822103#file_reload_lib.rb" style="float:right;margin-right:10px;color:#666">reload_lib.rb</a> <a href="https://gist.github.com/822103">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Now we only need to reload these files on every request. The best place for doing so is the ApplicationController. So we create this before_filter:</p><div id="gist-822114" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="n">before_filter</span> <span class="ss">:_reload_libs</span><span class="p">,</span> <span class="ss">:if</span> <span class="o">=&gt;</span> <span class="ss">:_reload_libs?</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="k">def</span> <span class="nf">_reload_libs</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="no">RELOAD_LIBS</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">lib</span><span class="o">|</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">require_dependency</span> <span class="n">lib</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC7'><span class="k">end</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'><span class="k">def</span> <span class="nf">_reload_libs?</span></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="n">defined?</span> <span class="no">RELOAD_LIBS</span></div><div class='line' id='LC11'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/822114/ec11376f850227b428a0fb2ee76b2480fe964e60/application_controller.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/822114#file_application_controller.rb" style="float:right;margin-right:10px;color:#666">application_controller.rb</a> <a href="https://gist.github.com/822114">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>The before filter runs only when the constant is defined (in our case in Development Mode) and reloads the file with the changes. No more restarting!</p><p>There are a couple of ways to reload the files, but I find this the least hackish way to do it. The downsides of this approach is that we have a before_filter in our ApplicationController that has nothing to do with the application logic and of course reloading all the files on every request slows things down. Nevertheless, not having to restart the server is really really helpful when developing in the lib directory.</p><p>See the quicktip in <a href="http://notes.hemju.com">hemju Notes</a>: http://notes.hemju.com/notes/rails-reload-lib-directory</p><p>&#8212;&#8212;&#8212;&#8212;&#8212;</p><p><strong>Update 25.4.2011</strong></p><p>I updated the &#8216;reload_lib&#8217; GIST using the suggestions from James&#8217; comment.</p> <a style="visibility:hidden;color:white;" href="http://www.lingui.st">Lingui.st - Online Resource Editor, Manage your Ruby/Rails, Java, .Net and C++ language files with ease</a><div class="shr-publisher-1450"></div><p><b>Related posts:</b><ol><li><a href='http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/' rel='bookmark' title='Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading'>Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading</a></li><li><a href='http://hemju.com/2010/10/06/quicktip-generating-entity-relationship-diagrams-for-ruby-on-rails/' rel='bookmark' title='Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails'>Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails</a></li><li><a href='http://hemju.com/2011/02/21/quicktip-finding-deprecated-constantsmethods-easily/' rel='bookmark' title='Quicktip: Finding deprecated constants/methods easily'>Quicktip: Finding deprecated constants/methods easily</a></li></ol></p><img src="http://feeds.feedburner.com/~r/hemju/~4/E9bMlbXmT2U" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/feed/</wfw:commentRss> <slash:comments>12</slash:comments> <feedburner:origLink>http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/</feedburner:origLink></item> <item><title>Internationalization (I18n) API in Ruby on Rails 3 (Part III)</title><link>http://feedproxy.google.com/~r/hemju/~3/isHJrjhTL80/</link> <comments>http://hemju.com/2011/01/29/internationalization-i18n-api-in-ruby-on-rails-3-part-iii/#comments</comments> <pubDate>Sat, 29 Jan 2011 18:30:29 +0000</pubDate> <dc:creator>hemali</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[api]]></category> <category><![CDATA[Globalize2]]></category> <category><![CDATA[i18n]]></category> <category><![CDATA[i18n api]]></category> <category><![CDATA[i18n_backend_database]]></category> <category><![CDATA[internationalization]]></category> <category><![CDATA[internationalization and localization]]></category> <category><![CDATA[l10n]]></category> <category><![CDATA[linguistics]]></category> <category><![CDATA[localization]]></category> <category><![CDATA[localize]]></category> <category><![CDATA[multi-language]]></category> <category><![CDATA[ruby on rails]]></category> <category><![CDATA[translate]]></category> <category><![CDATA[translate_routes]]></category> <category><![CDATA[translation]]></category><guid isPermaLink="false">http://hemju.com/?p=1333</guid> <description><![CDATA[In Internationalization (I18n) API in Ruby on Rails 3 (Part I) and Internationalization (I18n) API in Ruby on Rails 3 (Part II) we already covered a lot of the Rails I18n functionality. In part III, we will now a look at some more advanced features of I18n. Using Different backend with I18n The I18n ruby gem [...] <b>Related posts:</b><ol><li><a href='http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part II)'>Internationalization (I18n) API in Ruby on Rails 3 (Part II)</a></li><li><a href='http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part I)'>Internationalization (I18n) API in Ruby on Rails 3 (Part I)</a></li><li><a href='http://hemju.com/2008/11/22/ruby-on-rails-22/' rel='bookmark' title='Ruby on Rails 2.2'>Ruby on Rails 2.2</a></li></ol>]]></description> <content:encoded><![CDATA[<p>In <a title="Internationalization (I18n) API in Ruby on Rails 3 (Part I)" href="http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/">Internationalization (I18n) API in Ruby on Rails 3 (Part I)</a> and <a title="Internationalization (I18n) API in Ruby on Rails 3 (Part II)" href="http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/">Internationalization (I18n) API in Ruby on Rails 3 (Part II)</a> we already covered a lot of the Rails I18n functionality. In part III, we will now a look at some more advanced features of I18n.</p><h2><strong>Using Different backend with I18n</strong></h2><p>The I18n ruby gem comes with backend support for resource files (more specifically .yml files). Additionally, it also provides simple approach to exchange the backend implementation using different gem/plugin depending on your requirements. Let’s examine an example where all translations are stored within database.</p><h3>Using Database backend for Ruby I18n API</h3><p>You  can easily use your database for storing all the translations with the help of i18n_backend_database (<a href="https://github.com/dylanz/i18n_backend_database" target="_blank">https://github.com/dylanz/i18n_backend_database</a>) plugin. This plugin will store all your translations in the database instead of YAML files and provides a caching mechanism, so that the database doesn&#8217;t get hit for every translation. When you tag items using i18n.t() within the code base, all of untranslated items will be noted as well as added into the database. You can translate untranslated textual content through an administrator panel provided by plugin.</p><p><strong>Update 2011-02-01</strong></p><p>Please note that this plugin is not yet ready for Rails 3 (see comments). Here are the steps to use this plugin for Rails 2.x:</p><div id="gist-801603" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>#install plugin in vendor/plugin folder</div><div class='line' id='LC2'>script/plugin install git://github.com/dylanz/i18n_backend_database.git</div><div class='line' id='LC3'># add migration</div><div class='line' id='LC4'>script/generate i18n_backend_database</div><div class='line' id='LC5'># migrate</div><div class='line' id='LC6'>rake db:migrate</div><div class='line' id='LC7'># populate default locales</div><div class='line' id='LC8'>rake i18n:populate:load_default_locales</div><div class='line' id='LC9'># populate the locales and translations tables from all Rails Locale YAML files.</div><div class='line' id='LC10'>rake i18n:populate:from_rails</div><div class='line' id='LC11'># populate the translation tables from translation calls within the application.</div><div class='line' id='LC12'>rake i18n:populate:from_application</div><div class='line' id='LC13'># create non-default locale translation records from default locale translations.</div><div class='line' id='LC14'>rake i18n:populate:synchronize_translations</div><div class='line' id='LC15'># run all populate tasks.</div><div class='line' id='LC16'>rake i18n:populate:all</div><div class='line' id='LC17'># translate all untranslated string values using Google Language Translation API.</div><div class='line' id='LC18'>rake i18n:translate:google</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801603/bb5848d59fec623d7d6196b51a25630198a64425/i18n_backend_database%20setup" style="float:right;">view raw</a> <a href="https://gist.github.com/801603#file_i18n_backend_database setup" style="float:right;margin-right:10px;color:#666">i18n_backend_database setup</a> <a href="https://gist.github.com/801603">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Add this lines in config/initializers/i18n.rb</p><div id="gist-801606" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">I18n</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="no">I18n</span><span class="o">::</span><span class="no">Backend</span><span class="o">::</span><span class="no">Database</span><span class="o">.</span><span class="n">new</span> <span class="c1"># registers the backend</span></div><div class='line' id='LC2'><span class="no">I18n</span><span class="o">.</span><span class="n">backend</span><span class="o">.</span><span class="n">cache_store</span> <span class="o">=</span> <span class="ss">:memory_store</span>   <span class="c1"># optional: specify an alternate cache store</span></div><div class='line' id='LC3'><span class="no">I18n</span><span class="o">.</span><span class="n">backend</span><span class="o">.</span><span class="n">localize_text_tag</span> <span class="o">=</span> <span class="s1">&#39;##&#39;</span>      <span class="c1"># optional: specify an alternate localize text tag, the default is ^^</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801606/e72800c36a88191e2ddd1182deca4d8241cdba79/config/initialisers/i18n.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/801606#file_config/initialisers/i18n.rb" style="float:right;margin-right:10px;color:#666">config/initialisers/i18n.rb</a> <a href="https://gist.github.com/801606">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>In config/routes.rb register admin panel routes</p><div id="gist-801610" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="n">map</span><span class="o">.</span><span class="n">from_plugin</span> <span class="s1">&#39;i18n_backend_database&#39;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801610/5d9ab130861373bf0382268b6076b337259a543b/config/routes.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/801610#file_config/routes.rb" style="float:right;margin-right:10px;color:#666">config/routes.rb</a> <a href="https://gist.github.com/801610">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Now, rails application can translate all the code from the  database. All non-user generated text provided by the application needs  to be wrapped in a call to I18n.t().</p><div id="gist-801637" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>I18n.t(&quot;Hello there!&quot;)</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801637/1bd434e99c305655eff32ba59a4601a976063d78/call%20to%20I18n.t()" style="float:right;">view raw</a> <a href="https://gist.github.com/801637#file_call to i18n.t()" style="float:right;margin-right:10px;color:#666">call to I18n.t()</a> <a href="https://gist.github.com/801637">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Interpolation is handled by passing in key/value pairs as a value to  an interpolation tag    ( {{ }} ).</p><div id="gist-801638" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="err">$</span> <span class="no">I18n</span><span class="o">.</span><span class="n">t</span><span class="p">(</span><span class="s2">&quot;Hello there {{name}}!&quot;</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s2">&quot;Dylan&quot;</span><span class="p">)</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="err">$</span> <span class="no">I18n</span><span class="o">.</span><span class="n">t</span><span class="p">(</span><span class="s2">&quot;Click {{here}} or {{there}}&quot;</span><span class="p">,</span> <span class="ss">:here</span> <span class="o">=&gt;</span> <span class="s2">&quot;link_to(I18n.t(&#39;midnite&#39;), croix_path)&quot;</span><span class="p">,</span> <span class="ss">:there</span> <span class="o">=&gt;</span> <span class="s2">&quot;link_to(I18n.t(&#39;staten_island&#39;), wu_path)&quot;</span><span class="p">)</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801638/b329da572e6d6192b2db5e88579b3a065580b6ae/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/801638#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/801638">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><h2>Translating Routes with translate_routes Gem</h2><p>The  Ruby gem translate_routes helps you to translate URLs to any number of different languages, even for an already working application. This gem works with Rails 3.x. and also with other Rails versions like 2.1.x, 2.2.x and 2.3.x. The Ruby gem translate_routes is working good with all type of routing definitions, which includes RESTful as well as named routes. You don&#8217;t have to change your existing routing code, helpers, and so on; links work as expected &#8211; even in your tests.</p><p>Add translate_routes to your Gemfile:</p><div id="gist-801612" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="n">gem</span> <span class="s1">&#39;translate_routes&#39;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801612/ced85f1d460b6699e0873691c6b4b3e0dc935b28/Gemfile.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/801612#file_gemfile.rb" style="float:right;margin-right:10px;color:#666">Gemfile.rb</a> <a href="https://gist.github.com/801612">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>And let bundle do the rest: bundle install</p><p><strong>1)</strong> Let&#8217;s say you have this in your routes.rb file:</p><div id="gist-801614" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">TranslateRoutesApp</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">match</span> <span class="s1">&#39;contact&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;contact#index&#39;</span></div><div class='line' id='LC3'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801614/17feb61b98614fb737f21d89cb6e187ad060edec/config/routes.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/801614#file_config/routes.rb" style="float:right;margin-right:10px;color:#666">config/routes.rb</a> <a href="https://gist.github.com/801614">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>You can see the available routes with the &#8216;rake routes&#8217; task:</p><p>contact  /contact(.:format)  {:controller=&gt;&#8221;contact&#8221;, :action=&gt;&#8221;index&#8221;}</p><p><strong>2)</strong> Now write your translations in a standard YAML file (e.g: in  /config/i18n-routes.yml), including all the locales and their translations pairs:</p><div id="gist-801617" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="l-Scalar-Plain">en</span><span class="p-Indicator">:</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="c1"># you can leave empty locales, for example the default one</span></div><div class='line' id='LC3'><span class="l-Scalar-Plain">es</span><span class="p-Indicator">:</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="l-Scalar-Plain">contact</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">contacto</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801617/ab91b01700426bde1ee0f4721272b28d122bc997/i18n-routes.yml" style="float:right;">view raw</a> <a href="https://gist.github.com/801617#file_i18n_routes.yml" style="float:right;margin-right:10px;color:#666">i18n-routes.yml</a> <a href="https://gist.github.com/801617">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>3)</strong> Append this line in your routes.rb file to activate the translations specifying the path of the  translations file:</p><div id="gist-801618" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">ActionDispatch</span><span class="o">::</span><span class="no">Routing</span><span class="o">::</span><span class="no">Translator</span><span class="o">.</span><span class="n">translate_from_file</span><span class="p">(</span><span class="s1">&#39;config&#39;</span><span class="p">,</span><span class="s1">&#39;i18n-routes.yml&#39;</span><span class="p">)</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801618/c6ce9dc88bae507edd06498bea0f928d1e89cdc4/config/routes.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/801618#file_config/routes.rb" style="float:right;margin-right:10px;color:#666">config/routes.rb</a> <a href="https://gist.github.com/801618">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>4)</strong> Execute rake routes to see the new routes:</p><p>contact_es   /es/contacto(.:format) {:controller=&gt;&#8221;contact&#8221;, :action=&gt;&#8221;index&#8221;}<br /> contact_en   /contact(.:format)     {:controller=&gt;&#8221;contact&#8221;, :action=&gt;&#8221;index&#8221;}</p><p><strong>5)</strong> Include this filter in your ApplicationController:</p><div id="gist-801619" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="n">before_filter</span> <span class="ss">:set_locale_from_url</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/801619/40ed8bde04704d39bf3349aa268ba7127f734250/ApplicationController.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/801619#file_application_controller.rb" style="float:right;margin-right:10px;color:#666">ApplicationController.rb</a> <a href="https://gist.github.com/801619">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Now your application recognizes the different routes and sets the I18n.locale value in your controllers. But what about the routes generation? As you can see in the previous rake  routes output, the contact_es_es_path and contact_en_us_path routing helpers have been generated and are available in your controllers and views. Additionally, a contact_path helper has been generated, which generates the routes according to the current request&#8217;s locale.</p><p>This means that if you use named routes, you don&#8217;t need to modify your application links because the routing helpers are automatically adapted to the current locale.</p><p><strong>6)</strong> What about tests?</p><p>Of course, functional and integration testing involves some requests. The plugin includes some code to add a default locale parameter so they can remain untouched. Append it to your test_helper and it will be applied.</p><p>You can find additional information in the <a href="http://ruby-i18n.org/wiki">translate_routes&#8217; wiki</a>.</p><p><strong>Globalize2 &#8211; Alternatives for Ruby I18n Gem</strong></p><p>The Ruby gem Globalize2 was very popular in Rails community because it provides full-fledged internationalization solutions for Ruby on Rails application. You can use most of the features/tools independently and also you can combine them with other libraries or plugins.</p><p>The Feature/Tools for this gem are listed below.</p><ul><li>Model  translations – This functionality transparently translates ActiveRecord  data</li><li> Locale LoadPath – This gem load translation data from standard  locations enforcing conventions that suite your needs</li><li> Locale  Fallbacks – This feature make sure your translation lookups fall back  transparently through a path of alternative locales that make sense for any given locale in your application</li><li>Translation value objects – You can access useful meta data information on the translations returned from your backend and/or translated models</li></ul><h2>Conclusion</h2><p>The I18n API comes with plenty of features and yet hides the complexity behind a simple to use API. With this gem, a Ruby on Rails application has a great built-in support for multiple languages. As the diversity of users is growing and more and more users speak different languages, a good localization and internationalizationsupport is necessary for every serious Web Framework. If your application has a more specific need, have a look at the various plugins and extensions available. Rails has also a great documentation, and of course there is an Internationalization section, <a href="http://rails-i18n.org/wiki">I18n Wiki</a>.</p><div class="shr-publisher-1333"></div><p><b>Related posts:</b><ol><li><a href='http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part II)'>Internationalization (I18n) API in Ruby on Rails 3 (Part II)</a></li><li><a href='http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part I)'>Internationalization (I18n) API in Ruby on Rails 3 (Part I)</a></li><li><a href='http://hemju.com/2008/11/22/ruby-on-rails-22/' rel='bookmark' title='Ruby on Rails 2.2'>Ruby on Rails 2.2</a></li></ol></p><img src="http://feeds.feedburner.com/~r/hemju/~4/isHJrjhTL80" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/01/29/internationalization-i18n-api-in-ruby-on-rails-3-part-iii/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://hemju.com/2011/01/29/internationalization-i18n-api-in-ruby-on-rails-3-part-iii/</feedburner:origLink></item> <item><title>Internationalization (I18n) API in Ruby on Rails 3 (Part II)</title><link>http://feedproxy.google.com/~r/hemju/~3/2s9ovvdg2Cw/</link> <comments>http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/#comments</comments> <pubDate>Thu, 20 Jan 2011 08:33:04 +0000</pubDate> <dc:creator>hemali</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[api]]></category> <category><![CDATA[i18n]]></category> <category><![CDATA[i18n api]]></category> <category><![CDATA[internationalization]]></category> <category><![CDATA[internationalization and localization]]></category> <category><![CDATA[l10n]]></category> <category><![CDATA[linguistics]]></category> <category><![CDATA[localization]]></category> <category><![CDATA[localize]]></category> <category><![CDATA[multi-language]]></category> <category><![CDATA[ruby on rails]]></category> <category><![CDATA[translate]]></category> <category><![CDATA[translation]]></category><guid isPermaLink="false">http://hemju.com/?p=1246</guid> <description><![CDATA[In the Internationalization (I18n) API in Rails 3 (Part I) you read about Definition of Internationalization &#38; Localization How i18n mechanism works in Rails Setup/Configuration about the i18n mechanism Using the I18n with interpolation Using the I18n with pluralization You can read the full article on Internationalization (I18n) API in Rails 3 (Part I), if [...] <b>Related posts:</b><ol><li><a href='http://hemju.com/2011/01/29/internationalization-i18n-api-in-ruby-on-rails-3-part-iii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part III)'>Internationalization (I18n) API in Ruby on Rails 3 (Part III)</a></li><li><a href='http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part I)'>Internationalization (I18n) API in Ruby on Rails 3 (Part I)</a></li></ol>]]></description> <content:encoded><![CDATA[<p>In the <a title="Internationalization (I18n) API in Rails 3 (Part I)" href="http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/">Internationalization (I18n) API in Rails 3 (Part I)</a> you read about</p><ol><li> Definition of Internationalization &amp; Localization</li><li> How i18n mechanism works in Rails</li><li> Setup/Configuration about the i18n mechanism</li><li> Using the I18n with interpolation</li><li> Using the I18n with pluralization</li></ol><p>You can read the full article on <a title="Internationalization (I18n) API in Rails 3 (Part I)" href="http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/">Internationalization (I18n) API in Rails 3 (Part I)</a>, if you have not yet read it.</p><p>Now, let&#8217;s start with some other features of I18n in Ruby on Rails.</p><p><strong>Localization of Times/Dates</strong><br /> As I18n API provides date/time localization feature, we can easily add localized version of timestamp in Ruby on Rails application. To use this feature, first of all we need to add our localized translation for time format. Let&#8217;s change our de.yml file to add a German version.<br /><div id="gist-785930" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'># config/locales/de.yml</div><div class='line' id='LC2'>de:</div><div class='line' id='LC3'>&nbsp;&nbsp;time:</div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;formats:</div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description: &quot;Aktuelle Uhrzeit %H Stunden und %M Minuten&quot;</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785930/0ef86ace4f7dfc008cf2c3188ec6082838b7fd94/Localization%20of%20Times/Dates" style="float:right;">view raw</a> <a href="https://gist.github.com/785930#file_localization of times/dates" style="float:right;margin-right:10px;color:#666">Localization of Times/Dates</a> <a href="https://gist.github.com/785930">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Now, we can use I18n.l or Rails #l helper to localize the Time object in our desired time format.</p><div id="gist-785940" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>#script/console</div><div class='line' id='LC2'>&gt;&gt; I18n.locale = :de</div><div class='line' id='LC3'>=&gt; :de</div><div class='line' id='LC4'>&gt;&gt; I18n.l Time.now, :format =&gt; :description</div><div class='line' id='LC5'>=&gt; &quot;Aktuelle Uhrzeit 20 Stunden und 07 Minuten&quot;</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785940/ddd1e82683c9729c3050e7744226c28940c38a22/Localization%20of%20Times/Dates%20script/console" style="float:right;">view raw</a> <a href="https://gist.github.com/785940#file_localization of times/dates script/console" style="float:right;margin-right:10px;color:#666">Localization of Times/Dates script/console</a> <a href="https://gist.github.com/785940">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>You can add many more formats for date/time to make it work using the format that you want. You can also get a ready made version of different types of local files from <a title="rails-i18n" href="https://github.com/svenfuchs/rails-i18n">rails-i18n</a> github repository. Once you place those file(s) in config/locales/ folder, they are ready to use for localization.</p><p><strong>Using views for translation</strong><br /> In Rails 2.3 a new feature named &#8220;<strong>localized views</strong> (templates)&#8221; was introduced. For example, your application has  an ItemsController class with an index view. Your default index template page for  ItemsController is rendered by app/views/items/index.html.erb. If you want a localized version of index page, you will just have to write your text in index.de.html.erb file and then will have to save in the same folder. By setting the locale to :de, you can force Ruby on Rails application to render the German version of that template. When the locale is set to the default locale, the generic index.html.erb view will be used.</p><p>Generally, this feature is used for large amount of static content pages, where putting this large text content in YAML or in Ruby dictionaries feels cumbersome.</p><p><strong>Translating ActiveRecord errors</strong><br /> You can translate Active Record validation error messages easily. Active Record uses different namespaces which can be used to translate easily models, attributes, and/or validations.</p><p>For example, an Item model with a validates_presence_of validation for the name attribute like this:</p><div id="gist-785954" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>class Item &lt; ActiveRecord::Base</div><div class='line' id='LC2'>&nbsp;&nbsp;validates_presence_of :name</div><div class='line' id='LC3'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785954/08672e3d389a940630f6a9354cec40e5f02d7e30/Translating%20ActiveRecord%20errors%20Item%20Model" style="float:right;">view raw</a> <a href="https://gist.github.com/785954#file_translating active_record errors item model" style="float:right;margin-right:10px;color:#666">Translating ActiveRecord errors Item Model</a> <a href="https://gist.github.com/785954">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>In this case :blank is the key for the error message. So, Active Record will check this key in the namespaces:</p><div id="gist-785955" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>activerecord.errors.models.[model_name].attributes.[attribute_name]</div><div class='line' id='LC2'>activerecord.errors.models.[model_name]</div><div class='line' id='LC3'>activerecord.errors.messages</div><div class='line' id='LC4'>errors.attributes.[attribute_name]</div><div class='line' id='LC5'>errors.messages</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785955/788b5445a02046e8d48ecb716b102977022b356b/Translating%20ActiveRecord%20errors%20namespaces" style="float:right;">view raw</a> <a href="https://gist.github.com/785955#file_translating active_record errors namespaces" style="float:right;margin-right:10px;color:#666">Translating ActiveRecord errors namespaces</a> <a href="https://gist.github.com/785955">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>After following keys in the above mentioned order the result will be:</p><div id="gist-785957" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>activerecord.errors.models.item.attributes.name.blank</div><div class='line' id='LC2'>activerecord.errors.models.item.blank</div><div class='line' id='LC3'>activerecord.errors.messages.blank</div><div class='line' id='LC4'>errors.attributes.name.blank</div><div class='line' id='LC5'>errors.messagges.blank</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785957/084f928a8bdafbb512c13a4196e4efc7b4985c50/Translating%20ActiveModel%20errors%20result" style="float:right;">view raw</a> <a href="https://gist.github.com/785957#file_translating active_model errors result" style="float:right;margin-right:10px;color:#666">Translating ActiveModel errors result</a> <a href="https://gist.github.com/785957">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>If, your models are using inheritance then the messages are looked up in the inheritance chain.</p><p>For example, you might have an Book model inheriting from Item:<br /><div id="gist-785958" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>class Book &lt; Item</div><div class='line' id='LC2'>&nbsp;&nbsp;validates_presence_of :title</div><div class='line' id='LC3'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785958/cfc5134e9c3cf3853f510240baf26c7ec7fe8585/Translating%20ActiveModel%20errors%20Book%20model" style="float:right;">view raw</a> <a href="https://gist.github.com/785958#file_translating active_model errors book model" style="float:right;margin-right:10px;color:#666">Translating ActiveModel errors Book model</a> <a href="https://gist.github.com/785958">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>Then Active Record will look for messages in this order:<br /><div id="gist-785959" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>activerecord.errors.models.book.attributes.title.blank</div><div class='line' id='LC2'>activerecord.errors.models.book.blank</div><div class='line' id='LC3'>activerecord.errors.models.item.attributes.title.blank</div><div class='line' id='LC4'>activerecord.errors.models.item.blank</div><div class='line' id='LC5'>activerecord.errors.messages.blank</div><div class='line' id='LC6'>errors.attributes.title.blank</div><div class='line' id='LC7'>errors.messagges.blank</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785959/1d9e2548c601f6b8c59d3890b5e262b3f89507fe/Translating%20ActiveModel%20errors%20inheritance%20order" style="float:right;">view raw</a> <a href="https://gist.github.com/785959#file_translating active_model errors inheritance order" style="float:right;margin-right:10px;color:#666">Translating ActiveModel errors inheritance order</a> <a href="https://gist.github.com/785959">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>You can also add translations for Active Record error_messages_for helper like this.</p><div id="gist-785961" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="l-Scalar-Plain">de</span><span class="p-Indicator">:</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="l-Scalar-Plain">activerecord</span><span class="p-Indicator">:</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="l-Scalar-Plain">errors</span><span class="p-Indicator">:</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="l-Scalar-Plain">template</span><span class="p-Indicator">:</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="l-Scalar-Plain">header</span><span class="p-Indicator">:</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="l-Scalar-Plain">one</span><span class="p-Indicator">:</span>   <span class="s">&quot;1</span><span class="nv"> </span><span class="s">fehler</span><span class="nv"> </span><span class="s">verboten</span><span class="nv"> </span><span class="s">diese</span><span class="nv"> </span><span class="s">%{model}</span><span class="nv"> </span><span class="s">nicht</span><span class="nv"> </span><span class="s">gespeichert&quot;</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="l-Scalar-Plain">other</span><span class="p-Indicator">:</span> <span class="s">&quot;%{count}</span><span class="nv"> </span><span class="s">fehler</span><span class="nv"> </span><span class="s">verboten</span><span class="nv"> </span><span class="s">diese</span><span class="nv"> </span><span class="s">%{model}</span><span class="nv"> </span><span class="s">nicht</span><span class="nv"> </span><span class="s">gespeichert&quot;</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="l-Scalar-Plain">body</span><span class="p-Indicator">:</span>    <span class="s">&quot;Es</span><span class="nv"> </span><span class="s">gab</span><span class="nv"> </span><span class="s">probleme</span><span class="nv"> </span><span class="s">mit</span><span class="nv"> </span><span class="s">den</span><span class="nv"> </span><span class="s">folgenden</span><span class="nv"> </span><span class="s">feldern:&quot;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785961/98a06c821122c2ea2e47710c54035b490456834f/error_messages_for%20helper%20de.yml" style="float:right;">view raw</a> <a href="https://gist.github.com/785961#file_error_messages_for helper de.yml" style="float:right;margin-right:10px;color:#666">error_messages_for helper de.yml</a> <a href="https://gist.github.com/785961">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Organization of resource files</strong><br /> If you are using default i18n library settings, you may find that all files are stored in plain-text format on the disc. Placing all translations text of your Ruby on Rails application in one file per locale could be tedious to organize. You can easily store these files in a hierarchy structure which is easy to understand for you. For example, your config/locales directory could be organized like this:</p><div id="gist-785965" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>|-defaults</div><div class='line' id='LC2'>|---de.rb</div><div class='line' id='LC3'>|---en.rb</div><div class='line' id='LC4'>|-models</div><div class='line' id='LC5'>|---item</div><div class='line' id='LC6'>|-----de.rb</div><div class='line' id='LC7'>|-----en.rb</div><div class='line' id='LC8'>|-views</div><div class='line' id='LC9'>|---defaults</div><div class='line' id='LC10'>|-----de.rb</div><div class='line' id='LC11'>|-----en.rb</div><div class='line' id='LC12'>|---items</div><div class='line' id='LC13'>|-----de.rb</div><div class='line' id='LC14'>|-----en.rb</div><div class='line' id='LC15'>|---navigation</div><div class='line' id='LC16'>|-----de.rb</div><div class='line' id='LC17'>|-----en.rb</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785965/69cfdbd7f7fda4d1af2ef1114b35338fa6bb5c6a/Organization%20of%20resource%20files" style="float:right;">view raw</a> <a href="https://gist.github.com/785965#file_organization of resource files" style="float:right;margin-right:10px;color:#666">Organization of resource files</a> <a href="https://gist.github.com/785965">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>By following the above way to organize resource files, you can easily differentiate model and their attribute names from text inside views, and all of this from the &#8220;defaults&#8221;. In Ruby on Rails, locale files in nested dictionaries structure are not being loaded automatically. So, to make it work we have to do this settings in config/application.rb</p><div id="gist-785967" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="c1"># config/application.rb</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">config</span><span class="o">.</span><span class="n">i18n</span><span class="o">.</span><span class="n">load_path</span> <span class="o">+=</span> <span class="no">Dir</span><span class="o">[</span><span class="no">Rails</span><span class="o">.</span><span class="n">root</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">&#39;config&#39;</span><span class="p">,</span> <span class="s1">&#39;locales&#39;</span><span class="p">,</span> <span class="s1">&#39;**&#39;</span><span class="p">,</span> <span class="s1">&#39;*.{rb,yml}&#39;</span><span class="p">)</span><span class="o">]</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785967/738e30b8b56c66c953de927c2019c8be4e23d038/config/application.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/785967#file_config/application.rb" style="float:right;margin-right:10px;color:#666">config/application.rb</a> <a href="https://gist.github.com/785967">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Setting the Locale from the Domain Name</strong><br /> In the previous article you read about how to set the locale in Ruby on Rails using application.rb settings. There are also other ways to do so. You can set the locale from the domain name where your Ruby on Rails application runs. Like www.example.com will load the content in English locale, www.example.de will load the content in German locale. This way you can use top-level domain names to set the locale for Ruby on Rails application.</p><p>The benefits of using this method are:</p><ol><li>The locale setting is an obvious part of the URL.</li><li>Visitors obviously know in which language the content of the website will be displayed.</li><li>It is very easy to implement in Ruby on Rails.</li><li>Search engines love the content in different languages served at different domains.</li></ol><p>You can use it in your ApplicationController:</p><div id="gist-785972" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>before_filter :set_locale</div><div class='line' id='LC2'>&nbsp;</div><div class='line' id='LC3'>def set_locale</div><div class='line' id='LC4'>&nbsp;&nbsp;I18n.locale = extract_locale_from_tld</div><div class='line' id='LC5'>end</div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>def extract_locale_from_tld</div><div class='line' id='LC8'>&nbsp;&nbsp;parsed_locale = request.host.split(&#39;.&#39;).last</div><div class='line' id='LC9'>&nbsp;&nbsp;I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale  : nil</div><div class='line' id='LC10'>end</div><div class='line' id='LC11'>&nbsp;</div><div class='line' id='LC12'># Get locale from top-level domain or return nil if such locale is not available</div><div class='line' id='LC13'># You have to put something like:</div><div class='line' id='LC14'>#   127.0.0.1 example.com</div><div class='line' id='LC15'>#   127.0.0.1 example.it</div><div class='line' id='LC16'>#   127.0.0.1 example.pl</div><div class='line' id='LC17'># in your /etc/hosts file to try this out locally</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785972/85e79b034c332f7b8c8b50f4eadf05580079d4a6/Setting%20the%20Locale%20from%20the%20Domain%20Name%20ApplicationController" style="float:right;">view raw</a> <a href="https://gist.github.com/785972#file_setting the locale from the domain name application_controller" style="float:right;margin-right:10px;color:#666">Setting the Locale from the Domain Name ApplicationController</a> <a href="https://gist.github.com/785972">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>We can also set the locale from the subdomain in a very similar way:</p><div id="gist-785973" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'># Get locale code from request subdomain (like http://it.example.local:3000)</div><div class='line' id='LC2'># You have to put something like:</div><div class='line' id='LC3'>#   127.0.0.1 gr.example.local</div><div class='line' id='LC4'># in your /etc/hosts file to try this out locally</div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'>def extract_locale_from_subdomain</div><div class='line' id='LC7'>&nbsp;&nbsp;parsed_locale = request.subdomains.first</div><div class='line' id='LC8'>&nbsp;&nbsp;I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale  : nil</div><div class='line' id='LC9'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785973/00423e3be143994959c3f92204bbc44c087b4d72/Get%20locale%20code%20from%20request%20subdomain" style="float:right;">view raw</a> <a href="https://gist.github.com/785973#file_get locale code from request subdomain" style="float:right;margin-right:10px;color:#666">Get locale code from request subdomain</a> <a href="https://gist.github.com/785973">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>You can also use switching menu option in your application like this:</p><div id="gist-785974" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>link_to(&quot;Deutsch&quot;, &quot;#{APP_CONFIG[:deutsch_website_url]}#{request.env[&#39;REQUEST_URI&#39;]}&quot;)</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785974/6ca5222d8d10ff4e68f92697fd4922bf7cebb903/switching%20menu%20option" style="float:right;">view raw</a> <a href="https://gist.github.com/785974#file_switching menu option" style="float:right;margin-right:10px;color:#666">switching menu option</a> <a href="https://gist.github.com/785974">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>assuming you would set APP_CONFIG[:deutsch_website_url] to some value like http://www.example.de.</p><p>As previously mentioned this method has benefits, but what if you do not want to or able to provide different localizations (&#8220;language versions&#8221;) on different domains. The solution to this will be to add locale code in the URL params (or request path).</p><p><strong>Setting the Locale from the URL Params</strong><br /> We can also set the locale by including it in URL params like www.example.com/items?locale=de or www.example.com/de/items.</p><p>You can use it in your ApplicationController:</p><div id="gist-785977" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>before_filter :set_locale</div><div class='line' id='LC2'>&nbsp;</div><div class='line' id='LC3'>def set_locale</div><div class='line' id='LC4'>&nbsp;&nbsp;I18n.locale = params[:locale]</div><div class='line' id='LC5'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785977/53e629e3f7c366bbc294983cdcd6076ef13cb6f9/Setting%20the%20Locale%20from%20the%20URL%20Params%20ApplicationController" style="float:right;">view raw</a> <a href="https://gist.github.com/785977#file_setting the locale from the url params application_controller" style="float:right;margin-right:10px;color:#666">Setting the Locale from the URL Params ApplicationController</a> <a href="https://gist.github.com/785977">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>You can get same benefits with this method as with setting the locale from the domain name, but the only little problem is it takes bit more code to implement. Here is the code to implement it by including it in our ApplicationController:</p><div id="gist-785979" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'># app/controllers/application_controller.rb</div><div class='line' id='LC2'>def default_url_options(options={})</div><div class='line' id='LC3'>&nbsp;&nbsp;logger.debug &quot;default_url_options is passed options: #{options.inspect}\n&quot;</div><div class='line' id='LC4'>&nbsp;&nbsp;{ :locale =&gt; I18n.locale }</div><div class='line' id='LC5'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785979/a2d24abd5c47075e25ddc65abbec39235119602e/Setting%20the%20Locale%20from%20the%20URL%20Params%20default_url_options" style="float:right;">view raw</a> <a href="https://gist.github.com/785979#file_setting the locale from the url params default_url_options" style="float:right;margin-right:10px;color:#666">Setting the Locale from the URL Params default_url_options</a> <a href="https://gist.github.com/785979">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>This way we can easily set/override &#8220;defaults&#8221; for url_for and helper methods dependent on it. So, every url_for dependent helper method will now add the locale in the query string like, http://example.com/?locale=de.</p><p>Now, if you want URLs to look like this http://example.com/de/items (which loads the German locale), we need to set up routes with path_prefix option this way:</p><div id="gist-785982" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'># config/routes.rb</div><div class='line' id='LC2'>scope &quot;/:locale&quot; do</div><div class='line' id='LC3'>&nbsp;&nbsp;resources :items</div><div class='line' id='LC4'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785982/237b60631c54f5b1e8e632d348f3bb3de1101f84/path_prefix%20option" style="float:right;">view raw</a> <a href="https://gist.github.com/785982#file_path_prefix option" style="float:right;margin-right:10px;color:#666">path_prefix option</a> <a href="https://gist.github.com/785982">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>So, when you call items_path for :de locales, an URL like http://example.com/de/items will be generated with the German locale. But, if you do not want to force the use of a locale in your routes you can set an optional path scope like:</p><div id="gist-785983" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'># config/routes.rb</div><div class='line' id='LC2'>scope &quot;(:locale)&quot;, :locale =&gt; /en|de/ do</div><div class='line' id='LC3'>&nbsp;&nbsp;resources :items</div><div class='line' id='LC4'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785983/21fdea9bd0dd59ace3aadc4e27e3994cb23d8546/optional%20path%20scope%20for%20path_prefix" style="float:right;">view raw</a> <a href="https://gist.github.com/785983#file_optional path scope for path_prefix" style="float:right;margin-right:10px;color:#666">optional path scope for path_prefix</a> <a href="https://gist.github.com/785983">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>This way when you access http://example.com/items without a locale, you will not get a routing error, which is very useful for setting default locale when one is not mentioned.</p><p><strong>Setting the Locale from the Client Supplied Information</strong><br /> Sometimes, you have to set the locale from the information that client had supplied (not from the URL.) i.e. user&#8217;s preferred language or by choosing the locale in your application interface and saving it to their profile.</p><p><strong>Using Accept-Language HTTP header</strong><br /> Client may set Accept-Language HTTP header in their browser or other client (like curl) and request the url. By supplying the information of the locale. We can implement this scenario with this code in ApplicationController.</p><div id="gist-785987" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>def set_locale</div><div class='line' id='LC2'>&nbsp;&nbsp;logger.debug &quot;* Accept-Language: #{request.env[&#39;HTTP_ACCEPT_LANGUAGE&#39;]}&quot;</div><div class='line' id='LC3'>&nbsp;&nbsp;I18n.locale = extract_locale_from_accept_language_header</div><div class='line' id='LC4'>&nbsp;&nbsp;logger.debug &quot;* Locale set to &#39;#{I18n.locale}&#39;&quot;</div><div class='line' id='LC5'>end</div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>private</div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>def extract_locale_from_accept_language_header</div><div class='line' id='LC10'>&nbsp;&nbsp;request.env[&#39;HTTP_ACCEPT_LANGUAGE&#39;].scan(/^[a-z]{2}/).first</div><div class='line' id='LC11'>end</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785987/f26011c6ca4a796e5fd8993c1c56a610b95f257a/Using%20Accept-Language%20HTTP%20header" style="float:right;">view raw</a> <a href="https://gist.github.com/785987#file_using accept_language http header" style="float:right;margin-right:10px;color:#666">Using Accept-Language HTTP header</a> <a href="https://gist.github.com/785987">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>You can also use a plugin such as Iain <a href="https://github.com/iain/http_accept_language">Hecker’s http_accept_language</a> or even <a href="http://railscasts.com/episodes/151-rack-middleware">Rack middleware</a> such as Ryan Tomayko’s locale to implement this method in production mode.</p><p><strong>Using User Profile</strong><br /> In your Ruby on Rails application it is also possible that users want to set the locale for their interface by setting it from database. In user&#8217;s profile, user will have to choose the locale from a dropdown list and it will get saved in the database along with other profile data. In this case, you need to override the locale value something like this.</p><div id="gist-785990" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>def set_locale</div><div class='line' id='LC2'>&nbsp;&nbsp;if current_user?</div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;I18n.locale = current_user.locale</div><div class='line' id='LC4'>&nbsp;&nbsp;else</div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;I18n.locale = :en</div><div class='line' id='LC6'>&nbsp;&nbsp;end</div><div class='line' id='LC7'>end </div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/785990/487fe2a6d54d8c08a5575aa9524f659d3336dad3/Using%20User%20Profile" style="float:right;">view raw</a> <a href="https://gist.github.com/785990#file_using user profile" style="float:right;margin-right:10px;color:#666">Using User Profile</a> <a href="https://gist.github.com/785990">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>That’s it for Part II. In Part III we will check</p><ul><li>Using different backends for I18n API</li><li>Translating Routes</li></ul><div class="shr-publisher-1246"></div><p><b>Related posts:</b><ol><li><a href='http://hemju.com/2011/01/29/internationalization-i18n-api-in-ruby-on-rails-3-part-iii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part III)'>Internationalization (I18n) API in Ruby on Rails 3 (Part III)</a></li><li><a href='http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part I)'>Internationalization (I18n) API in Ruby on Rails 3 (Part I)</a></li></ol></p><img src="http://feeds.feedburner.com/~r/hemju/~4/2s9ovvdg2Cw" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/</feedburner:origLink></item> <item><title>Internationalization (I18n) API in Ruby on Rails 3 (Part I)</title><link>http://feedproxy.google.com/~r/hemju/~3/hlEMZyp4dq8/</link> <comments>http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/#comments</comments> <pubDate>Thu, 13 Jan 2011 14:56:07 +0000</pubDate> <dc:creator>hemali</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[i18n]]></category> <category><![CDATA[i18n api]]></category> <category><![CDATA[internationalization]]></category> <category><![CDATA[l10n]]></category> <category><![CDATA[localization]]></category> <category><![CDATA[localize]]></category> <category><![CDATA[multi-language]]></category> <category><![CDATA[ruby on rails]]></category> <category><![CDATA[translate]]></category> <category><![CDATA[translation]]></category><guid isPermaLink="false">http://hemju.com/?p=1109</guid> <description><![CDATA[Whenever we hear about Internationalization of web application, the first word that comes to our mind is &#8220;Translation&#8220;. There are three ways to translate software: Do it Yourself Pay Someone for doing Translation Ask your Users No matter what, making the software &#8216;Internationalization ready&#8217; is the developer&#8217;s job. No static strings, dates in the code [...] <b>Related posts:</b><ol><li><a href='http://hemju.com/2011/01/29/internationalization-i18n-api-in-ruby-on-rails-3-part-iii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part III)'>Internationalization (I18n) API in Ruby on Rails 3 (Part III)</a></li><li><a href='http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part II)'>Internationalization (I18n) API in Ruby on Rails 3 (Part II)</a></li><li><a href='http://hemju.com/2008/11/22/ruby-on-rails-22/' rel='bookmark' title='Ruby on Rails 2.2'>Ruby on Rails 2.2</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Whenever we hear about <strong>Internationalization of web application</strong>, the first word that comes to our mind is &#8220;<strong>Translation</strong>&#8220;. There are three ways to translate software:</p><ul><li>Do it Yourself</li><li>Pay Someone for doing Translation</li><li>Ask your Users</li></ul><p><img class="size-full wp-image-1240 aligncenter" title="How to get translations" src="http://hemju.com/wp-content/uploads/2011/01/Translation.jpg" alt="how to get translations" width="300" height="200" /></p><p>No matter what, making the software &#8216;Internationalization ready&#8217; is the developer&#8217;s job. No static strings, dates in the code and so forth; every text must be put in resource files and the code decides which text to use. Luckily Ruby on Rails provides a simple ruby gem called &#8220;<a href="http://ruby-i18n.org/"><strong>I18n</strong></a>&#8221;  (internationalization) that does exactly that.</p><p><strong>Definition of Internationalization &amp; Localization :</strong></p><p>First of all let&#8217;s check the definition of Internationalization &amp; Localization. According to Wikipedia,</p><p><strong>i18n</strong> &#8211; &#8220;<em>Internationalization</em> is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes.&#8221; This means, the <strong>&#8220;Internationalization&#8221;</strong> functionality translates all string and other locale specific information ( like date and currency formats) from your application in desire language to end user.</p><p><strong>l10n</strong> &#8211; &#8220;<em>Localization</em> is the process of adapting software for a specific region or language by adding locale-specific components and translating text.&#8221; This means, the <strong>&#8220;Localization&#8221;</strong> functionality gives translations in local-specific language and other localized formats for local specific information.</p><p><strong>How i18n mechanism works in Rails :</strong></p><p>All the languages are different from each other in many ways (For example pluralization rules). It is very difficult for any tools/software to provide a general solution for language translation. To solve this problem I18n API provides two features in Ruby on Rails.</p><ol><li>Give support for English and other similar languages out of the box</li><li>Provide a user-friendly and adjustable functions for supporting other languages</li></ol><p>This means in Ruby on Rails every static string has been internationalized and you can &#8220;over-ride&#8221; these defaults with &#8220;localization&#8221; of the application.</p><p>There are two parts of Ruby I18n gem which are:</p><ol><li><strong>The public I18n API</strong> &#8211; provides a Ruby module with public methods to characterize the work of the library</li><li><strong>A default backend</strong> &#8211; which executes these public methods</li></ol><p>The Public I18n API comes with two most important methods which are:</p><ol><li><strong>translate</strong> # This public method do translations of the text</li><li><strong>localize</strong> # This public method localize Date and Time objects to local formats as per settings</li></ol><p>These method have aliases #t and #l respectively, so you can use them like this:</p><div id="gist-772983" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="no">I18n</span><span class="o">.</span><span class="n">t</span> <span class="s1">&#39;store.title&#39;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="no">I18n</span><span class="o">.</span><span class="n">l</span> <span class="no">Time</span><span class="o">.</span><span class="n">now</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/772983/57a0e9e945f2b7ca91234dc8d6ae73557ca18fca/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/772983#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/772983">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Setup/Configuration about the i18n mechanism</strong></p><p>You can easily setup ruby I18n gem with few simple steps and use in your application for I18n support. Ruby on Rails application set up reasonable defaults in all .rb and .yml files in config folder. If you want to change the settings, you can easily change them according to your need.</p><p>To check the defaults for I18n module you have to check config/locales directory, which is default path for translation.</p><p>You will get one file named en.yml which default locale and contains these translation strings:</p><div id="gist-773002" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="n">en</span><span class="p">:</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">hello</span><span class="p">:</span> <span class="s2">&quot;Hello world&quot;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773002/ae09dd93589808b6ebf0ea4b7f2d6aa5fb610f1c/gistfile1.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/773002#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a> <a href="https://gist.github.com/773002">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>English is default locale in I18n library. So, if your application is not set in different locale, :en will translate all the static text changes.</p><p>So, when you check this on console the output shows like following :</p><div id="gist-773005" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>&gt;&gt; I18n.locale</div><div class='line' id='LC2'>=&gt; :en</div><div class='line' id='LC3'>&gt;&gt; I18n.default_locale</div><div class='line' id='LC4'>=&gt; :en</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773005/8c78e1fb2610afcf3d363fab126999d7c33260b2/I18n%20:en%20example" style="float:right;">view raw</a> <a href="https://gist.github.com/773005#file_i18n :en example" style="float:right;margin-right:10px;color:#666">I18n :en example</a> <a href="https://gist.github.com/773005">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Some other available locales which are supported by rails 3 are:</p><p>ar, bg, bn-IN, bs, ca, cy, cz, da, de, de-AT, de-CH, dsb, el, en-GB, en-US, eo, es, es-AR, es-CO, es-MX, es-PE, et, eu, fa, fi, fr, fr-CA, fr-CH, fur, gl-ES, gsw-CH, he, hi-IN, hr, hsb, hu, id, is, it, ja, ko, lo, lt, lv, mk, mn, nb, nl, nn, pl, pt-BR, pt-PT, rm, ro, ru, sk, sl, sr, sr-Latn, sv-SE, sw, th, tr, uk, vi, zh-CN, zh-TW</p><p>The easiest method to set your own locales to override the default locale is to change config/application.rb file in Rails 3. (You can apply same settings to config/environment.rb in Rails 2). Add this line to get German language as default locale:</p><div id="gist-773012" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>config.i18n.load_path += Dir[Rails.root.join(&#39;my&#39;, &#39;locales&#39;, &#39;*.{rb,yml}&#39;).to_s]</div><div class='line' id='LC2'>config.i18n.default_locale = :de</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773012/2de14373a935372bc0cd4cb442c03e071a6ce77b/application.rb%20Setting%20for%20I18n" style="float:right;">view raw</a> <a href="https://gist.github.com/773012#file_application.rb setting for i18n" style="float:right;margin-right:10px;color:#666">application.rb Setting for I18n</a> <a href="https://gist.github.com/773012">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>The first line of code tells the location of translation file to the I18n library. The second line of code will set the default locale to :de other than :en.</p><p><strong>Using the I18n module</strong></p><p>Put these lines in config/locale/de.yml.</p><div id="gist-773014" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>de:</div><div class='line' id='LC2'>&nbsp;&nbsp;hello: &quot;Hallo Welt&quot;</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773014/72ef91cae66982f023eb4affcc1bc86e52d61b92/:de%20for%20I18n%20Example" style="float:right;">view raw</a> <a href="https://gist.github.com/773014#file_:de for i18n example" style="float:right;margin-right:10px;color:#666">:de for I18n Example</a> <a href="https://gist.github.com/773014">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Let&#8217;s check now whether this settings translate &#8220;hello&#8221; into &#8220;German&#8221; locale or not.</p><div id="gist-773017" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>&gt;&gt; I18n.locale</div><div class='line' id='LC2'>=&gt; :en</div><div class='line' id='LC3'>&gt;&gt; I18n.locale = &#39;de&#39;</div><div class='line' id='LC4'>=&gt; :de</div><div class='line' id='LC5'>&gt;&gt; I18n.t &quot;hello&quot;</div><div class='line' id='LC6'>=&gt; &quot;Hallo Welt&quot;</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773017/a6926381373149df01bc891070e9ba0afabdd46b/I18n%20Testing%20for%20default%20locale" style="float:right;">view raw</a> <a href="https://gist.github.com/773017#file_i18n testing for default locale" style="float:right;margin-right:10px;color:#666">I18n Testing for default locale</a> <a href="https://gist.github.com/773017">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Using the I18n with interpolation</strong></p><p>Most of the time you want to use various variables with your translations. That&#8217;s why I18n API also provide interpolation feature.</p><div id="gist-773020" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>&gt;&gt; I18n.backend.store_translations :en, :hello =&gt; &#39;Hello %{name}!&#39;</div><div class='line' id='LC2'>&gt;&gt; I18n.translate :hello, :name =&gt; &#39;Newton&#39;</div><div class='line' id='LC3'>=&gt; &#39;Hello Newton!&#39;</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><br/></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773020/8dd61b191dc5b15ea0cf6d890b2ca4383ff9cc9a/I18n%20API%20with%20Interpolation%20feature" style="float:right;">view raw</a> <a href="https://gist.github.com/773020#file_i18n api with interpolation feature" style="float:right;margin-right:10px;color:#666">I18n API with Interpolation feature</a> <a href="https://gist.github.com/773020">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Using the I18n with pluralization</strong><br /> In English there are only one singular and one plural form for a given   string, e.g. “1 friend” and “2 friends”. The best thing is I18n API also  provides a flexible pluralization feature in Rails applications.</p><p>We   must note that an interpolation variable named :count plays key role  in translation and pluralization.</p><div id="gist-773024" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>I18n.backend.store_translations :en, :friend =&gt; {</div><div class='line' id='LC2'>:one =&gt; &#39;1 friend&#39;,</div><div class='line' id='LC3'>:other =&gt; &#39;%{count} friends&#39;</div><div class='line' id='LC4'>}</div><div class='line' id='LC5'>I18n.translate :friend, :count =&gt; 2</div><div class='line' id='LC6'># =&gt; &#39;2 friends&#39;</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773024/c0324641b30417f68ec9ce32b7fc965106f972ca/I18n%20API%20with%20Pluralization%20feature" style="float:right;">view raw</a> <a href="https://gist.github.com/773024#file_i18n api with pluralization feature" style="float:right;margin-right:10px;color:#666">I18n API with Pluralization feature</a> <a href="https://gist.github.com/773024">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>The algorithm for pluralization is:<br /><div id="gist-773027" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'>entry[count == 1 ? 0 : 1]</div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/773027/8035bec9f4faf06868d02934b5a051f251fa5a91/I18n%20API%20with%20Pluralization%20feature%20Code" style="float:right;">view raw</a> <a href="https://gist.github.com/773027#file_i18n api with pluralization feature code" style="float:right;margin-right:10px;color:#666">I18n API with Pluralization feature Code</a> <a href="https://gist.github.com/773027">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div></p><p>I.e. here 1 denotes singular and 0 denotes plural. So as specified  using conditional operator, if count == 1, it will consider it as  singular form otherwise its plural.</p><p>That&#8217;s it for Part I. In Part II we will check other features of I18n like</p><ul><li>Localization of Times/Dates</li><li>Using views for  translation</li><li>Translating ActiveModel errors</li><li>Organization of resource files</li><li>Setting the locale (from domain, parameter or client) and of  course storing it in the database when the user is logged in</li></ul><p>For more details you can check <a href="http://ruby-i18n.org/">http://ruby-i18n.org/ </a>.</p><div class="shr-publisher-1109"></div><p><b>Related posts:</b><ol><li><a href='http://hemju.com/2011/01/29/internationalization-i18n-api-in-ruby-on-rails-3-part-iii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part III)'>Internationalization (I18n) API in Ruby on Rails 3 (Part III)</a></li><li><a href='http://hemju.com/2011/01/20/internationalization-i18n-api-in-rails-3-part-ii/' rel='bookmark' title='Internationalization (I18n) API in Ruby on Rails 3 (Part II)'>Internationalization (I18n) API in Ruby on Rails 3 (Part II)</a></li><li><a href='http://hemju.com/2008/11/22/ruby-on-rails-22/' rel='bookmark' title='Ruby on Rails 2.2'>Ruby on Rails 2.2</a></li></ol></p><img src="http://feeds.feedburner.com/~r/hemju/~4/hlEMZyp4dq8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://hemju.com/2011/01/13/internationalization-i18n-api-in-rails-3-part-i/</feedburner:origLink></item> <item><title>Full text search with Sunspot in Rails</title><link>http://feedproxy.google.com/~r/hemju/~3/mdnDJBRvphg/</link> <comments>http://hemju.com/2011/01/04/full-text-search-with-sunspot-in-rails/#comments</comments> <pubDate>Tue, 04 Jan 2011 10:07:20 +0000</pubDate> <dc:creator>hemali</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[HowTo]]></category> <category><![CDATA[Rails3]]></category> <category><![CDATA[Sunspot]]></category> <category><![CDATA[Text Search]]></category><guid isPermaLink="false">http://hemju.com/?p=1000</guid> <description><![CDATA[Have you ever been came across a situation, when you have to examine all of the words in every stored document in Rails? Wait! here comes the solution and, that is, none other than Sunspot. Sunspot is basically a Ruby Library that is built on top of the RSolr library &#8211; A simple, extensible Ruby [...] No related posts.]]></description> <content:encoded><![CDATA[<p>Have you ever been came across a situation, when you have to examine all of the words in every stored document in Rails?</p><p>Wait! here comes the solution and, that is, none other than <a title="Sunspot" href="http://outoftime.github.com/sunspot/" target="_blank">Sunspot</a>. Sunspot is basically a Ruby Library that is built on top of the RSolr library &#8211; A simple, extensible Ruby client for <a title="Apache Solr" href="http://lucene.apache.org/solr/">Apache Solr</a>.</p><p>Recently, I had great experience of using Sunspot for full text search in one of my rails application. In Ruby on Rails, it is really easy to integrate full text search functionality, using <a title="Sunspot::Rails" href="http://github.com/outoftime/sunspot_rails">Sunspot::Rails</a>. I just followed set of steps, and it&#8217;s done. So, I thought sharing it with you.</p><p>For seamless integration of Sunspot search in your Rails application, you first need to install <a title="Sunspot::Rails" href="http://github.com/outoftime/sunspot_rails">Sunspot::Rails</a>.</p><p><strong>Installation in Rails 2</strong></p><p>$ sudo gem install sunspot_rails</p><div id="gist-763419" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="c1">#config/environment.rb</span></div><div class='line' id='LC2'><span class="n">config</span><span class="o">.</span><span class="n">gem</span> <span class="s1">&#39;sunspot_rails&#39;</span><span class="p">,</span> <span class="ss">:lib</span> <span class="o">=&gt;</span> <span class="s1">&#39;sunspot/rails&#39;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/763419/b0892161838b2113f0994d28d525e9910f3d2b12/environment.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/763419#file_environment.rb" style="float:right;margin-right:10px;color:#666">environment.rb</a> <a href="https://gist.github.com/763419">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Next step is to run the generator to create config/sunspot.yml file.  For that, run following command</p><p>$ script/generate sunspot</p><p>To get the Sunspot rake tasks, you’ll need to require the tasks from  your app’s <code>Rakefile</code>:</p><div id="gist-763485" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="s1">&#39;sunspot/rails/tasks&#39;</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/763485/c4deba090df88681c8c3e3dddcc5fa8d4bd52dd7/Rakefile.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/763485#file_rakefile.rb" style="float:right;margin-right:10px;color:#666">Rakefile.rb</a> <a href="https://gist.github.com/763485">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p><strong>Installation in Rails 3</strong></p><p>Add following line to your Gemfile to specify sunspot_rails gem</p><p>gem &#8216;sunspot_rails&#8217;, &#8217;1.2.1&#8242;</p><p>Now, it&#8217;s time to update your bundle using the command below</p><p>$ bundle install</p><p>To run Sunspot generator, use</p><p>$ rails g sunspot_rails:install</p><p>The above steps will install Sunspot and RSolr as dependencies.</p><p><strong>To Configure Solr that is a standalone HTTP Server use following command</strong></p><p>$ rake sunspot:solr:start</p><p>The above command creates solr/ directory in Rails root consisting of Solr&#8217; configurations and data files for Solr index. To change the configuration, you can check solr/conf file.</p><p>Full text search is basically a combination of two tasks:</p><ol><li>Indexing</li><li>Searching/ Querying</li></ol><p>Lets go through each of them one by one :</p><p><strong>Defining an Index</strong>:</p><p>Suppose, I have a Book model with title, description, published and updated_at fields. Book model belongs to Author</p><div id="gist-764613" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Book</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">belongs_to</span> <span class="ss">:auther</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="n">searchable</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">text</span> <span class="ss">:title</span><span class="p">,</span> <span class="ss">:default_boost</span> <span class="o">=&gt;</span> <span class="mi">2</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">text</span> <span class="ss">:description</span> </div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">time</span> <span class="ss">:updated_at</span>       <span class="c1"># for sorting by recent</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">integer</span> <span class="ss">:auther_id</span><span class="p">,</span> <span class="ss">:multi</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="k">do</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">authers</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span><span class="o">|</span><span class="n">auther</span><span class="o">|</span> <span class="n">auther</span><span class="o">.</span><span class="n">auther_id</span><span class="p">}</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">boolean</span> <span class="ss">:published</span><span class="p">,</span> <span class="ss">:using</span> <span class="o">=&gt;</span> <span class="ss">:published?</span></div><div class='line' id='LC11'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">published?</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">state</span> <span class="o">==</span> <span class="ss">:published</span></div><div class='line' id='LC15'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC16'><br/></div><div class='line' id='LC17'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/764613/7bad907807e82e023ba00fbcc965399e6e93fc18/book.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/764613#file_book.rb" style="float:right;margin-right:10px;color:#666">book.rb</a> <a href="https://gist.github.com/764613">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div><p>Note here that, text fields are used for full-text search, while, other fields are just used for filtering / restricting / sorting. The <code>:default_boost</code> parameter means that, words matching the <code>:title</code> field should be  considered twice as relevant as, words matching the <code>:description</code> field.</p><p>For reindexing Book model&#8217;s records, You can use like <strong>Book.reindex!</strong>. For full reindex, you have to use rake sunspot:reindex</p><p><strong>Searching / Querying</strong><br /><div id="gist-763536" class="gist"><div class="gist-file"><div class="gist-data gist-syntax"><div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">BooksController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">search_results</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">search</span> <span class="o">=</span> <span class="no">Book</span><span class="o">.</span><span class="n">search</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">keywords</span> <span class="s1">&#39;Rails Programming&#39;</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">with</span><span class="p">(</span><span class="ss">:author_id</span><span class="p">)</span><span class="o">.</span><span class="n">any_of</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">8</span><span class="o">]</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">paginate</span> <span class="ss">:page</span> <span class="o">=&gt;</span> <span class="n">page_number</span><span class="p">,</span> <span class="ss">:per_page</span> <span class="o">=&gt;</span> <span class="mi">30</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">order_by</span> <span class="ss">:updated_at</span><span class="p">,</span> <span class="ss">:asc</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="vi">@results</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">results</span></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC11'><span class="k">end</span></div></pre></div></div><div class="gist-meta"> <a href="https://gist.github.com/raw/763536/49a8ade992a581660d7bf9706387d342dfdd42b1/BooksController.rb" style="float:right;">view raw</a> <a href="https://gist.github.com/763536#file_books_controller.rb" style="float:right;margin-right:10px;color:#666">BooksController.rb</a> <a href="https://gist.github.com/763536">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.</div></div></div> <br /> That&#8217;s it! It&#8217;s up and running with full text search functionality in rails.</p><p>Here are benefits of using Sunspot:</p><ul><li>It supports text,string,time,boolean and float fields.</li><li>It easily integrates geolocation indexing.</li><li>It uses flexible DSL for querying.</li><li>It playes nice with WillPaginate Plugin.</li></ul><div class="shr-publisher-1000"></div><p>No related posts.</p><img src="http://feeds.feedburner.com/~r/hemju/~4/mdnDJBRvphg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2011/01/04/full-text-search-with-sunspot-in-rails/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://hemju.com/2011/01/04/full-text-search-with-sunspot-in-rails/</feedburner:origLink></item> <item><title>Quicktip: Generating Entity-Relationship Diagrams for Ruby on Rails</title><link>http://feedproxy.google.com/~r/hemju/~3/UqesSq9pC-I/</link> <comments>http://hemju.com/2010/10/06/quicktip-generating-entity-relationship-diagrams-for-ruby-on-rails/#comments</comments> <pubDate>Wed, 06 Oct 2010 09:04:11 +0000</pubDate> <dc:creator>Helmut M. Juskewycz</dc:creator> <category><![CDATA[development]]></category> <category><![CDATA[Documentation]]></category> <category><![CDATA[Quicktip]]></category> <category><![CDATA[Rails]]></category> <category><![CDATA[Rails3]]></category> <category><![CDATA[RubyMine]]></category> <category><![CDATA[Tips]]></category><guid isPermaLink="false">http://www.hemju.com/?p=925</guid> <description><![CDATA[I am not a big fan of documentation. In my experience most documentation just exists for its own sake and normally nobody cares about it. In my mind, the code itself should be so expressive that nearly no documentation is needed (libraries and frameworks are the exception to this rule). Luckily, Ruby allows the most [...] <b>Related posts:</b><ol><li><a href='http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/' rel='bookmark' title='Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading'>Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading</a></li><li><a href='http://hemju.com/2011/02/21/quicktip-finding-deprecated-constantsmethods-easily/' rel='bookmark' title='Quicktip: Finding deprecated constants/methods easily'>Quicktip: Finding deprecated constants/methods easily</a></li><li><a href='http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/' rel='bookmark' title='Rails 3 Quicktip: Auto reload lib folders in development mode'>Rails 3 Quicktip: Auto reload lib folders in development mode</a></li></ol>]]></description> <content:encoded><![CDATA[<p>I am not a big fan of documentation. In my experience most documentation just exists for its own sake and normally nobody cares about it. In my mind, the code itself should be so expressive that nearly no documentation is needed (libraries and frameworks are the exception to this rule). Luckily, Ruby allows the most expressive code I have ever seen, the actual code reads like a documentation.</p><p>However, <strong>sometimes</strong> documentation is really helpful. For example as an entity relationship diagram (ERD) of your domain model. With such a diagram you easily comprehend the relationships between the models. Creating an ERD manually is cumbersome and manual generated content tends to get outdated. Hence, we are looking for an auto generation tool for ERD.</p><h3>RubyMine (IDE)</h3><p><a href="http://www.jetbrains.com/ruby/">RubyMine</a> is a Ruby/Rails IDE from <a href="http://www.jetbrains.com">JetBrains</a> and it comes with an integrated ERD viewer. As an example I checked out <a href="http://github.com/rubygems/gemcutter">Gemcutter</a> (the Rails app behind <a href="http://rubygems.org/">RubyGems</a>) and imported it as a project into RubyMine. Next open View/Show Model Dependency Diagram and you will see the ERD. You can export the image with the 4th button from the right (the one with the arrow).</p><p><a href="http://hemju.com/wp-content/uploads/2010/10/rubymine-open_diagram1.png"><img class="aligncenter size-medium wp-image-926" title="rubymine open diagram" src="http://hemju.com/wp-content/uploads/2010/10/rubymine-open_diagram-240x3001.png" alt="RubyMine Open ERD" width="240" height="300" /></a></p><p>Here is the result:</p><p><a href="http://hemju.com/wp-content/uploads/2010/10/rubymine-diagram1.png"><img class="aligncenter size-medium wp-image-927" title="rubymine-diagram" src="http://hemju.com/wp-content/uploads/2010/10/rubymine-diagram-300x2211.png" alt="RubyMine generated ERD" width="300" height="221" /></a></p><h3>Rails-ERD</h3><p>Because not everyone is using RubyMine (or even an IDE!), here another way to generate the diagram using the <a href="http://rails-erd.rubyforge.org/">Rails-ERD</a> gem. Follow the <a href="http://rails-erd.rubyforge.org/install.html">installations instructions</a> for your operating system (sorry Windows, just Unix). I recommend using <a href="http://github.com/mxcl/homebrew">Homebrew</a> which is just awesome. Then add the gem to the application&#8217;s Gemfile (gem &#8220;rails-erd&#8221;) and run <em>bundle install </em>from your application&#8217;s root. After that there is a new Rake task available called &#8220;erd&#8221;. When you run the task, it will generate an ERD as pdf (for more <a href="http://rails-erd.rubyforge.org/customise.html">output options</a>). Using Rails-ERD in our example Gemcutter project, produces <a href="http://hemju.com/wp-content/uploads/2010/10/ERD.pdf">this pdf</a>.</p><h3>Final Thoughts</h3><p>When you compare the diagram from RubyMine with the diagram from Rails-ERD, you will see that they are different. This is because RubyMine generates the diagram based on the classes in the Model folder, while Rails-ERD seems to inspect the actual database models. Further, Rails-ERD shows only the relationships without the type (1:n, m:n), while RubyMine shows it. Nevertheless, both provide a quick and useful view of the database schema and it is generated automatically, hence always up to date.</p> <a style="visibility:hidden;color:white;" href="http://www.lingui.st">Lingui.st - Online Resource Editor, Manage your Ruby/Rails, Java, .Net and C++ language files with ease</a><div class="shr-publisher-925"></div><p><b>Related posts:</b><ol><li><a href='http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/' rel='bookmark' title='Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading'>Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading</a></li><li><a href='http://hemju.com/2011/02/21/quicktip-finding-deprecated-constantsmethods-easily/' rel='bookmark' title='Quicktip: Finding deprecated constants/methods easily'>Quicktip: Finding deprecated constants/methods easily</a></li><li><a href='http://hemju.com/2011/02/11/rails-3-quicktip-auto-reload-lib-folders-in-development-mode/' rel='bookmark' title='Rails 3 Quicktip: Auto reload lib folders in development mode'>Rails 3 Quicktip: Auto reload lib folders in development mode</a></li></ol></p><img src="http://feeds.feedburner.com/~r/hemju/~4/UqesSq9pC-I" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://hemju.com/2010/10/06/quicktip-generating-entity-relationship-diagrams-for-ruby-on-rails/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://hemju.com/2010/10/06/quicktip-generating-entity-relationship-diagrams-for-ruby-on-rails/</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: wp.hemju.com @ 2012-01-21 12:54:10 -->

