<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jetpack Flight Log &#187; rails</title>
	<atom:link href="http://jetpackweb.com/blog/topics/ruby/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://jetpackweb.com/blog</link>
	<description>Rock{et}ing the interweb</description>
	<lastBuildDate>Sun, 12 Jun 2011 17:51:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Pretty Paging in Rails Console</title>
		<link>http://jetpackweb.com/blog/2011/01/20/pretty-paging-in-rails-console/</link>
		<comments>http://jetpackweb.com/blog/2011/01/20/pretty-paging-in-rails-console/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 22:07:44 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=859</guid>
		<description><![CDATA[When using irb or Rails console I use the awesome_print gem to get nicer colorized output. I also like to use looksee to examine method lookup paths which the gem colorizes nicely. For large objects looksee can produce a lot of output and if there is more output than your terminal can display at once [...]]]></description>
			<content:encoded><![CDATA[<p>When using irb or Rails console I use the <a href="https://github.com/michaeldv/awesome_print" target="_blank">awesome_print</a> gem to get nicer colorized output. I also like to use <a href="https://github.com/oggy/looksee">looksee</a> to examine method lookup paths which the gem colorizes nicely. For large objects looksee can produce a lot of output and if there is more output than your terminal can display at once it will get handed off to your system&#8217;s pager (probably <a href="http://en.wikipedia.org/wiki/Less_(Unix)">less</a>). I was having an issue while in Rails console when the output got paged it would show the ANSI color escape codes rather than colorized text (this didn&#8217;t happen in irb for whatever reason).</p>
<p>Luckily <em>less</em> has a flag that will repaint the screen when paging. To make it a default you need to export a LESS variable to your shell&#8217;s environment. Something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">export</span> <span class="re2">LESS</span>=<span class="st0">&quot;-R&quot;</span></pre></div></div>

<p>Just throw that in your ~/.bashrc or <a href="https://github.com/anveo/dotfiles/commit/db1f89cd9b8e50525bca3901bcf7f121cab41ce8#L0R3" target="_blank">dotfiles</a> and you&#8217;re all set!</p>
<p><img class="aligncenter size-large wp-image-868" title="Screenshot-Terminal" src="http://jetpackweb.com/blog/wp-content/uploads/2011/01/Screenshot-Terminal-1024x550.png" alt="" width="950" height="525" /></p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2011/01/20/pretty-paging-in-rails-console/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making monit, delayed_job, and bundler play nice together</title>
		<link>http://jetpackweb.com/blog/2010/05/19/making-monit-delayed_job-and-bundler-play-nice-together/</link>
		<comments>http://jetpackweb.com/blog/2010/05/19/making-monit-delayed_job-and-bundler-play-nice-together/#comments</comments>
		<pubDate>Wed, 19 May 2010 22:21:53 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[bundler]]></category>
		<category><![CDATA[delayed_job]]></category>
		<category><![CDATA[monit]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=831</guid>
		<description><![CDATA[Recently I was having a heck of a time getting monit to start my delayed_job instances. I was using the monit template that came with delayed job, it looks something like this: check process delayed_job_bandwith_prod with pidfile /home/bandwith/apps/production/shared/pids/delayed_job.pid start program = &#34;/usr/bin/env RAILS_ENV=production /home/bandwith/apps/production/current/script/delayed_job start&#34; as uid bandwith and gid bandwith stop program = &#34;/usr/bin/env [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was having a heck of a time getting <a href="http://mmonit.com/monit/" target="_blank">monit</a> to start my <a href="http://github.com/collectiveidea/delayed_job" target="_blank">delayed_job</a> instances. I was using the monit template that came with delayed job, it looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">check process delayed_job_bandwith_prod 
  with pidfile <span class="sy0">/</span>home<span class="sy0">/</span>bandwith<span class="sy0">/</span>apps<span class="sy0">/</span>production<span class="sy0">/</span>shared<span class="sy0">/</span>pids<span class="sy0">/</span>delayed_job.pid
  start program = <span class="st0">&quot;/usr/bin/env RAILS_ENV=production /home/bandwith/apps/production/current/script/delayed_job start&quot;</span> <span class="kw2">as</span> uid bandwith and gid bandwith 
  stop program  = <span class="st0">&quot;/usr/bin/env RAILS_ENV=production /home/bandwith/apps/production/current/script/delayed_job stop&quot;</span> <span class="kw2">as</span> uid bandwith and gid bandwith</pre></div></div>

<p>This did not work however, and after quite a bit of debugging I found there are a couple of issues you might need to be aware of:</p>
<h2>1. Your $PATH</h2>
<p>monit starts things with a &#8216;<em>spartan path</em>&#8216; of:</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="sy0">/</span>bin:<span class="sy0">/</span>usr<span class="sy0">/</span>bin:<span class="sy0">/</span>sbin:<span class="sy0">/</span>usr<span class="sy0">/</span>sbin</pre></div></div>

<p>My ruby happens to be in /usr/local/bin, so we will need to pass that in too:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">start program = <span class="st0">&quot;/usr/bin/env PATH=/usr/local/bin:PATH RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start&quot;</span></pre></div></div>

<h2>2. monit doesn&#8217;t define a $HOME environment variable</h2>
<p>Even though we are starting these processes with uids and guids specified, that doesn&#8217;t actually load the users shell. With no $HOME env variable, <a href="http://gembundler.com/" target="_blank">bundler</a> can&#8217;t find where your gems are installed and thinks they are all missing. I ended up just putting the variable in the monit command, another option might be running <em>su -c &#8216;{command}&#8217;</em> (I didn&#8217;t test that).</p>
<p>So putting that all together you get the following which should make everything work:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">check process delayed_job_bandwith_prod 
  with pidfile <span class="sy0">/</span>home<span class="sy0">/</span>bandwith<span class="sy0">/</span>apps<span class="sy0">/</span>production<span class="sy0">/</span>shared<span class="sy0">/</span>pids<span class="sy0">/</span>delayed_job.pid
  start program = <span class="st0">&quot;/usr/bin/env HOME=/home/bandwith PATH=/usr/local/bin:<span class="es2">$PATH</span> RAILS_ENV=production /home/bandwith/apps/production/current/script/delayed_job start&quot;</span> <span class="kw2">as</span> uid bandwith and gid bandwith 
  stop program  = <span class="st0">&quot;/usr/bin/env HOME=/home/bandwith PATH=/usr/local/bin:<span class="es2">$PATH</span> RAILS_ENV=production /home/bandwith/apps/production/current/script/delayed_job stop&quot;</span> <span class="kw2">as</span> uid bandwith and gid bandwith</pre></div></div>

<p>I would be interested to know if anyone has any better suggestions, but this seems to be working nicely.</p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2010/05/19/making-monit-delayed_job-and-bundler-play-nice-together/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Vim Tips for Ruby (and your wrists)</title>
		<link>http://jetpackweb.com/blog/2010/02/15/vim-tips-for-ruby/</link>
		<comments>http://jetpackweb.com/blog/2010/02/15/vim-tips-for-ruby/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 18:02:08 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=688</guid>
		<description><![CDATA[Each time I am forced to type non-alpha-numeric characters during a coding session I feel that the flow and speed of my typing suffers. Not to mention depending on the size of your hands and how (im)properly you type, those keys can also put extra strain on your wrists. Since Ruby and Rails make extensive [...]]]></description>
			<content:encoded><![CDATA[<p>Each time I am forced to type non-alpha-numeric characters during a coding session I feel that the flow and speed of my typing suffers. Not to mention depending on the size of your hands and how (im)properly you type, those keys can also put extra strain on your wrists. Since Ruby and Rails make extensive use of <strong>:</strong>symbols and hash-rockets ( <strong>=></strong> ) I felt the need to optimize their entry. </p>
<h3><strong>Hash-Rocket Insertion</strong></h3>

<div class="wp_syntax"><div class="code"><pre class="vim"><span class="co1">&quot; bind control-l to hashrocket</span>
imap <span class="sy0">&lt;</span>C<span class="sy0">-</span>l<span class="sy0">&gt;</span> <span class="sy0">&lt;</span>Space<span class="sy0">&gt;</span>=<span class="sy0">&gt;&lt;</span>Space<span class="sy0">&gt;</span><span class="co1">&quot;</span></pre></div></div>

<p>This emulates TextMate&#8217;s hash-rocket insertion. Just press Ctrl-L when in insert mode for a hash-rocket and leading quote to be inserted. Thanks to <a href="http://technicalpickles.com/posts/vimpocalypse/" target="_blank">TechnicalPickles</a> for this one.</p>
<p>If you use this with <a href="http://www.vim.org/scripts/script.php?script_id=1849" target="_blank">autoClose.vim</a> the trailing quote will be inserted too. There are times when you don&#8217;t want  quotes surrounding the hash value like booleans and symbols, so use <a href="http://www.vim.org/scripts/script.php?script_id=1697" target="_blank">surround.vim</a> and type <strong>ds&#8221;</strong>. <i>Poof!</i> gone are the quotes.</p>
<h3><strong>Word to Symbol</strong></h3>

<div class="wp_syntax"><div class="code"><pre class="vim"><span class="co1">&quot; convert word into ruby symbol</span>
imap <span class="sy0">&lt;</span>C<span class="sy0">-</span>k<span class="sy0">&gt;</span> <span class="sy0">&lt;</span>C<span class="sy0">-</span>o<span class="sy0">&gt;</span>b<span class="sy0">:&lt;</span>Esc<span class="sy0">&gt;</span>Ea
nmap <span class="sy0">&lt;</span>C<span class="sy0">-</span>k<span class="sy0">&gt;</span> lbi<span class="sy0">:&lt;</span>Esc<span class="sy0">&gt;</span>E</pre></div></div>

<p>This will turn any word into a symbol by prefixing it with a colon. It works in either Insert or Command mode. In command mode just place your cursor over the word and press Ctrl-k. While in Insert mode pressing Ctrl-k will convert the current word you are typing into a symbol.</p>
<p>You could probably make the argument it&#8217;s easier just to type the colon.  To each his own but I have seen a lot of people who bend their right wrist to press both <strong>Shift</strong> and <strong>;</strong> entirely with their right hand which puts strain on the wrist. Since symbols are often used right before the hash-rocket, chaining these two shortcuts can be a bit more fluid IMHO(the caret denotes the cursor position):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">render action^<span class="sy0">&lt;</span>Ctrl<span class="sy0">-</span>k<span class="sy0">&gt;&lt;</span>Ctrl<span class="sy0">-</span>l<span class="sy0">&gt;</span>
&nbsp;
<span class="co1"># Will be transformed to</span>
&nbsp;
render <span class="re3">:action</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;^&quot;</span></pre></div></div>

<h3><strong>Symbol to Proc snippets</strong></h3>

<div class="wp_syntax"><div class="code"><pre class="ruby">snippet collecta
             collect<span class="br0">&#40;</span><span class="sy0">&amp;</span>:$<span class="br0">&#123;</span><span class="nu0">1</span>:symbol<span class="br0">&#125;</span><span class="br0">&#41;</span>$<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span>
snippet mapa
             map<span class="br0">&#40;</span><span class="sy0">&amp;</span>:$<span class="br0">&#123;</span><span class="nu0">1</span>:symbol<span class="br0">&#125;</span><span class="br0">&#41;</span>$<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span></pre></div></div>

<p>The <strong>collection.collect(&amp;:symbol)</strong> is a great shortcut I use often in Rails, these <a href="http://www.vim.org/scripts/script.php?script_id=2540" target="_blank">snipMate.vim</a> snippets make for less awkward entry.</p>
<h3><strong>Easy Command Mode Entry</strong></h3>

<div class="wp_syntax"><div class="code"><pre class="vim"><span class="co1">&quot; Easier non-interactive command insertion</span>
<span class="kw1">nnoremap</span> <span class="sy0">&lt;</span>Space<span class="sy0">&gt;</span> <span class="sy0">:</span></pre></div></div>

<p>This one has nothing to do with Ruby, but instead of typing the colon every time to want to enter a new command in Command mode, just hit the spacebar!</p>
<h3><strong>Swap Esc and Caps-Lock</strong></h3>
<p>Another tip not specific to Ruby or even Vim really. I think using the Caps-Lock key as escape in Vim is the most efficient and quickest way to cancel some commands or exit certain modes. I prefer to swap them at the Operating System level rather than .vimrc hacks because I find the switch convenient in almost all applications, not just Vim. Consult Google to find out how to do it in your OS.</p>
<h3><strong>Conclusion</strong></h3>
<p>That&#8217;s it! If anyone has any other vim tips for ruby I would love to hear them!  Also feel free to dig through my <a href="http://github.com/anveo/dotfiles" target="_blank">dotfiles</a> and <a href="http://github.com/anveo/vimfiles" target="_blank">vimfiles</a> to glean other tips.</p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2010/02/15/vim-tips-for-ruby/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Monitoring delayed_job with god on CentOS</title>
		<link>http://jetpackweb.com/blog/2009/11/02/monitoring-delayed_job-with-god-on-centos/</link>
		<comments>http://jetpackweb.com/blog/2009/11/02/monitoring-delayed_job-with-god-on-centos/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 22:24:51 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[delayed_job]]></category>
		<category><![CDATA[god]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=570</guid>
		<description><![CDATA[I recently started using god rather than monit for process monitoring. god lets me be a bit more expressive with how I want processes monitored using the the power of Ruby. The current project I am working on has a number of tasks that I want processed asynchronously so I will setup god to monitor [...]]]></description>
			<content:encoded><![CDATA[<p>I recently started using <a href="http://god.rubyforge.org/" target="_blank">god</a> rather than <a href="http://mmonit.com/monit/" target="_blank">monit</a> for process monitoring. <strong>god</strong> lets me be a bit more expressive with how I want processes monitored using the the power of Ruby.</p>
<p>The current project I am working on has a number of tasks that I want processed asynchronously so I will setup <strong>god</strong> to monitor my <a href="http://github.com/collectiveidea/delayed_job" target="_blank">delayed_jobs</a>. If you are not familiar with awesome delayed_job gem, watch the excellent <a href="http://railscasts.com/episodes/171-delayed-job" target="_blank">Railscast tutorial</a>.</p>
<p>First install the god gem:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> gem <span class="kw2">install</span> god</pre></div></div>

<p>Next we will create a Redhat compatible init script for god:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> <span class="kw2">vi</span> <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>god
&nbsp;
<span class="co0">#!/bin/bash</span>
<span class="co0">#</span>
<span class="co0"># God</span>
<span class="co0">#</span>
<span class="co0"># chkconfig: - 85 15</span>
<span class="co0"># description: start, stop, restart God (bet you feel powerful)</span>
<span class="co0">#</span>
&nbsp;
<span class="re2">RETVAL</span>=<span class="nu0">0</span>
&nbsp;
<span class="kw1">case</span> <span class="st0">&quot;$1&quot;</span> <span class="kw1">in</span>
    start<span class="br0">&#41;</span>
      <span class="sy0">/</span>usr<span class="sy0">/</span>bin<span class="sy0">/</span>god <span class="re5">-P</span> <span class="sy0">/</span>var<span class="sy0">/</span>run<span class="sy0">/</span>god.pid <span class="re5">-l</span> <span class="sy0">/</span>var<span class="sy0">/</span>log<span class="sy0">/</span>god.log
      <span class="sy0">/</span>usr<span class="sy0">/</span>bin<span class="sy0">/</span>god load <span class="sy0">/</span>etc<span class="sy0">/</span>god.conf
      <span class="re2">RETVAL</span>=<span class="re4">$?</span>
      <span class="sy0">;;</span>
    stop<span class="br0">&#41;</span>
      <span class="kw2">kill</span> <span class="sy0">`</span><span class="kw2">cat</span> <span class="sy0">/</span>var<span class="sy0">/</span>run<span class="sy0">/</span>god.pid<span class="sy0">`</span>
      <span class="re2">RETVAL</span>=<span class="re4">$?</span>
      <span class="sy0">;;</span>
    restart<span class="br0">&#41;</span>
      <span class="kw2">kill</span> <span class="sy0">`</span><span class="kw2">cat</span> <span class="sy0">/</span>var<span class="sy0">/</span>run<span class="sy0">/</span>god.pid<span class="sy0">`</span>
      <span class="sy0">/</span>usr<span class="sy0">/</span>bin<span class="sy0">/</span>god <span class="re5">-P</span> <span class="sy0">/</span>var<span class="sy0">/</span>run<span class="sy0">/</span>god.pid <span class="re5">-l</span> <span class="sy0">/</span>var<span class="sy0">/</span>log<span class="sy0">/</span>god.log
      <span class="sy0">/</span>usr<span class="sy0">/</span>bin<span class="sy0">/</span>god load <span class="sy0">/</span>etc<span class="sy0">/</span>god.conf
      <span class="re2">RETVAL</span>=<span class="re4">$?</span>
      <span class="sy0">;;</span>
    status<span class="br0">&#41;</span>      
      <span class="sy0">/</span>usr<span class="sy0">/</span>bin<span class="sy0">/</span>god status
      <span class="re2">RETVAL</span>=<span class="re4">$?</span>
      <span class="sy0">;;</span>
    <span class="sy0">*</span><span class="br0">&#41;</span>
      <span class="kw3">echo</span> <span class="st0">&quot;Usage: god {start|stop|restart|status}&quot;</span>
      <span class="kw3">exit</span> <span class="nu0">1</span>
  <span class="sy0">;;</span>
<span class="kw1">esac</span>
&nbsp;
<span class="kw3">exit</span> <span class="re1">$RETVAL</span></pre></div></div>

<h6>(adapted from debian version at <a href="http://mylescarrick.com/articles/simple_delayed_job_with_god" target="_blank">http://mylescarrick.com/articles/simple_delayed_job_with_god</a>)</h6>
<p>Now adjust the permissions, and set the init script to start on system boot:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> <span class="kw2">chmod</span> a+x <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>god
$ <span class="kw2">sudo</span> <span class="sy0">/</span>sbin<span class="sy0">/</span>chkconfig <span class="re5">--add</span> god
$ <span class="kw2">sudo</span> <span class="sy0">/</span>sbin<span class="sy0">/</span>chkconfig <span class="re5">--level</span> <span class="nu0">345</span> god on</pre></div></div>

<p>Before we start <strong>god</strong> up, we need to create a configuration file that tells it what configuration files to load:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">$ sudo vi <span class="sy0">/</span>etc<span class="sy0">/</span>god.<span class="me1">conf</span>
&nbsp;
God.<span class="kw3">load</span> <span class="st0">&quot;/srv/apps/your_app/current/config/god/*.god&quot;</span></pre></div></div>

<p>You will need to adjust the above depending on how you have your app setup. When working in a Rails project I like to put my god scripts in <i>config/god</i>.</p>
<p>We will use <a href="http://github.com/blog/229-dj-god" target="_blank">a script</a> from the guys at github to monitor our job daemon. I tweaked it slightly to have less workers, and to set the environment properly.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">RAILS_ROOT = <span class="st0">&quot;/srv/apps/your_app/current&quot;</span>
&nbsp;
<span class="nu0">1</span>.<span class="me1">times</span> <span class="kw1">do</span> <span class="sy0">|</span>num<span class="sy0">|</span>
  God.<span class="me1">watch</span> <span class="kw1">do</span> <span class="sy0">|</span>w<span class="sy0">|</span>
    w.<span class="me1">name</span> = <span class="st0">&quot;dj-#{num}&quot;</span>
    w.<span class="me1">group</span> = <span class="st0">'dj'</span>
    w.<span class="me1">interval</span> = <span class="nu0">30</span>.<span class="me1">seconds</span>
    w.<span class="me1">start</span> = <span class="st0">&quot;rake -f #{RAILS_ROOT}/Rakefile RAILS_ENV=production jobs:work&quot;</span>
&nbsp;
    w.<span class="me1">uid</span> = <span class="st0">'your_app_user'</span>
    w.<span class="me1">gid</span> = <span class="st0">'your_app_user'</span>
&nbsp;
    <span class="co1"># retart if memory gets too high</span>
    w.<span class="me1">transition</span><span class="br0">&#40;</span><span class="re3">:up</span>, <span class="re3">:restart</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>on<span class="sy0">|</span>
      on.<span class="me1">condition</span><span class="br0">&#40;</span><span class="re3">:memory_usage</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>c<span class="sy0">|</span>
        c.<span class="me1">above</span> = <span class="nu0">300</span>.<span class="me1">megabytes</span>
        c.<span class="me1">times</span> = <span class="nu0">2</span>
      <span class="kw1">end</span>
    <span class="kw1">end</span>
&nbsp;
    <span class="co1"># determine the state on startup</span>
    w.<span class="me1">transition</span><span class="br0">&#40;</span><span class="re3">:init</span>, <span class="br0">&#123;</span> <span class="kw2">true</span> <span class="sy0">=&gt;</span> <span class="re3">:up</span>, <span class="kw2">false</span> <span class="sy0">=&gt;</span> <span class="re3">:start</span> <span class="br0">&#125;</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>on<span class="sy0">|</span>
      on.<span class="me1">condition</span><span class="br0">&#40;</span><span class="re3">:process_running</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>c<span class="sy0">|</span>
        c.<span class="me1">running</span> = <span class="kw2">true</span>
      <span class="kw1">end</span>
    <span class="kw1">end</span>
&nbsp;
    <span class="co1"># determine when process has finished starting</span>
    w.<span class="me1">transition</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span class="re3">:start</span>, <span class="re3">:restart</span><span class="br0">&#93;</span>, <span class="re3">:up</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>on<span class="sy0">|</span>
      on.<span class="me1">condition</span><span class="br0">&#40;</span><span class="re3">:process_running</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>c<span class="sy0">|</span>
        c.<span class="me1">running</span> = <span class="kw2">true</span>
        c.<span class="me1">interval</span> = <span class="nu0">5</span>.<span class="me1">seconds</span>
      <span class="kw1">end</span>
&nbsp;
      <span class="co1"># failsafe</span>
      on.<span class="me1">condition</span><span class="br0">&#40;</span><span class="re3">:tries</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>c<span class="sy0">|</span>
        c.<span class="me1">times</span> = <span class="nu0">5</span>
        c.<span class="me1">transition</span> = <span class="re3">:start</span>
        c.<span class="me1">interval</span> = <span class="nu0">5</span>.<span class="me1">seconds</span>
      <span class="kw1">end</span>
    <span class="kw1">end</span>
&nbsp;
    <span class="co1"># start if process is not running</span>
    w.<span class="me1">transition</span><span class="br0">&#40;</span><span class="re3">:up</span>, <span class="re3">:start</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>on<span class="sy0">|</span>
      on.<span class="me1">condition</span><span class="br0">&#40;</span><span class="re3">:process_running</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>c<span class="sy0">|</span>
        c.<span class="me1">running</span> = <span class="kw2">false</span>
      <span class="kw1">end</span>
    <span class="kw1">end</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div>

<p>It&#8217;s now time to start the daemon:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>god start
$ <span class="kw2">sudo</span> <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>god status
dj:
  dj-<span class="nu0">0</span>: up</pre></div></div>

<p>Looks good! If you want to make sure it&#8217;s working, kill the rake task running <strong>jobs:work</strong>. god will see that it is stopped and automatically restart it!</p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2009/11/02/monitoring-delayed_job-with-god-on-centos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails 2.3.4 and SWFUpload &#8211; Rack Middleware for Flash Uploads that Degrade Gracefully</title>
		<link>http://jetpackweb.com/blog/2009/10/21/rails-2-3-4-and-swfupload-rack-middleware-for-flash-uploads-that-degrade-gracefully/</link>
		<comments>http://jetpackweb.com/blog/2009/10/21/rails-2-3-4-and-swfupload-rack-middleware-for-flash-uploads-that-degrade-gracefully/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 05:24:15 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rack]]></category>
		<category><![CDATA[swfobject]]></category>
		<category><![CDATA[swfupload]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=523</guid>
		<description><![CDATA[Browser upload controls have been pretty much the same for years. They are very difficult to style, and do not look consistent across browsers. Perhaps the biggest issue with them is they provide no feedback to the user about how long the submission will take. One alternative is to use Flash for the uploads. There [...]]]></description>
			<content:encoded><![CDATA[<p>Browser upload controls have been pretty much the same for years. They are very difficult to style, and do not look consistent across browsers. Perhaps the biggest issue with them is they provide no feedback to the user about how long the submission will take. One alternative is to use Flash for the uploads. There are numerous libraries available, I like <a href="http://swfupload.org/" target="_blank">SWFUpload</a>. Since the reason you are here is probably because you can&#8217;t get it working in Rails, I&#8217;m going to try and help you deal with the quirks associated with using Flash and Rails together.</p>
<p>It used to be you would monkeypatch the CGI class to get Flash uploaders to work due to issues with Flash. With the introduction of <a href="http://rack.rubyforge.org/" target="_blank">Rack</a> in Rails 2.3 things now work quite differently. What we will do is create some rack middleware to intercept traffic from Flash to deal with it&#8217;s quirks. I have created a small example application of an mp3 player and uploader. You will probably want to download it, as it contains a few files not displayed in this article. You can clone it from the <a href="http://github.com/anveo/swfupload_demo" target="_blank">github project page</a>.</p>
<p>First lets create a simple Song model:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">.<span class="sy0">/</span>script generate model Song title:string artist:string length_in_seceonds:integer track_file_name:string track_content_type:string track_file_size:integer</pre></div></div>

<p><i>title</i>, <i>artist</i>, and <i>length_in_seconds</i> are meta-data we will pull from the ID3 tags of the uploaded mp3 file, and the rest will be used by <a href="http://www.thoughtbot.com/projects/paperclip" target="_blank">Paperclip</a> to handle the attachment. Lets add the paperclip attachment and a few simple validations to our new Song model:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="kw1">class</span> Song <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span>
&nbsp;
  has_attached_file <span class="re3">:track</span>,
                    <span class="re3">:path</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;:rails_root/public/assets/:attachment/:id_partition/:id/:style/:basename.:extension&quot;</span>,
                    <span class="re3">:url</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;/assets/:attachment/:id_partition/:id/:style/:basename.:extension&quot;</span>
&nbsp;
  validates_presence_of <span class="re3">:title</span>, <span class="re3">:artist</span>, <span class="re3">:length_in_seconds</span>
  validates_attachment_presence <span class="re3">:track</span>
  validates_attachment_content_type <span class="re3">:track</span>, <span class="re3">:content_type</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span> <span class="st0">'application/mp3'</span>, <span class="st0">'application/x-mp3'</span>, <span class="st0">'audio/mpeg'</span>, <span class="st0">'audio/mp3'</span> <span class="br0">&#93;</span>
  validates_attachment_size <span class="re3">:track</span>, <span class="re3">:less_than</span> <span class="sy0">=&gt;</span> <span class="nu0">20</span>.<span class="me1">megabytes</span>
&nbsp;
  attr_accessible <span class="re3">:title</span>, <span class="re3">:artist</span>, <span class="re3">:length_in_seconds</span>
&nbsp;
  <span class="kw1">def</span> convert_seconds_to_time
    total_minutes = length_in_seconds <span class="sy0">/</span> <span class="nu0">1</span>.<span class="me1">minutes</span>
    seconds_in_last_minute = length_in_seconds <span class="sy0">-</span> total_minutes.<span class="me1">minutes</span>.<span class="me1">seconds</span>
    <span class="st0">&quot;#{total_minutes}m #{seconds_in_last_minute}s&quot;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div>

<p>Next comes an upload form and some containers to hold the SWFUploader:</p>

<div class="wp_syntax"><div class="code"><pre class="haml">- form_tag songs_path, :multipart =&gt; true do
  #swfupload_degraded_container
    %noscript= &quot;You should have Javascript enabled for a nicer upload experience&quot;
    = file_field_tag :Filedata
    = submit_tag &quot;Add Song&quot;
  #swfupload_container{ :style =&gt; &quot;display: none&quot; }
    %span#spanButtonPlaceholder
  #divFileProgressContainer</pre></div></div>

<p>The container that holds the SWFUploader will be hidden until we know the user can support it. Initially a standard file upload form will display. A number of things can go wrong, so we need to think about a few levels of degradation here. The user might not have flash installed, the user might have an outdated version of flash, he might not have javascript installed or enabled(which is needed to load the flash), and there may be a problem downloading the flash swf file. Yikes. Luckily using the <a href="http://code.google.com/p/swfobject/" target="_blank">swfobject</a> library we can easily handle all these potential issues.</p>
<p>If the user is missing javascript, he will see the message in the <strong>noscript</strong> tag and be presented a standard upload control.</p>
<p>If the user is missing flash or it is outdated, he will be presented a dialog with an upgrade link. Otherwise he can use the standard upload control.</p>
<p>If  everything goes okey-dokey, then some function handlers we write will hide the the degradation container, and display the flash container.</p>
<p><i>Oh, and just so you know the current version of Flash Player for linux do not fire the event that monitors upload progress, so you will not get the status bar until the upload finishes. No work around for that right now.</i></p>
<p>So lets initialize the SWFUpload via some javascript. Many tutorials out there seem to put the authentication token and session information in the URL, but there are some options with current version of SWFUpload to POST and avoid that.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="sy0">:</span>javascript
  SWFUpload.<span class="kw3">onload</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw2">var</span> swf_settings <span class="sy0">=</span> <span class="br0">&#123;</span>
&nbsp;
      <span class="co1">// SWFObject settings</span>
      minimum_flash_version<span class="sy0">:</span> <span class="st0">&quot;9.0.28&quot;</span><span class="sy0">,</span>
      swfupload_pre_load_handler<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        $<span class="br0">&#40;</span><span class="st0">'#swfupload_degraded_container'</span><span class="br0">&#41;</span>.<span class="me1">hide</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        $<span class="br0">&#40;</span><span class="st0">'#swfupload_container'</span><span class="br0">&#41;</span>.<span class="me1">show</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="br0">&#125;</span><span class="sy0">,</span>
      swfupload_load_failed_handler<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
      post_params<span class="sy0">:</span> <span class="br0">&#123;</span>
        <span class="st0">&quot;#{session_key_name}&quot;</span><span class="sy0">:</span> <span class="st0">&quot;#{cookies[session_key_name]}&quot;</span><span class="sy0">,</span>
        <span class="st0">&quot;authenticity_token&quot;</span><span class="sy0">:</span> <span class="st0">&quot;#{form_authenticity_token}&quot;</span><span class="sy0">,</span>
      <span class="br0">&#125;</span><span class="sy0">,</span>
&nbsp;
      upload_url<span class="sy0">:</span> <span class="st0">&quot;#{songs_path}&quot;</span><span class="sy0">,</span>
      flash_url<span class="sy0">:</span> <span class="st0">'/flash/swfupload/swfupload.swf'</span><span class="sy0">,</span>
&nbsp;
      file_types<span class="sy0">:</span> <span class="st0">&quot;*.mp3&quot;</span><span class="sy0">,</span>
      file_types_description<span class="sy0">:</span> <span class="st0">&quot;mp3 Files&quot;</span><span class="sy0">,</span>
      file_size_limit<span class="sy0">:</span> <span class="st0">&quot;20 MB&quot;</span><span class="sy0">,</span>
&nbsp;
      button_placeholder_id<span class="sy0">:</span> <span class="st0">&quot;spanButtonPlaceholder&quot;</span><span class="sy0">,</span>
      button_width<span class="sy0">:</span> <span class="nu0">380</span><span class="sy0">,</span>
      button_height<span class="sy0">:</span> <span class="nu0">32</span><span class="sy0">,</span>
      button_text <span class="sy0">:</span> <span class="st0">'&lt;span class=&quot;button&quot;&gt;Select Files &lt;span class=&quot;buttonSmall&quot;&gt;(20 MB Max)&lt;/span&gt;&lt;/span&gt;'</span><span class="sy0">,</span>
      button_text_style <span class="sy0">:</span> <span class="st0">'.button { font-family: Helvetica, Arial, sans-serif; font-size: 24pt; } .buttonSmall { font-size: 18pt; }'</span><span class="sy0">,</span>
      button_text_top_padding<span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">,</span>
      button_text_left_padding<span class="sy0">:</span> <span class="nu0">18</span><span class="sy0">,</span>
      button_window_mode<span class="sy0">:</span> SWFUpload.<span class="me1">WINDOW_MODE</span>.<span class="me1">TRANSPARENT</span><span class="sy0">,</span>
      button_cursor<span class="sy0">:</span> SWFUpload.<span class="me1">CURSOR</span>.<span class="me1">HAND</span><span class="sy0">,</span>
      file_queue_error_handler <span class="sy0">:</span> fileQueueError<span class="sy0">,</span>
      file_dialog_complete_handler <span class="sy0">:</span> fileDialogComplete<span class="sy0">,</span>
      upload_progress_handler <span class="sy0">:</span> uploadProgress<span class="sy0">,</span>
      upload_error_handler <span class="sy0">:</span> uploadError<span class="sy0">,</span>
      upload_success_handler <span class="sy0">:</span> uploadSuccess<span class="sy0">,</span>
      upload_complete_handler <span class="sy0">:</span> uploadComplete<span class="sy0">,</span>
&nbsp;
      custom_settings <span class="sy0">:</span> <span class="br0">&#123;</span>
        upload_target<span class="sy0">:</span> <span class="st0">&quot;divFileProgressContainer&quot;</span>
      <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>
    <span class="kw2">var</span> swf_upload <span class="sy0">=</span> <span class="kw2">new</span> SWFUpload<span class="br0">&#40;</span>swf_settings<span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="sy0">;</span></pre></div></div>

<p>You will want to check out the <a href="http://demo.swfupload.org/Documentation/#settingsobject" target="_blank">official SWFUpload docs</a> to understand what all of these variable do. There are <a href="http://github.com/anveo/swfupload_demo/blob/master/public/javascripts/swfupload/handlers.js" target="_blank">many handlers</a> we have to define to handle various events, and if you clone the project you can review them in detail.</p>
<p>We also need to set styles for the containers that will be generated. You can see the Sass file I created for SWFUpload <a href="http://github.com/anveo/swfupload_demo/blob/master/app/stylesheets/swfupload.sass" target="_blank">here</a>, and <a href="http://github.com/anveo/swfupload_demo/blob/master/app/stylesheets/nifty.sass" target="_blank">another one</a> for Ryan Bates <a href="http://github.com/ryanb/nifty-generators" target="_blank">nifty_generators</a>.</p>
<p>Another quirk we have to be aware of when dealing with flash uploads is that everything gets a content-type of an octet stream. We will use the <a href="http://mime-types.rubyforge.org/" target="_blank">mime-types</a> library to identify it for validation. Keep in mind it only uses the extension to determine the file type. (<i>I haven&#8217;t tested it yet, but I believe <a href="http://github.com/mattetti/mimetype-fu" target="_blank">mimetype-fu</a> will actually check file-data and magic numbers</i>). By default SWFUpload calls the file parameter &#8216;Filedata&#8217;.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span class="kw1">def</span> create
    <span class="kw3">require</span> <span class="st0">'mp3info'</span>
&nbsp;
    mp3_info = Mp3Info.<span class="me1">new</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:Filedata</span><span class="br0">&#93;</span>.<span class="me1">path</span><span class="br0">&#41;</span>
&nbsp;
    song = Song.<span class="me1">new</span>
    song.<span class="me1">artist</span> = mp3_info.<span class="me1">tag</span>.<span class="me1">artist</span>
    song.<span class="me1">title</span> = mp3_info.<span class="me1">tag</span>.<span class="me1">title</span>
    song.<span class="me1">length_in_seconds</span> = mp3_info.<span class="me1">length</span>.<span class="me1">to_i</span>
&nbsp;
    params<span class="br0">&#91;</span><span class="re3">:Filedata</span><span class="br0">&#93;</span>.<span class="me1">content_type</span> = <span class="re2">MIME::Types</span>.<span class="me1">type_for</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:Filedata</span><span class="br0">&#93;</span>.<span class="me1">original_filename</span><span class="br0">&#41;</span>.<span class="me1">to_s</span>
    song.<span class="me1">track</span> = params<span class="br0">&#91;</span><span class="re3">:Filedata</span><span class="br0">&#93;</span>
    song.<span class="me1">save</span>
&nbsp;
    render <span class="re3">:text</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span>song.<span class="me1">artist</span>, song.<span class="me1">title</span>, song.<span class="me1">convert_seconds_to_time</span><span class="br0">&#93;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">&quot; - &quot;</span><span class="br0">&#41;</span>
  <span class="kw1">rescue</span> Mp3InfoError <span class="sy0">=&gt;</span> e
    render <span class="re3">:text</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;File error&quot;</span>
  <span class="kw1">rescue</span> <span class="kw4">Exception</span> <span class="sy0">=&gt;</span> e
    render <span class="re3">:text</span> <span class="sy0">=&gt;</span> e.<span class="me1">message</span>
  <span class="kw1">end</span></pre></div></div>

<p>Another annoyance with flash uploads is that it doesn&#8217;t send cookie data. That is why we are sending the session information in the POST data. We will intercept requests from Flash, check for the session key, and if so inject it into the cookie header. We can do this with some pretty simple middleware.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="kw3">require</span> <span class="st0">'rack/utils'</span>
&nbsp;
<span class="kw1">class</span> FlashSessionCookieMiddleware
  <span class="kw1">def</span> initialize<span class="br0">&#40;</span>app, session_key = <span class="st0">'_session_id'</span><span class="br0">&#41;</span>
    <span class="re1">@app</span> = app
    <span class="re1">@session_key</span> = session_key
  <span class="kw1">end</span>
&nbsp;
  <span class="kw1">def</span> call<span class="br0">&#40;</span>env<span class="br0">&#41;</span>
    <span class="kw1">if</span> env<span class="br0">&#91;</span><span class="st0">'HTTP_USER_AGENT'</span><span class="br0">&#93;</span> =~ <span class="sy0">/</span>^<span class="br0">&#40;</span>Adobe<span class="sy0">|</span>Shockwave<span class="br0">&#41;</span> Flash<span class="sy0">/</span>
      params = ::<span class="re2">Rack::Request</span>.<span class="me1">new</span><span class="br0">&#40;</span>env<span class="br0">&#41;</span>.<span class="me1">params</span>
      env<span class="br0">&#91;</span><span class="st0">'HTTP_COOKIE'</span><span class="br0">&#93;</span> = <span class="br0">&#91;</span> <span class="re1">@session_key</span>, params<span class="br0">&#91;</span>@session_key<span class="br0">&#93;</span> <span class="br0">&#93;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">'='</span><span class="br0">&#41;</span>.<span class="me1">freeze</span> <span class="kw1">unless</span> params<span class="br0">&#91;</span>@session_key<span class="br0">&#93;</span>.<span class="kw2">nil</span>?
    <span class="kw1">end</span>
    <span class="re1">@app</span>.<span class="me1">call</span><span class="br0">&#40;</span>env<span class="br0">&#41;</span>
  <span class="kw1">end</span>
<span class="kw1">end</span></pre></div></div>

<p>This is a modified version from code the appears in a few tutorials about flash uploads. It will allow the session information to be in the query string *or* POST data. Next we have to make sure this middleware gets put to use so in <i>config/initializers/session_store.rb</i> add:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="re2">ActionController::Dispatcher</span>.<span class="me1">middleware</span>.<span class="me1">insert_before</span><span class="br0">&#40;</span><span class="re2">ActionController::Base</span>.<span class="me1">session_store</span>, FlashSessionCookieMiddleware, <span class="re2">ActionController::Base</span>.<span class="me1">session_options</span><span class="br0">&#91;</span><span class="re3">:key</span><span class="br0">&#93;</span><span class="br0">&#41;</span></pre></div></div>

<p>And that&#8217;s, uhh, all there is too it. Again, I really suggest you <a href="http://github.com/anveo/swfupload_demo" target="_blank">checkout the example project</a>. It also uses the nifty WordPress Audio Player flash control to play the music you upload!</p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/Picture-21.png" /><br />
<img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/Picture-11.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2009/10/21/rails-2-3-4-and-swfupload-rack-middleware-for-flash-uploads-that-degrade-gracefully/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>High Quality Ruby on Rails Example Applications</title>
		<link>http://jetpackweb.com/blog/2009/10/14/high-quality-ruby-on-rails-example-applications/</link>
		<comments>http://jetpackweb.com/blog/2009/10/14/high-quality-ruby-on-rails-example-applications/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 19:37:16 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=450</guid>
		<description><![CDATA[Sometimes to best way to get up to speed with a new technology is learning by example. I have compiled a list of fully featured, production ready example applications that I consider to be of very decent quality. Most are RESTful and all have good-great test coverage. I listed components like the authentication, templating, and [...]]]></description>
			<content:encoded><![CDATA[<p><img alt="Ruby on Rails Logo" src="http://blogs.nitobi.com/alexei/wp-content/uploads/2008/04/ruby_on_rails_logo.jpg" title="Ruby on Rails Logo" width="116" height="156"  style="float: left" />Sometimes to best way to get up to speed with a new technology is learning by example. I have compiled a list of fully featured, production ready example applications that I consider to be of very decent quality. </p>
<p>Most are RESTful and all have good-great test coverage. I listed components like the authentication, templating, and testing frameworks they employ &#8211; perhaps useful if you are looking for examples of say <a href="http://cukes.info/" target="_blank">cucumber</a> stories, or maybe how to use <a href="http://haml-lang.com/" target="_blank">haml</a> markup. Also listed are some of the gems and plugins they leverage which I think are either useful or popular and worth checking out if you are not already familiar with them.</p>
<p>If you know of other quality apps I have missed just let me know in the comments section and I will add them. So in no particular order here they are &#8211; Enjoy!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/railscasts-logo.png" title="Railscast" /><br />
Homepage: <a href="http://railscasts.com/" target="_blank">http://railscasts.com/</a><br />
Github: <a href="http://github.com/ryanb/railscasts" target="_blank">http://github.com/ryanb/railscasts</a></p>
<p>You&#8217;ve probably seen his excellent video tutorials, but did you know Ryan Bates also gives away the code that powers his site?</p>
<p>Plugins: <a href="http://redcloth.org/" target="_blank">redcloth</a>, <a href="http://github.com/ryanb/acts-as-list" taret="_blank">acts-as-list</a>, <a href="http://github.com/mislav/will_paginate" target="_blank">will_paginate</a>, <a href="http://github.com/javan/whenever/" target="_blank">whenever</a><br />
Templates: ERB<br />
Testing: <a href="http://rspec.info/" target="_blank">RSpec</a>(controllers, helpers, models)<br />
Search: <a href="http://freelancing-god.github.com/ts/en/" target="_blank">ThinkingSphinx</a></p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/gumcutter-logo.png" title="Gemcutter" /><br />
Homepage: <a href="http://gemcutter.org/" target="_blank">http://gemcutter.org/</a><br />
Github: <a href="http://github.com/qrush/gemcutter" target="_blank">http://github.com/qrush/gemcutter</a></p>
<p>&#8220;Awesome gem hosting&#8221;. Good source of <a href="http://cukes.info/" target="_blank">cucumber</a> story examples. Also a few <a href="http://rack.rubyforge.org/" target="_blank">Rack</a> examples, including middleware that uses <a href="http://www.sinatrarb.com/" target="_blank">Sinatra</a> to serve files from <a href="http://aws.amazon.com/s3/" target="_blank">Amazon&#8217;s S3</a> service. Also some memcache action going on, and some <a href="http://github.com/tobi/delayed_job" target="_blank">delayed_job</a>s.</p>
<p>Authentication: <a href="http://github.com/thoughtbot/clearance" target="_blank">clearance</a><br />
Plugins: <a href="http://github.com/thoughtbot/pacecar" target="_blank">pacecar</a>, <a href="http://github.com/mislav/will_paginate" target="_blank">will_paginate</a>, <a href="http://github.com/thoughtbot/high_voltage" target="blank">high_voltage</a>, <a href="http://github.com/aaronchi/jrails" target="_blank">jrails</a><br />
Templates: ERB, also uses the <a href="http://960.gs/" target="_blank">960.gs grid framework</a><br />
Testing: <a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html" target="_blank">test unit</a>(functional, unit), <a href="http://www.thoughtbot.com/projects/factory_girl" target="_blank">Factory Girl</a>, <a href="http://www.thoughtbot.com/projects/shoulda" target="_blank">shoulda</a>, <a href="http://cukes.info/" target="_blank">cucumber</a><br />
Search: named_scopes</p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/spotus-logo.png" title="SpotUs" /><br />
Homepage: <a href="http://www.spot.us/" target="_blank">http://www.spot.us/</a><br />
Github: <a href="http://github.com/spot-us/spot-us" target="_blank">http://github.com/spot-us/spot-us</a></p>
<p>Crowdsourcing and Crowdfunding local news stories.</p>
<p>Authentication: <a href="http://github.com/technoweenie/restful-authentication" target="_blank">restful-authentication</a><br />
E-Commerce: <a href="http://www.activemerchant.org/ target="_blank">active_merchant</a>, <a href="http://github.com/rails/ssl_requirement" target="_blank">ssl_requirement</a><br />
Plugins: <a href="http://github.com/rubyist/aasm" target="_blank">acts_as_state_machine(aasm)</a>, <a href="http://fastercsv.rubyforge.org/" target="_blank">fastercsv</a>, <a href="http://github.com/Search: <a href="http://github.com/binarylogic/searchlogic" target="_blank">searchlogic</a>ctran/annotate_models&#8221; target=&#8221;_blank&#8221;>annotate_models</a>, <a href="http://github.com/giraffesoft/attribute_fu" target="_blank">attribute_fu</a>, <a href="http://www.thoughtbot.com/projects/paperclip" target=_blank">paperclip</a>, <a href="http://github.com/mbleigh/subdomain-fu" target="_blank">subdomain_fu</a><br />
Templates: <a href="http://haml-lang.com/" target="_blank">haml</a> (no <a href="http://sass-lang.com/" target="_blank">sass</a>), <a href="http://compass-style.org/" target="blank">compass</a><br />
Testing: <a href="http://rspec.info/" target="_blank">RSpec</a>(models, views, controllers, helpers), <a href="http://www.thoughtbot.com/projects/factory_girl" target="_blank">Factory Girl</a></p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/spree-logo.png" title="Spree" /><br />
Homepage: <a href="http://spreecommerce.com/" target="_blank">http://spreecommerce.com/</a><br />
Github: <a href="http://github.com/railsdog/spree" target="_blank">http://github.com/railsdog/spree</a></p>
<p>An <strong>excellent</strong> base to build ecommerce sites from.</p>
<p>Authentication: <a href="http://rdoc.info/projects/binarylogic/authlogic">authlogic</a><br />
E-Commerce: <a href="http://www.activemerchant.org/ target="_blank">active_merchant</a>, <a href="http://github.com/rails/ssl_requirement" target="_blank">ssl_requirement</a><br />
Plugins: <a href="http://github.com/pluginaweek/state_machine" target="_blank">pluginaweek-state_machine</a>, <a href="http://github.com/mislav/will_paginate" target="_blank">will_paginate</a>, <a href="http://github.com/javan/whenever/" target="_blank">whenever</a>, <a href="http://chronic.rubyforge.org/" target="_blank">chronic</a>, <a href="http://github.com/ryanb/acts-as-list" taret="_blank">acts-as-list</a>, <a href="http://github.com/giraffesoft/attribute_fu" target="_blank">attribute_fu</a>, <a href="http://github.com/collectiveidea/awesome_nested_set" target="_blank">awesome_nested_set</a>, <a href="http://www.thoughtbot.com/projects/paperclip" target=_blank">paperclip</a><br />
Templating: <a href="http://haml-lang.com/" target="_blank">haml</a>, <a href="http://compass-style.org/" target="blank">compass</a>, <a href="http://sass-lang.com/" target="_blank">sass</a><br />
Testing: <a href="http://rspec.info/" target="_blank">RSpec</a>(controllers, models), <a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html" target="_blank">test unit</a>(functional, unit)</p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/bostonrb-logo.png" title="Boston RB" /><br />
Homepage: <a href="http://bostonrb.org/" target="_blank">http://bostonrb.org/</a><br />
Github: <a href="http://github.com/bostonrb/bostonrb" target="_blank">http://github.com/bostonrb/bostonrb</a></p>
<p>This is a pretty cutting edge rails app. Follows <a href="http://www.thoughtbot.com/" target="_blank">ThoughtBot&#8217;s</a> best practices.</p>
<p>Authentication: <a href="http://github.com/thoughtbot/clearance" target="_blank">clearance</a><br />
Plugins: <a href="http://github.com/josevalim/inherited_resources" target="_blank">inherited_resources</a>, <a href="http://ar-versioned.rubyforge.org/" target="blank">acts_as_versioned</a>, <a href="http://github.com/flogic/autochronic" target="_blank">autochronic</a>, <a href="http://geokit.rubyforge.org/" target="_blank">geokit</a>, <a href="http://github.com/aaronchi/jrails" target="_blank">jrails</a><br />
Templating: <a href="http://haml-lang.com/" target="_blank">haml</a>, <a href="http://sass-lang.com/" target="_blank">sass</a><br />
Testing: <a href="http://mocha.rubyforge.org/" target="_blank">mocha</a>, <a href="http://www.thoughtbot.com/projects/shoulda" target="_blank">shoulda</a>, <a href="http://cukes.info/" target="_blank">cucumber</a>, <a href="http://www.thoughtbot.com/projects/factory_girl" target="_blank">Factory Girl</a>, <a href="http://wiki.github.com/brynary/webrat" target="_blank">webrat</a>, <a href="http://github.com/chrisk/fakeweb" target="_blank">fakeweb</a></p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/raildevelopmentdirectory-logo.png" title="Rails Development Directory" /><br />
Homepage: <a href="http://www.railsdevelopment.com/" target="_blank">http://www.railsdevelopment.com/</a><br />
Github: <a href="http://github.com/engineyard/rails_dev_directory" target="_blank">http://github.com/engineyard/rails_dev_directory</a></p>
<p>Here is a fresh new app just released from the guys at <a href="http://www.engineyard.com/" target="_blank">EngineYard</a>. An web directory of professional Rails development firms. Good example for dealing with internationalization(I18N) and localization(L10n). Also many <a href="http://cukes.info/" target="_blank">cucumber</a> features.</p>
<p>Authentication: <a href="http://rdoc.info/projects/binarylogic/authlogic">authlogic</a><br />
Authorization: <a href="http://github.com/paulca/can_has" target="_blank">can_has</a><br />
Plugins: <a href="http://github.com/rubyist/aasm" target="_blank">acts_as_state_machine(aasm)</a>, <a href="http://github.com/ryanb/acts-as-list" taret="_blank">acts-as-list</a>, <a href="http://www.thoughtbot.com/projects/paperclip" target=_blank">paperclip</a>, <a href="http://agilewebdevelopment.com/plugins/recaptcha" target="_blank">recaptcha</a>, <a href="http://redcloth.org/" target="_blank">redcloth</a>, <a href="http://github.com/paulca/shortcode-url" target="_blank">shortcode_url</a>, <a href="http://github.com/rails/ssl_requirement" target="_blank">ssl_requirement</a>, <a href="http://github.com/mislav/will_paginate" target="_blank">will_paginate</a>, <a href="http://code.google.com/p/xssterminate/" target="_blank">xss_terminate</a>, <a href="http://github.com/aaronchi/jrails" target="_blank">jrails</a><br />
Search: <a href="http://freelancing-god.github.com/ts/en/" target="_blank">ThinkingSphinx</a><br />
Testing: <a href="http://rspec.info/" target="_blank">RSpec</a>(controllers, helpers, models), <a href="http://cukes.info/" target="_blank">cucumber</a>, <a href="http://www.thoughtbot.com/projects/factory_girl" target="_blank">Factory Girl</a></p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/insochi-logo.png" title="Insoshi" /><br />
Homepage: <a href="http://dogfood.insoshi.com/" target="_blank">http://dogfood.insoshi.com/</a><br />
Github: <a href="http://github.com/insoshi/insoshi" target="_blank">http://github.com/insoshi/insoshi</a></p>
<p>An OpenSource social network platform in Rails</p>
<p>Authentication: <a href="http://github.com/technoweenie/restful-authentication" target="_blank">restful-authentication</a>, <a href="http://agilewebdevelopment.com/plugins/openidauthentication" target="_blank">open_id_authentication</a><br />
Plugins: <a href="http://github.com/ryanb/acts-as-list" taret="_blank">acts-as-list</a>, <a href="http://github.com/ctran/annotate_models" target="_blank">annotate_models</a>, <a href="http://github.com/technoweenie/attachment_fu" target="_blank">attachment_fu</a>, <a href="http://github.com/aaronchi/jrails" target="_blank">jrails</a><br />
Search: <a href="http://github.com/fauna/ultrasphinx" target="_blank">ultrasphinx</a><br />
Testing: <a href="http://rspec.info/" target="_blank">RSpec</a>(controllers, helpers, models, views)</p>
<h2>Bucketwise</h2>
<p>Homepage: <a href="http://wiki.github.com/jamis/bucketwise" target="_blank">http://wiki.github.com/jamis/bucketwise</a><br />
Github: <a href="http://github.com/jamis/bucketwise" target="_blank">http://github.com/jamis/bucketwise</a></p>
<p>A simple web based personal finance application. A pretty straight forward application that doesn&#8217;t leverage many plugins.</p>
<p>Testing: <a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html" target="_blank">test unit</a>(unit, functional)</p>
<h2>Fat Free CRM</h2>
<p>Homepage: <a href="http://fatfreecrm.com/" target="_blank">http://fatfreecrm.com/</a><br />
Github: <a href="http://github.com/michaeldv/fat_free_crm" target="_blank">http://github.com/michaeldv/fat_free_crm</a></p>
<p>Fat Free CRM is an open source Ruby on Rails-based customer relationship management platform. Out of the box it features group collaboration, campaign and lead management, contact lists, and opportunity tracking. </p>
<p>Authentication: <a href="http://rdoc.info/projects/binarylogic/authlogic">authlogic</a><br />
Plugins: <a href="http://github.com/jackdempsey/acts_as_commentable" target="_blank">acts_as_commentable</a>, <a href="http://github.com/markcatley/advanced_errors" target="_blank">advanced_errors</a>, <a href="http://github.com/ctran/annotate_models" target="_blank">annotate_models</a>, <a href="http://www.thoughtbot.com/projects/paperclip" target=_blank">paperclip</a>, <a href="http://github.com/mislav/will_paginate" target="_blank">will_paginate</a><br />
Search: <a href="http://www.railslodge.com/plugins/1331-simple-column-search" target="_blank">simple_column_search</a><br />
Templating: <a href="http://haml-lang.com/" target="_blank">haml</a>, <a href="http://sass-lang.com/" target="_blank">sass</a><br />
Testing: <a href="http://rspec.info/" target="_blank">RSpec</a>(controllers, helpers, models, routing, views), <a href="http://faker.rubyforge.org/" target="_blank">faker</a>, <a href="http://www.thoughtbot.com/projects/factory_girl" target="_blank">Factory Girl</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2009/10/14/high-quality-ruby-on-rails-example-applications/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Rails autocompletion in MacVim when using Macports</title>
		<link>http://jetpackweb.com/blog/2009/10/02/rails-autocompletion-in-macvim-when-using-macports/</link>
		<comments>http://jetpackweb.com/blog/2009/10/02/rails-autocompletion-in-macvim-when-using-macports/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 22:33:10 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[osx]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=439</guid>
		<description><![CDATA[In moving much of my development over to OS X, I started receiving errors when trying to use vim&#8217;s omnicompletion in Rails projects. An excerpt from my vim config to enable that functionality looks like this: &#34; Turn on language specific omnifuncs autocmd FileType ruby,eruby set omnifunc=rubycomplete#Complete autocmd FileType ruby,eruby let g:rubycomplete_buffer_loading = 1 autocmd [...]]]></description>
			<content:encoded><![CDATA[<p>In moving much of my development over to OS X, I started receiving errors when trying to use vim&#8217;s omnicompletion in Rails projects. An excerpt from my vim config to enable that functionality looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="vim"><span class="co1">&quot; Turn on language specific omnifuncs</span>
<span class="kw1">autocmd</span> <span class="kw3">FileType</span> ruby,eruby <span class="kw1">set</span> <span class="kw2">omnifunc</span>=rubycomplete#Complete
<span class="kw1">autocmd</span> <span class="kw3">FileType</span> ruby,eruby <span class="kw1">let</span> g<span class="sy0">:</span>rubycomplete_buffer_loading = <span class="nu0">1</span>
<span class="kw1">autocmd</span> <span class="kw3">FileType</span> ruby,eruby <span class="kw1">let</span> g<span class="sy0">:</span>rubycomplete_rails = <span class="nu0">1</span>
<span class="kw1">autocmd</span> <span class="kw3">FileType</span> ruby,eruby <span class="kw1">let</span> g<span class="sy0">:</span>rubycomplete_classes_in_global = <span class="nu0">1</span>
<span class="kw1">autocmd</span> <span class="kw3">FileType</span> ruby,eruby <span class="kw1">let</span> g<span class="sy0">:</span>rubycomplete_include_object = <span class="nu0">1</span>
<span class="kw1">autocmd</span> <span class="kw3">FileType</span> ruby,eruby <span class="kw1">let</span> g<span class="sy0">:</span>rubycomplete_include_objectspace = <span class="nu0">1</span></pre></div></div>

<p>When I tried to auto-complete something(Ctrl^X^O), I would receive the following error:</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="st0">&quot;-- Omni completion (^O^N^P) -- Searching...Rails requires RubyGems &gt;= 1.3.5 (you have 1.0.1). Please <span class="es5">`gem update --system`</span> and try again. Error loading rails environment&quot;</span></pre></div></div>

<p>Long story short, I was using MacPort&#8217;s ruby/gem packages, but a binary snapshot of MacVim that I downloaded off their website was using the libraries that come with OSX. There is not really a clean workaround for that, but luckily it turns out macport&#8217;s macvim builds the latest snapshot. So all you need to is to install macvim with ruby support:</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> port <span class="kw2">install</span> macvim +ruby</pre></div></div>

<p>And you will get nice auto-completion:</p>
<p><a href="http://jetpackweb.com/blog/wp-content/uploads/2009/10/macvim_omnicomplete.png"><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/10/macvim_omnicomplete-300x221.png" alt="macvim_omnicomplete" title="macvim_omnicomplete" width="300" height="221" class="aligncenter size-medium wp-image-444" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2009/10/02/rails-autocompletion-in-macvim-when-using-macports/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Munin Graphs for Phusion Passenger (a.k.a. mod_rails)</title>
		<link>http://jetpackweb.com/blog/2009/09/29/munin-graphs-for-phusion-passenger-a-k-a-mod_rails/</link>
		<comments>http://jetpackweb.com/blog/2009/09/29/munin-graphs-for-phusion-passenger-a-k-a-mod_rails/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 16:54:05 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[cpanel]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[munin]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=408</guid>
		<description><![CDATA[The goal of this article is to get fairly nice looking graphs of Phusion Passenger&#8217;s performance and memory metrics: This specific setup focuses on CentOS (on cPanel none the less) &#8211; but instructions should apply for most linux distros. It assumes you already have Passenger and Munin successfully setup. See my previous article on getting [...]]]></description>
			<content:encoded><![CDATA[<p>The goal of this article is to get fairly nice looking graphs of <a href="http://www.modrails.com/" target="_blank">Phusion Passenger&#8217;s</a> performance and memory metrics:</p>
<p><img src="http://jetpackweb.com/blog/wp-content/uploads/2009/09/passenger_memory_stats.png" /><br />
<img src="http://jetpackweb.com/blog/wp-content/uploads/2009/09/passenger_status.png" /></p>
<p>This specific setup focuses on CentOS (on cPanel none the less) &#8211; but instructions should apply for most linux distros. It assumes you already have Passenger and Munin successfully setup. See my <a href="http://jetpackweb.com/blog/2009/07/21/install-phusion-passenger-a-k-a-mod_rails-on-cpanel-server/">previous article</a> on getting Phusion Passenger setup if you have not already. </p>
<p>First we need to allow the <strong>munin</strong> user sudo privileges for a few passenger related commands:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> <span class="sy0">/</span>usr<span class="sy0">/</span>sbin<span class="sy0">/</span>visudo
&nbsp;
<span class="co0"># Add the following line to the file</span>
munin <span class="re2">ALL</span>=<span class="br0">&#40;</span>ALL<span class="br0">&#41;</span> NOPASSWD:<span class="sy0">/</span>usr<span class="sy0">/</span>bin<span class="sy0">/</span>passenger-status, <span class="sy0">/</span>usr<span class="sy0">/</span>bin<span class="sy0">/</span>passenger-memory-stats
&nbsp;
<span class="co0"># Depending on your setup, you may also have to comment out the following line:</span>
Defaults requiretty</pre></div></div>

<p>If you see the error <strong>sorry, you must have a tty to run sudo</strong> in <strong>/var/log/munin/munin-node.log</strong>, comment out the final line shown above.</p>
<p>The following two files will glean some performance and memory statistics.</p>
<p><strong>Passenger Status:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> <span class="kw2">vi</span> <span class="sy0">/</span>usr<span class="sy0">/</span>share<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_status</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="co1">#!/usr/bin/env ruby</span>
&nbsp;
<span class="kw1">def</span> output_config
  <span class="kw3">puts</span> <span class="sy0">&lt;&lt;-</span><span class="kw1">END</span>
graph_category App
graph_title passenger status
graph_vlabel count
&nbsp;
sessions.<span class="me1">label</span> sessions
max.<span class="me1">label</span> max processes
running.<span class="me1">label</span> running processes
active.<span class="me1">label</span> active processes
<span class="kw1">END</span>
  <span class="kw3">exit</span> <span class="nu0">0</span>
<span class="kw1">end</span>
&nbsp;
<span class="kw1">def</span> output_values
  status = <span class="st0">`sudo /usr/bin/passenger-status`</span>
  <span class="kw1">unless</span> $?.<span class="me1">success</span>?
    <span class="re0">$stderr</span>.<span class="kw3">puts</span> <span class="st0">&quot;failed executing passenger-status&quot;</span>
    <span class="kw3">exit</span> <span class="nu0">1</span>
  <span class="kw1">end</span>
  status =~ <span class="sy0">/</span>max\s<span class="sy0">+</span>=\s<span class="sy0">+</span><span class="br0">&#40;</span>\d<span class="sy0">+</span><span class="br0">&#41;</span><span class="sy0">/</span>
  <span class="kw3">puts</span> <span class="st0">&quot;max.value #{$1}&quot;</span>
&nbsp;
  status =~ <span class="sy0">/</span>count\s<span class="sy0">+</span>=\s<span class="sy0">+</span><span class="br0">&#40;</span>\d<span class="sy0">+</span><span class="br0">&#41;</span><span class="sy0">/</span>
  <span class="kw3">puts</span> <span class="st0">&quot;running.value #{$1}&quot;</span>
&nbsp;
  status =~ <span class="sy0">/</span>active\s<span class="sy0">+</span>=\s<span class="sy0">+</span><span class="br0">&#40;</span>\d<span class="sy0">+</span><span class="br0">&#41;</span><span class="sy0">/</span>
  <span class="kw3">puts</span> <span class="st0">&quot;active.value #{$1}&quot;</span>
&nbsp;
  total_sessions = <span class="nu0">0</span>
  status.<span class="me1">scan</span><span class="br0">&#40;</span><span class="sy0">/</span>Sessions: <span class="br0">&#40;</span>\d<span class="sy0">+</span><span class="br0">&#41;</span><span class="sy0">/</span><span class="br0">&#41;</span>.<span class="me1">flatten</span>.<span class="me1">each</span> <span class="br0">&#123;</span> <span class="sy0">|</span>count<span class="sy0">|</span> total_sessions <span class="sy0">+</span>= count.<span class="me1">to_i</span> <span class="br0">&#125;</span>
  <span class="kw3">puts</span> <span class="st0">&quot;sessions.value #{total_sessions}&quot;</span>
<span class="kw1">end</span>
&nbsp;
<span class="kw1">if</span> ARGV<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="st0">&quot;config&quot;</span>
  output_config
<span class="kw1">else</span>
  output_values
<span class="kw1">end</span></pre></div></div>

<p><strong>Memory Stats:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> <span class="kw2">vi</span> <span class="sy0">/</span>usr<span class="sy0">/</span>share<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_memory_status</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="co1">#!/usr/bin/env ruby</span>
<span class="co1"># put in /etc/munin/plugins and restart munin-node</span>
<span class="co1"># by Dan Manges, http://www.dcmanges.com/blog/rails-application-visualization-with-munin</span>
<span class="co1"># NOTE: you might need to add munin to allow passwordless sudo for passenger-memory-stats</span>
&nbsp;
<span class="kw1">def</span> output_config
  <span class="kw3">puts</span> <span class="sy0">&lt;&lt;-</span><span class="kw1">END</span>
graph_category App
graph_title Passenger memory stats
graph_vlabel count
&nbsp;
memory.<span class="me1">label</span> memory
<span class="kw1">END</span>
  <span class="kw3">exit</span> <span class="nu0">0</span>
<span class="kw1">end</span>
&nbsp;
<span class="kw1">def</span> output_values
  status = <span class="st0">`sudo /usr/bin/passenger-memory-stats | tail -1`</span>
  <span class="kw1">unless</span> $?.<span class="me1">success</span>?
    <span class="re0">$stderr</span>.<span class="kw3">puts</span> <span class="st0">&quot;failed executing passenger-memory-stats&quot;</span>
    <span class="kw3">exit</span> <span class="nu0">1</span>
  <span class="kw1">end</span>
  status =~ <span class="sy0">/</span><span class="br0">&#40;</span>\d<span class="sy0">+</span>\.\d<span class="sy0">+</span><span class="br0">&#41;</span><span class="sy0">/</span>
  <span class="kw3">puts</span> <span class="st0">&quot;memory.value #{$1}&quot;</span>
<span class="kw1">end</span>
&nbsp;
<span class="kw1">if</span> ARGV<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="st0">&quot;config&quot;</span>
  output_config
<span class="kw1">else</span>
  output_values
<span class="kw1">end</span></pre></div></div>

<p>Now we will link these to the active plugins, and make them executable:</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> <span class="kw2">chmod</span> +x <span class="sy0">/</span>usr<span class="sy0">/</span>share<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_status
<span class="kw2">sudo</span> <span class="kw2">chmod</span> +x <span class="sy0">/</span>usr<span class="sy0">/</span>share<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_memory_status
<span class="kw2">sudo</span> <span class="kw2">ln</span> <span class="re5">-s</span> <span class="sy0">/</span>usr<span class="sy0">/</span>share<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_status <span class="sy0">/</span>etc<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_status
<span class="kw2">sudo</span> <span class="kw2">ln</span> <span class="re5">-s</span> <span class="sy0">/</span>usr<span class="sy0">/</span>share<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_memory_status <span class="sy0">/</span>etc<span class="sy0">/</span>munin<span class="sy0">/</span>plugins<span class="sy0">/</span>passenger_memory_status</pre></div></div>

<p>Last thing we need to do is make sure those scripts run as the munin user:</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> <span class="kw2">vi</span> <span class="sy0">/</span>etc<span class="sy0">/</span>munin<span class="sy0">/</span>plugin-conf.d<span class="sy0">/</span>munin-node</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="br0">&#91;</span>passenger_<span class="sy0">*</span><span class="br0">&#93;</span>
user munin
<span class="kw3">command</span> ruby <span class="sy0">%</span>c</pre></div></div>

<p>Restart the munin node, and wait and you should see the graphs start to propagate.</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">sudo</span> <span class="sy0">/</span>etc<span class="sy0">/</span>init.d<span class="sy0">/</span>munin-node restart</pre></div></div>

<p>For even more detailed performance analytics, checkout <a href="http://www.newrelic.com/" target="_blank">NewRelic</a> monitoring. And thanks to <a href="http://www.dcmanges.com/blog/rails-application-visualization-with-munin" target="_blank">Dan Mange</a> for the munin scripts.</p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2009/09/29/munin-graphs-for-phusion-passenger-a-k-a-mod_rails/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Unobtrusive RESTful jQuery</title>
		<link>http://jetpackweb.com/blog/2009/09/09/unobtrusive-restful-jquery/</link>
		<comments>http://jetpackweb.com/blog/2009/09/09/unobtrusive-restful-jquery/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 16:42:32 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=347</guid>
		<description><![CDATA[Many Rails(and non-Rails) web applications these days strive to create RESTful interfaces for their application design. When dealing with Ajax updates through jQuery, this can become somewhat tricky. Since most browsers only implement GET and POST requests, we have to fake it in Rails by sending a parameter called _methd for all PUT and DELETE [...]]]></description>
			<content:encoded><![CDATA[<p>Many Rails(and non-Rails) web applications these days strive to create <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank">RESTful</a> interfaces for their application design. When dealing with Ajax updates through jQuery, this can become somewhat tricky. Since most browsers only implement GET and POST requests, we have to fake it in Rails by sending a parameter called <b>_methd</b> for all PUT and DELETE requests. To make things even more complicated, we need to include a token to prevent <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery" target="_blank">CSRF</a> attacks.</p>
<p>In Rails 2.x, the default way it generates the javascript to send a a RESTful command via POST request looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html">&lt;a href=&quot;/foos/1&quot; onclick=&quot;if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'VGcSbbdenz7ZCMDWl7LugKC2KFldp7oKdgdvjGyb4Zo='); f.appendChild(s);f.submit(); };return false;&quot;&gt;Destroy&lt;/a&gt; |</pre></div></div>

<p>Yuck. It&#8217;s creating a new form, setting a hidden input fields for the submission method and csrf token, and then submitting it. Not only is it obtrusive, that gets inserted at every location there is a delete or update link. </p>
<p>First lets extend jquery with PUT and DELETE methods. Well call this <strong>jquery.rest.js</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="sy0">;</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>$<span class="br0">&#41;</span><span class="br0">&#123;</span>
  $.<span class="me1">put</span> <span class="sy0">=</span> $.<span class="me1">update</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>uri<span class="sy0">,</span> data<span class="sy0">,</span> callback<span class="sy0">,</span> type <span class="sy0">=</span> <span class="st0">'json'</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>$.<span class="me1">isFunction</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="br0">&#41;</span> callback <span class="sy0">=</span> data<span class="sy0">,</span> data <span class="sy0">=</span> <span class="br0">&#123;</span><span class="br0">&#125;</span>
    <span class="kw1">return</span> $.<span class="me1">post</span><span class="br0">&#40;</span>uri<span class="sy0">,</span> $.<span class="me1">extend</span><span class="br0">&#40;</span>data<span class="sy0">,</span> <span class="br0">&#123;</span> _method<span class="sy0">:</span> <span class="st0">'put'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">,</span> callback<span class="sy0">,</span> type<span class="br0">&#41;</span>
  <span class="br0">&#125;</span>
&nbsp;
  $.<span class="kw1">delete</span> <span class="sy0">=</span> $.<span class="me1">del</span> <span class="sy0">=</span> $.<span class="me1">destroy</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span>uri<span class="sy0">,</span> data<span class="sy0">,</span> callback<span class="sy0">,</span> type <span class="sy0">=</span> <span class="st0">'json'</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>$.<span class="me1">isFunction</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="br0">&#41;</span> callback <span class="sy0">=</span> data<span class="sy0">,</span> data <span class="sy0">=</span> <span class="br0">&#123;</span><span class="br0">&#125;</span>
    <span class="kw1">return</span> $.<span class="me1">post</span><span class="br0">&#40;</span>uri<span class="sy0">,</span> $.<span class="me1">extend</span><span class="br0">&#40;</span>data<span class="sy0">,</span> <span class="br0">&#123;</span> _method<span class="sy0">:</span> <span class="st0">'delete'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">,</span> callback<span class="sy0">,</span> type<span class="br0">&#41;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#123;</span><span class="br0">&#41;</span><span class="br0">&#40;</span>jQuery<span class="br0">&#41;</span></pre></div></div>

<p>The previous code will <b>POST</b> data while always including a &#8216;_method&#8217; parameter. Using this code is as simple as a normal jQuery ajax call:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">$<span class="br0">&#40;</span><span class="st0">'.deletable'</span><span class="br0">&#41;</span>.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  $.<span class="kw1">delete</span><span class="br0">&#40;</span><span class="st0">'/videos/delete'</span><span class="sy0">,</span> <span class="br0">&#123;</span>
    <span class="st0">'video_id'</span><span class="sy0">:</span> $<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>.<span class="me1">attr</span><span class="br0">&#40;</span><span class="st0">'id'</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>That example might iterate through all elements with the deletable class, and then sent the <b>DELETE</b> method when clicked.</p>
<p> Now in a Rails app we also need to include the CSRF token in all POST, PUT, and DELETE requests. The way I go about this is to put this at the bottom of my applications layout:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">$<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ready</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  window.<span class="me1">AUTH_TOKEN</span> <span class="sy0">=</span> <span class="st0">'#{form_authenticity_token}'</span><span class="sy0">;</span>
  $<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ajaxSend</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>event<span class="sy0">,</span> request<span class="sy0">,</span> settings<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span><span class="br0">&#40;</span>window.<span class="me1">AUTH_TOKEN</span><span class="br0">&#41;</span> <span class="sy0">==</span> <span class="st0">&quot;undefined&quot;</span><span class="br0">&#41;</span> <span class="kw1">return</span><span class="sy0">;</span>
    <span class="co1">// IE6 fix for http://dev.jquery.com/ticket/3155</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>settings.<span class="me1">type</span> <span class="sy0">==</span> <span class="st0">'GET'</span> <span class="sy0">||</span> settings.<span class="me1">type</span> <span class="sy0">==</span> <span class="st0">'get'</span><span class="br0">&#41;</span> <span class="kw1">return</span><span class="sy0">;</span>
    settings.<span class="me1">data</span> <span class="sy0">=</span> settings.<span class="me1">data</span> <span class="sy0">||</span> <span class="st0">&quot;&quot;</span><span class="sy0">;</span>
    settings.<span class="me1">data</span> <span class="sy0">+=</span> <span class="br0">&#40;</span>settings.<span class="me1">data</span> <span class="sy0">?</span> <span class="st0">&quot;&amp;&quot;</span> <span class="sy0">:</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">&quot;authenticity_token=&quot;</span> <span class="sy0">+</span> encodeURIComponent<span class="br0">&#40;</span>window.<span class="me1">AUTH_TOKEN</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>This will extend the parameters of any ajax request with the authenticity token. I hope this short guide gives you a better idea how to do REST in an unobtrusive way.</p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2009/09/09/unobtrusive-restful-jquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>jQuery Sortables: Getting DOM element position for an efficient ajax update in Rails</title>
		<link>http://jetpackweb.com/blog/2009/09/02/jquery-sortables-getting-element-position-for-an-efficient-ajax-update-in-rails/</link>
		<comments>http://jetpackweb.com/blog/2009/09/02/jquery-sortables-getting-element-position-for-an-efficient-ajax-update-in-rails/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 02:23:47 +0000</pubDate>
		<dc:creator>Brian Racer</dc:creator>
				<category><![CDATA[jquery]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[act_as_list]]></category>
		<category><![CDATA[haml]]></category>

		<guid isPermaLink="false">http://jetpackweb.com/blog/?p=308</guid>
		<description><![CDATA[The jQuery UI library has some excellent interaction functionality, especially &#8216;sortables&#8217; to make cool things like rearrangeable lists. Although there are lots of tutorials on sortable lists, one problem I have with them is the amount of database queries a single update can generate. They generally make use of the Sortable.serialize method, send *all* the [...]]]></description>
			<content:encoded><![CDATA[<p>The jQuery UI library has some excellent interaction functionality, especially &#8216;sortables&#8217; to make cool things like rearrangeable lists. Although there are lots of tutorials on sortable lists, one problem I have with them is the amount of database queries a single update can generate. They generally make use of the <a href="http://jqueryui.com/demos/sortable/#method-serialize" target="_blank">Sortable.serialize</a> method, send *all* the elements back to the server, and update each element with something like ActiveRecord&#8217;s <a href="http://apidock.com/rails/ActiveRecord/Base/update_all/class" target="_blank">update_all</a>(which can be smart), or worse, separate SQL queries for each list element.</p>
<p>What we can do instead is just send the id and position of the single element that has moved, and use <b>acts_as_list</b> to adjust the positions in the database. Lets say we have an <i>unordered list</i> of Video models <i>(I am using <a href="http://haml-lang.com" target="_blank">HAML</a> in this example)</i>:</p>

<div class="wp_syntax"><div class="code"><pre class="haml">%h3= &quot;Videos&quot;
%ul(class=&quot;sortable&quot;)
  - @videos.each do |video|
    %li{ :id =&gt; &quot;video_#{video.id}&quot; }= video.title</pre></div></div>

<p>That might output something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html">&lt;h3&gt;Videos&lt;/h3&gt;
&lt;ul class='sortable'&gt;
  &lt;li id='video_5'&gt;Batman Begins&lt;/li&gt;
  &lt;li id='video_6'&gt;Ghostbusters&lt;/li&gt;
  &lt;li id='video_7'&gt;Indiana Jones and the Temple of Doom&lt;/li&gt;
 &lt;/ul&gt;</pre></div></div>

<p>We have the video&#8217;s database id&#8217;s in each of the element id&#8217;s, and we have given the <b>ul</b> element the <i>sortable</i> class so we can select it later. Now lets select that <b>ul</b> element and make it &#8216;sortable&#8217;:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">$<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  $<span class="br0">&#40;</span><span class="st0">'.sortable'</span><span class="br0">&#41;</span>.<span class="me1">sortable</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>With that we can now drag each list item around. Now comes the important part. When we finish dragging a single list element we will send a single ajax request to the server that contains the numeric value of the element&#8217;s id, and it&#8217;s position in the list:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">  $<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    $<span class="br0">&#40;</span><span class="st0">'.sortable'</span><span class="br0">&#41;</span>.<span class="me1">sortable</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
      <span class="kw3">stop</span><span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="sy0">,</span> ui<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        $<span class="br0">&#40;</span>ui.<span class="kw1">item</span><span class="br0">&#41;</span>.<span class="me1">effect</span><span class="br0">&#40;</span><span class="st0">&quot;highlight&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="kw2">var</span> video_id <span class="sy0">=</span> $<span class="br0">&#40;</span>ui.<span class="kw1">item</span><span class="br0">&#41;</span>.<span class="me1">attr</span><span class="br0">&#40;</span><span class="st0">'id'</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/[^\d]+/g</span><span class="sy0">,</span> <span class="st0">''</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
        <span class="kw2">var</span> position <span class="sy0">=</span> ui.<span class="kw1">item</span>.<span class="me1">prevAll</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">length</span><span class="sy0">;</span>
        $.<span class="me1">post</span><span class="br0">&#40;</span><span class="st0">'/videos/update_position'</span><span class="sy0">,</span> <span class="br0">&#123;</span>
          <span class="st0">'video_id'</span><span class="sy0">:</span> video_id<span class="sy0">,</span>
          <span class="st0">'position'</span><span class="sy0">:</span> position
         <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
         $<span class="br0">&#40;</span>ui.<span class="kw1">item</span><span class="br0">&#41;</span>.<span class="me1">effect</span><span class="br0">&#40;</span><span class="st0">&quot;highlight&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="br0">&#125;</span>
    <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span></pre></div></div>

<p>Couple of notes:</p>
<p><b>ui.item</b> is the DOM element we are dragging</p>
<p><b>$(ui.item).attr(&#8216;id&#8217;).replace(/[^\d+]+/g, &#8221;))</b> is pulling out the list item&#8217;s DOM id and removing anything that isn&#8217;t numeric, so we are left with the model&#8217;s ID</p>
<p><b>ui.item.prevAll().length</b> is what gives us the list item&#8217;s position in relation to it&#8217;s parent <b>ul</b></p>
<p>Now our controller action can be as simple as:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">Video.<span class="me1">find</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:video_id</span><span class="br0">&#93;</span><span class="br0">&#41;</span>.<span class="me1">insert_at</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:position</span><span class="br0">&#93;</span><span class="br0">&#41;</span></pre></div></div>

<p>Again this requires <b>acts_as_list</b>.  I believe this should never do more that 4 queries: One to find the model, one to update it&#8217;s position, and possibly two more to shift what was above and below it previously. Hopefully this saves you some SQL queries on larger lists.</p>
]]></content:encoded>
			<wfw:commentRss>http://jetpackweb.com/blog/2009/09/02/jquery-sortables-getting-element-position-for-an-efficient-ajax-update-in-rails/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

