<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.ramblingsonrails.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" version="2.0">

<channel>
	<title>Ramblings on Rails</title>
	
	<link>http://ramblingsonrails.com</link>
	<description>Andrew Timberlake's blog</description>
	<pubDate>Wed, 05 Aug 2009 13:30:20 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.ramblingsonrails.com/RamblingsOnRails" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="ramblingsonrails" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Extending the timeout for Rails processes through Passenger on Nginx</title>
		<link>http://ramblingsonrails.com/extending-timeout-rails-processes-passenger-nginx</link>
		<comments>http://ramblingsonrails.com/extending-timeout-rails-processes-passenger-nginx#comments</comments>
		<pubDate>Wed, 05 Aug 2009 13:30:20 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=169</guid>
		<description><![CDATA[I recently had to allow for a long running reporting task in a Rails app which is running under Passenger (mod_rails) on Nginx
The default setting is 60 seconds and setting send_timeout to 300 in the Nginx config wasn&#8217;t working.
After much searching, I found the answer. Edit
/ext/nginx/Conguration.c and change the lines:
ngx_conf_merge_msec_value&#40;conf-&#62;upstream.send_timeout, prev-&#62;upstream.send_timeout, 60000&#41;;
ngx_conf_merge_msec_value&#40;conf-&#62;upstream.read_timeout, prev-&#62;upstream.read_timeout, 60000&#41;;
to (for [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to allow for a long running reporting task in a Rails app which is running under Passenger (mod_rails) on Nginx</p>
<p>The default setting is 60 seconds and setting <i>send_timeout</i> to <i>300</i> in the Nginx config wasn&#8217;t working.<br />
After much searching, I found the answer. Edit
<passenger gem path>/ext/nginx/Conguration.c and change the lines:</p>
<div class="codecolorer-container c"><div class="codecolorer" style="font-family: monospace;">ngx_conf_merge_msec_value<span class="br0">&#40;</span>conf-&gt;upstream.<span class="me1">send_timeout</span>, prev-&gt;upstream.<span class="me1">send_timeout</span>, <span class="nu0">60000</span><span class="br0">&#41;</span>;<br />
ngx_conf_merge_msec_value<span class="br0">&#40;</span>conf-&gt;upstream.<span class="me1">read_timeout</span>, prev-&gt;upstream.<span class="me1">read_timeout</span>, <span class="nu0">60000</span><span class="br0">&#41;</span>;</div></div>
<p>to (for a 5 min timeout)</p>
<div class="codecolorer-container c"><div class="codecolorer" style="font-family: monospace;">ngx_conf_merge_msec_value<span class="br0">&#40;</span>conf-&gt;upstream.<span class="me1">send_timeout</span>, prev-&gt;upstream.<span class="me1">send_timeout</span>, <span class="nu0">300000</span><span class="br0">&#41;</span>;<br />
ngx_conf_merge_msec_value<span class="br0">&#40;</span>conf-&gt;upstream.<span class="me1">read_timeout</span>, prev-&gt;upstream.<span class="me1">read_timeout</span>, <span class="nu0">300000</span><span class="br0">&#41;</span>;</div></div>
<p>You will then need to recompile nginx and restart it (sending the HUP signal won&#8217;t work in this case)</p>
<p>Hope this helps someone else out there.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=GjCxEG0tUHI:F37dRlvghbY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=GjCxEG0tUHI:F37dRlvghbY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=GjCxEG0tUHI:F37dRlvghbY:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/extending-timeout-rails-processes-passenger-nginx/feed</wfw:commentRss>
		</item>
		<item>
		<title>Rails plugin that provides rake tasks for identifying missing specs</title>
		<link>http://ramblingsonrails.com/rails-plugin-provides-rake-tasks-for-identifying-missing-specs</link>
		<comments>http://ramblingsonrails.com/rails-plugin-provides-rake-tasks-for-identifying-missing-specs#comments</comments>
		<pubDate>Thu, 18 Jun 2009 07:50:18 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[testing]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[rspec]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=166</guid>
		<description><![CDATA[I have a bad habbit of generating my views while specing the controller and then never generating a view spec.
I wrote a rake task to tell me which views have no specs, kind of like a rcov for views.
I then realised that it could be useful to find all files with missing specs so now [...]]]></description>
			<content:encoded><![CDATA[<p>I have a bad habbit of generating my views while specing the controller and then never generating a view spec.<br />
I wrote a rake task to tell me which views have no specs, kind of like a rcov for views.</p>
<p>I then realised that it could be useful to find all files with missing specs so now we have <a href="http://github.com/internuity/unspecd.git">unspec&#8217;d</a>, a Rails plugin that provides rake tasks for identifying missing specs</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=3C13XDj5v7k:soaa0wwJFE0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=3C13XDj5v7k:soaa0wwJFE0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=3C13XDj5v7k:soaa0wwJFE0:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/rails-plugin-provides-rake-tasks-for-identifying-missing-specs/feed</wfw:commentRss>
		</item>
		<item>
		<title>How to select an array of values in Rails</title>
		<link>http://ramblingsonrails.com/how-to-select-an-array-of-values-in-rails</link>
		<comments>http://ramblingsonrails.com/how-to-select-an-array-of-values-in-rails#comments</comments>
		<pubDate>Mon, 15 Jun 2009 13:35:16 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=160</guid>
		<description><![CDATA[I recently wanted to get a list of IDs from rails, but wanted them in an array.
First try is to use :select => &#8216;id&#8217; in:
Model.find&#40;:all, :select =&#62; 'id'&#41;
but that creates a model for each id
In order to get an array of values, you can use select_values:
Model.connection.select_values&#40;'select id from models'&#41;
This is great, but what if you [...]]]></description>
			<content:encoded><![CDATA[<p>I recently wanted to get a list of IDs from rails, but wanted them in an array.</p>
<p>First try is to use <i>:select => &#8216;id&#8217;</i> in:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">Model.<span class="me1">find</span><span class="br0">&#40;</span><span class="re3">:all</span>, <span class="re3">:select</span> =&gt; <span class="st0">'id'</span><span class="br0">&#41;</span></div></div>
<p>but that creates a model for each id</p>
<p>In order to get an array of values, you can use <i>select_values</i>:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">Model.<span class="me1">connection</span>.<span class="me1">select_values</span><span class="br0">&#40;</span><span class="st0">'select id from models'</span><span class="br0">&#41;</span></div></div>
<p>This is great, but what if you have a more complex query and you still want to use the query building in Rails finder methods.<br />
You can use <i>construct_finder_sql</i>. This is a private method so it needs to be called via <i>send</i> and you should be cautious about it&#8217;s availability in future versions of Rails.<br />
The final query then is:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">sql = Model.<span class="me1">send</span><span class="br0">&#40;</span><span class="re3">:construct_finder_sql</span>, <span class="re3">:select</span> =&gt; <span class="st0">'id'</span>, <span class="re3">:conditions</span> =&gt; <span class="br0">&#91;</span>...<span class="br0">&#93;</span><span class="br0">&#41;</span><br />
Model.<span class="me1">connection</span>.<span class="me1">select_values</span><span class="br0">&#40;</span>sql<span class="br0">&#41;</span></div></div>
<p>This will be quicker and use less memory because it doesn&#8217;t create a model object for each id.<br />
I would only use this when pulling fairly large arrays of values, stick to the normal way of doing things for smaller collections.</p>
<p>If you want to get two or three values per &#8216;row&#8217;, you can use <i>select_rows</i> which will return an array of arrays.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=JrHbwMsP5pE:CbTKTrFEgio:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=JrHbwMsP5pE:CbTKTrFEgio:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=JrHbwMsP5pE:CbTKTrFEgio:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/how-to-select-an-array-of-values-in-rails/feed</wfw:commentRss>
		</item>
		<item>
		<title>Accessing the Rails logger inside of library files</title>
		<link>http://ramblingsonrails.com/accessing-the-rails-logger-inside-of-library-files</link>
		<comments>http://ramblingsonrails.com/accessing-the-rails-logger-inside-of-library-files#comments</comments>
		<pubDate>Wed, 10 Jun 2009 07:05:42 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=157</guid>
		<description><![CDATA[A quick tip, if you&#8217;re developing a library which lives inside of RAILS_ROOT/lib, you can use the Rails logger via DEFAULT_RAILS_LOGGER
class MyLib
&#160; def my_method
&#160; &#160; RAILS_DEFAULT_LOGGER.info &#34;my log message&#34; if RAILS_DEFAULT_LOGGER
&#160; end
end
I added if RAILS_DEFAULT_LOGGER so that it doesn&#8217;t trip up if used outside of RAILS
]]></description>
			<content:encoded><![CDATA[<p>A quick tip, if you&#8217;re developing a library which lives inside of RAILS_ROOT/lib, you can use the Rails logger via DEFAULT_RAILS_LOGGER</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">class</span> MyLib<br />
&nbsp; <span class="kw1">def</span> my_method<br />
&nbsp; &nbsp; RAILS_DEFAULT_LOGGER.<span class="me1">info</span> <span class="st0">&quot;my log message&quot;</span> <span class="kw1">if</span> RAILS_DEFAULT_LOGGER<br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<p>I added <i>if RAILS_DEFAULT_LOGGER</i> so that it doesn&#8217;t trip up if used outside of RAILS</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=bRdOGXS181o:OauKA2UVfYE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=bRdOGXS181o:OauKA2UVfYE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=bRdOGXS181o:OauKA2UVfYE:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/accessing-the-rails-logger-inside-of-library-files/feed</wfw:commentRss>
		</item>
		<item>
		<title>Download a large amount of data in CSV from Rails</title>
		<link>http://ramblingsonrails.com/download-a-large-amount-of-data-in-csv-from-rails</link>
		<comments>http://ramblingsonrails.com/download-a-large-amount-of-data-in-csv-from-rails#comments</comments>
		<pubDate>Wed, 03 Jun 2009 15:26:02 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[csv]]></category>

		<category><![CDATA[export]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=144</guid>
		<description><![CDATA[I&#8217;ve just had to re-write an export script because the application now needed to be able to download 14000 records in CSV format.
Originally I was reading all the records (with multiple joins) and then creating a csv string and then writing it to the response using send_data.
The original code
This is a simplified version of my [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just had to re-write an export script because the application now needed to be able to download 14000 records in CSV format.<br />
Originally I was reading all the records (with multiple joins) and then creating a csv string and then writing it to the response using send_data.</p>
<h3>The original code</h3>
<p>This is a simplified version of my code</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">accounts = Account.<span class="me1">find</span><span class="br0">&#40;</span><span class="re3">:all</span><span class="br0">&#41;</span><br />
csv_string = FasterCSV.<span class="me1">generate</span> <span class="kw1">do</span> |csv|<br />
&nbsp; accounts.<span class="me1">each</span> <span class="kw1">do</span> |account|<br />
&nbsp; &nbsp; csv &lt;&lt; <span class="br0">&#91;</span>account.<span class="me1">id</span>, account.<span class="me1">name</span><span class="br0">&#93;</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span><br />
send_data csv_string, <span class="re3">:filename</span> =&gt; <span class="st0">'accounts.csv'</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:type</span> =&gt; <span class="st0">'text/csv'</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:disposition</span> =&gt; <span class="st0">'attachment'</span></div></div>
<p>My first thought was to stream the data using</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">send_file_headers!&nbsp; <span class="re3">:filename</span> =&gt; <span class="st0">'accounts.csv'</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:type</span> =&gt; <span class="st0">'text/csv'</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:disposition</span> =&gt; <span class="st0">'attachment'</span><br />
render <span class="re3">:text</span> =&gt; <span class="kw3">Proc</span>.<span class="me1">new</span> <span class="br0">&#123;</span>|response, output|<br />
&nbsp; ...<br />
<span class="br0">&#125;</span></div></div>
<p>The problem with this is that <i>send_file_headers!</i> requires that the <i>:length</i> option be set. I also was running into the problem of loading 14000 records into memory before iterating over them.</p>
<p>For the memory problem, I considered using the new <i>Model.find_in_batches</i> but I needed to join tables and use some complicated conditions.</p>
<h2>The solution</h2>
<p>I finally settled on chunked reading of the data from the database and a more explicit use of <i>render :text => Proc&#8230;</i></p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw3">require</span> <span class="st0">'fastercsv'</span><br />
<span class="kw1">def</span> download<br />
&nbsp; filename = <span class="st0">'accounts.csv'</span><br />
&nbsp; headers.<span class="me1">merge</span>!<span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">'Content-Type'</span> =&gt; <span class="st0">'text/csv'</span>,<br />
&nbsp; &nbsp; <span class="st0">'Content-Disposition'</span> =&gt; <span class="st0">&quot;attachment; filename=<span class="es0">\&quot;</span>#{filename}<span class="es0">\&quot;</span>&quot;</span>,<br />
&nbsp; &nbsp; <span class="st0">'Content-Transfer-Encoding'</span> =&gt; <span class="st0">'binary'</span><br />
&nbsp; <span class="br0">&#41;</span><br />
&nbsp; <span class="re1">@performed_render</span> = <span class="kw2">false</span><br />
<br />
&nbsp; render <span class="re3">:status</span> =&gt; <span class="nu0">200</span>, <span class="re3">:text</span> =&gt; <span class="kw3">Proc</span>.<span class="me1">new</span> <span class="br0">&#123;</span> |response, output|<br />
&nbsp; &nbsp; headings = <span class="br0">&#91;</span><span class="st0">&quot;ID&quot;</span>, <span class="st0">&quot;Name&quot;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; output.<span class="me1">write</span> FasterCSV.<span class="me1">generate_line</span><span class="br0">&#40;</span>headings<span class="br0">&#41;</span><br />
<br />
&nbsp; &nbsp; last_account_id = <span class="nu0">0</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> last_account_id <span class="kw1">do</span><br />
&nbsp; &nbsp; &nbsp; accounts = Account.<span class="me1">find</span><span class="br0">&#40;</span><span class="re3">:all</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:conditions</span> =&gt; <span class="br0">&#91;</span><span class="st0">&quot;accounts.id &gt; ?&quot;</span>, last_account_id<span class="br0">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:order</span> =&gt; <span class="st0">'accounts.id'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:limit</span> =&gt; <span class="nu0">1000</span><span class="br0">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; last_account_id = accounts.<span class="me1">size</span> &gt; <span class="nu0">0</span> ? accounts<span class="br0">&#91;</span><span class="nu0">-1</span><span class="br0">&#93;</span>.<span class="me1">id</span> : <span class="kw2">nil</span><br />
<br />
&nbsp; &nbsp; &nbsp; accounts.<span class="me1">each</span> <span class="br0">&#123;</span> |account|<br />
&nbsp; &nbsp; &nbsp; &nbsp; data = <span class="br0">&#91;</span>account.<span class="me1">id</span>, account.<span class="me1">name</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; output.<span class="me1">write</span> FasterCSV.<span class="me1">generate_line</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="kw1">end</span></div></div>
<p>I hope this useful for you, if you have any questions, please ask in the comments.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=pMEjcTNqgTM:4xvcHV-tUhI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=pMEjcTNqgTM:4xvcHV-tUhI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=pMEjcTNqgTM:4xvcHV-tUhI:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/download-a-large-amount-of-data-in-csv-from-rails/feed</wfw:commentRss>
		</item>
		<item>
		<title>Map Fields - A Rails plugin to ease the importing of CSV files</title>
		<link>http://ramblingsonrails.com/map-fields-a-rails-plugin-to-ease-the-importing-of-csv-files</link>
		<comments>http://ramblingsonrails.com/map-fields-a-rails-plugin-to-ease-the-importing-of-csv-files#comments</comments>
		<pubDate>Wed, 03 Jun 2009 06:10:40 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[plugins]]></category>

		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=131</guid>
		<description><![CDATA[I&#8217;ve just released a plugin, map-fieilds, that eases the importing of CSV files.
When importing CSV files for a project, I wanted to add flexibility for the users so that they could import their CSV files in a looser format and then map their format to the format I needed.
map-fieilds will intercept calls to a method [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just released a plugin, <a href="http://github.com/internuity/map-fields">map-fieilds</a>, that eases the importing of CSV files.</p>
<p>When importing CSV files for a project, I wanted to add flexibility for the users so that they could import their CSV files in a looser format and then map their format to the format I needed.<br />
<a href="http://github.com/internuity/map-fields">map-fieilds</a> will intercept calls to a method and show an intermediate screen where the user can map their columns to the expected columns.</p>
<h2>How to install</h2>
<div class="codecolorer-container bash"><div class="codecolorer" style="font-family: monospace;">sudo gem install map-fields</div></div>
<p>In your environment.rb file:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">config.<span class="me1">gem</span> <span class="st0">'map-fields'</span>, <span class="re3">:version</span> =&gt; <span class="st0">'~&gt; 0.1.0'</span>, <span class="re3">:lib</span> =&gt; <span class="st0">'map_fields'</span></div></div>
<p>If you prefer, it can be installed as a plugin:</p>
<div class="codecolorer-container bash"><div class="codecolorer" style="font-family: monospace;">script/plugin install git://github.com/internuity/map-fields.git</div></div>
<h2>Using it in your controller</h2>
<p>lists_controller.rb:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">class</span> ListsController &lt; AppliactionController<br />
&nbsp; map_fields <span class="re3">:create</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span><span class="st0">'Title'</span>, <span class="st0">'First name'</span>, <span class="st0">'Last name'</span><span class="br0">&#93;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:file_field</span> =&gt; <span class="re3">:file</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:params</span> =&gt; <span class="br0">&#91;</span><span class="re3">:list</span><span class="br0">&#93;</span><br />
<br />
&nbsp; <span class="kw1">def</span> index<br />
&nbsp; &nbsp; <span class="re1">@lists</span> = List.<span class="me1">find</span><span class="br0">&#40;</span><span class="re3">:all</span><span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">end</span><br />
<br />
&nbsp; <span class="kw1">def</span> new<br />
&nbsp; &nbsp; <span class="re1">@list</span> = List.<span class="me1">new</span><br />
&nbsp; <span class="kw1">end</span><br />
<br />
&nbsp; <span class="kw1">def</span> create<br />
&nbsp; &nbsp; <span class="re1">@list</span> = List.<span class="me1">new</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:list</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> fields_mapped?<br />
&nbsp; &nbsp; &nbsp; mapped_fields.<span class="me1">each</span> <span class="kw1">do</span> |row|<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re1">@list</span>.<span class="me1">contact</span>.<span class="me1">create</span><span class="br0">&#40;</span><span class="re3">:title</span> =&gt; row<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re3">:first_name</span> =&gt; row<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re3">:last_name</span> =&gt; row<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; flash<span class="br0">&#91;</span><span class="re3">:notice</span><span class="br0">&#93;</span> = <span class="st0">'Contact list created'</span><br />
&nbsp; &nbsp; &nbsp; redirect_to <span class="re3">:action</span> =&gt; <span class="re3">:index</span><br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; render<br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="kw1">rescue</span> <span class="re2">MapFields::InconsistentStateError</span><br />
&nbsp; &nbsp; flash<span class="br0">&#91;</span><span class="re3">:error</span><span class="br0">&#93;</span> = <span class="st0">'Please try again'</span><br />
&nbsp; &nbsp; redirect_to <span class="re3">:action</span> =&gt; <span class="re3">:new</span><br />
&nbsp; <span class="kw1">rescue</span> <span class="re2">MapFields::MissingFileContentsError</span><br />
&nbsp; &nbsp; flash<span class="br0">&#91;</span><span class="re3">:error</span><span class="br0">&#93;</span> = <span class="st0">'Please upload a file'</span><br />
&nbsp; &nbsp; redirect_to <span class="re3">:action</span> =&gt; <span class="re3">:new</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<h3>Explanation</h3>
<h4>Setup map-fields</h4>
<p>Setup map-fields at the top of the controller.<br />
map_fields accepts three parameters</p>
<ol>
<li>The first is the method to intercept, in this case <b>:create</b>
<li>The second is an array of expected CSV fields. The order of the fields in this array is the order they will be available in the row object when finally reading the CSV file.</li>
<li>Lastly, a hash of options.<br />
         <b>:file_field</b> is the field that contains the import file. This is <i>:file</i> by default<br />
         <b>:params</b> is an array of parameters you want preserved. If you have a form based around a model, you just need to put the model name here and all the sub-fields will be preserved.<br />
So, if you have a form with <i>list[:name]</i> etc, use <i>:params => [:list]</i></li>
</ol>
<h4>Create your <i>new</i> view with a file field</h4>
<p>You can now setup your new view as normal with an included file field<br />
<img src="http://ramblingsonrails.com/wp-content/uploads/2009/06/screenshot_001.png" alt="map-fields_new" title="map-fields_new" width="288" height="152" class="alignnone size-full wp-image-136" /></p>
<h4>Handle the mapping in your create action</h4>
<p>The create action now has to perform two functions, the mapping and then the final creating.<br />
You can call the fields_mapped? method to see if the mapping has been performed and if not, render the mapping view.<br />
There is a mapping partial which you can use so your view is as easy as:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="co1">#create.html.erb</span><br />
&lt;%= render <span class="re3">:partial</span> =&gt; <span class="st0">'map_fields/map_fields'</span> %&gt;</div></div>
<p>and it produces the following:<br />
<img src="http://ramblingsonrails.com/wp-content/uploads/2009/06/screenshot_005.png" alt="map_fields-create" title="map_fields-create" width="321" height="181" class="alignnone size-full wp-image-137" /></p>
<p>When the fields have been mapped, you can iterate through them with:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">mapped_fields.<span class="me1">each</span> <span class="kw1">do</span> |row|<br />
&nbsp; <span class="co1"># row.number returns the number of the row in the original CSV file</span><br />
&nbsp; <span class="co1"># row[0] is the first mapped field, in this case Title</span><br />
&nbsp; <span class="co1"># row[1] is the second mapped field, in this case First name</span><br />
&nbsp; <span class="co1"># row[2] is the third mapped field etc...</span><br />
<span class="kw1">end</span></div></div>
<h4>Two errors can be raised:</h4>
<ol>
<li><b>MapFields::InconsistentStateError</b> is raised when map-fields is unable to determine whether a file is being uploaded or mapped. It can be experienced through a combination of using the back button and refreshes but is seldom experienced.</li>
<li><b>MapFields::MissingFileContentsError</b> is raised when no file has been uploaded</li>
</ol>
<p>Please feel free to ask any questions in the comments and raise issues on the <a href="http://github.com/internuity/map-fields">GitHub</a> page.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=dEbPAceRuWA:SeSVOiqRi-E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=dEbPAceRuWA:SeSVOiqRi-E:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=dEbPAceRuWA:SeSVOiqRi-E:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/map-fields-a-rails-plugin-to-ease-the-importing-of-csv-files/feed</wfw:commentRss>
		</item>
		<item>
		<title>Conditionally include development gems</title>
		<link>http://ramblingsonrails.com/conditionally-include-development-gems</link>
		<comments>http://ramblingsonrails.com/conditionally-include-development-gems#comments</comments>
		<pubDate>Thu, 28 May 2009 05:00:39 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=123</guid>
		<description><![CDATA[I was playing with metric_fu and after having to install multiple dependency gems I realised that it was going to be a pain to put the project into production.
The metric_fu instructions suggest using config.gem in your environment file but that will mean that when you push the app to production, you need to install the [...]]]></description>
			<content:encoded><![CDATA[<p>I was playing with <a href="http://metric-fu.rubyforge.org/">metric_fu</a> and after having to install multiple dependency gems I realised that it was going to be a pain to put the project into production.</p>
<p>The metric_fu instructions suggest using config.gem in your environment file but that will mean that when you push the app to production, you need to install the metric_fu gem and all it&#8217;s dependencies. Considering metric_fu is only used for development, I needed a way around this.</p>
<p>I decided to wrap the Rakefile entry in an environment check</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">if</span> <span class="br0">&#91;</span><span class="st0">'test'</span>, <span class="st0">'development'</span><span class="br0">&#93;</span>.<span class="kw1">include</span>?<span class="br0">&#40;</span>RAILS_ENV<span class="br0">&#41;</span><br />
&nbsp; <span class="kw3">require</span> <span class="st0">'metric_fu'</span><br />
<br />
&nbsp; <span class="re2">MetricFu::Configuration</span>.<span class="me1">run</span> <span class="kw1">do</span> |config|<br />
&nbsp; &nbsp; <span class="co1">#define which metrics you want to use</span><br />
&nbsp; &nbsp; config.<span class="me1">metrics</span>&nbsp; = <span class="br0">&#91;</span><span class="re3">:churn</span>, <span class="re3">:saikuro</span>, <span class="re3">:stats</span>, <span class="re3">:flog</span>, <span class="re3">:flay</span>, <span class="re3">:reek</span>, <span class="re3">:roodi</span>, <span class="re3">:rcov</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; config.<span class="me1">flay</span>&nbsp; &nbsp; &nbsp;= <span class="br0">&#123;</span> <span class="re3">:dirs_to_flay</span> =&gt; <span class="br0">&#91;</span><span class="st0">'app'</span>, <span class="st0">'lib'</span><span class="br0">&#93;</span>&nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; config.<span class="me1">flog</span>&nbsp; &nbsp; &nbsp;= <span class="br0">&#123;</span> <span class="re3">:dirs_to_flog</span> =&gt; <span class="br0">&#91;</span><span class="st0">'app'</span>, <span class="st0">'lib'</span><span class="br0">&#93;</span>&nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; config.<span class="me1">reek</span>&nbsp; &nbsp; &nbsp;= <span class="br0">&#123;</span> <span class="re3">:dirs_to_reek</span> =&gt; <span class="br0">&#91;</span><span class="st0">'app'</span>, <span class="st0">'lib'</span><span class="br0">&#93;</span>&nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; config.<span class="me1">roodi</span>&nbsp; &nbsp; = <span class="br0">&#123;</span> <span class="re3">:dirs_to_roodi</span> =&gt; <span class="br0">&#91;</span><span class="st0">'app'</span>, <span class="st0">'lib'</span><span class="br0">&#93;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; config.<span class="me1">saikuro</span>&nbsp; = <span class="br0">&#123;</span> <span class="re3">:output_directory</span> =&gt; <span class="st0">'scratch_directory/saikuro'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:input_directory</span> =&gt; <span class="br0">&#91;</span><span class="st0">'app'</span>, <span class="st0">'lib'</span><span class="br0">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:cyclo</span> =&gt; <span class="st0">&quot;&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:filter_cyclo</span> =&gt; <span class="st0">&quot;0&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:warn_cyclo</span> =&gt; <span class="st0">&quot;5&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:error_cyclo</span> =&gt; <span class="st0">&quot;7&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:formater</span> =&gt; <span class="st0">&quot;text&quot;</span><span class="br0">&#125;</span> <span class="co1">#this needs to be set to &quot;text&quot;</span><br />
&nbsp; &nbsp; config.<span class="me1">churn</span>&nbsp; &nbsp; = <span class="br0">&#123;</span> <span class="re3">:start_date</span> =&gt; <span class="st0">&quot;1 year ago&quot;</span>, <span class="re3">:minimum_churn_count</span> =&gt; <span class="nu0">10</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; config.<span class="me1">rcov</span>&nbsp; &nbsp; &nbsp;= <span class="br0">&#123;</span> <span class="re3">:test_files</span> =&gt; <span class="br0">&#91;</span><span class="st0">'test/**/*_test.rb'</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">'spec/**/*_spec.rb'</span><span class="br0">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re3">:rcov_opts</span> =&gt; <span class="br0">&#91;</span><span class="st0">&quot;--sort coverage&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;--no-html&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;--text-coverage&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;--no-color&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;--profile&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;--rails&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">&quot;--exclude /gems/,/Library/,spec&quot;</span><span class="br0">&#93;</span><span class="br0">&#125;</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<p>This allows metric_fu to run in either test or development and won&#8217;t even try to load the gem in production.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=_OZbPEMc-X8:4aJw1qu5tmM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=_OZbPEMc-X8:4aJw1qu5tmM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=_OZbPEMc-X8:4aJw1qu5tmM:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/conditionally-include-development-gems/feed</wfw:commentRss>
		</item>
		<item>
		<title>Easily compare a variable with multiple values</title>
		<link>http://ramblingsonrails.com/easily-compare-a-variable-with-multiple-values</link>
		<comments>http://ramblingsonrails.com/easily-compare-a-variable-with-multiple-values#comments</comments>
		<pubDate>Wed, 27 May 2009 04:44:39 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=118</guid>
		<description><![CDATA[I often forget this simple little trick for comparing multiple values against a single variable.
Instead of
var = 2
if var == 1 &#124;&#124; var == 2 &#124;&#124; var == 3
&#160; puts &#34;yes&#34;
end
#=&#62; &#34;yes&#34;
You can do the following
var = 2
if &#91;1,2,3&#93;.include?&#40;var&#41;
&#160; puts &#34;yes&#34;
end
#=&#62; &#34;yes&#34;
]]></description>
			<content:encoded><![CDATA[<p>I often forget this simple little trick for comparing multiple values against a single variable.</p>
<p>Instead of</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">var = <span class="nu0">2</span><br />
<span class="kw1">if</span> var == <span class="nu0">1</span> || var == <span class="nu0">2</span> || var == <span class="nu0">3</span><br />
&nbsp; <span class="kw3">puts</span> <span class="st0">&quot;yes&quot;</span><br />
<span class="kw1">end</span><br />
<span class="co1">#=&gt; &quot;yes&quot;</span></div></div>
<p>You can do the following</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">var = <span class="nu0">2</span><br />
<span class="kw1">if</span> <span class="br0">&#91;</span><span class="nu0">1</span>,<span class="nu0">2</span>,<span class="nu0">3</span><span class="br0">&#93;</span>.<span class="kw1">include</span>?<span class="br0">&#40;</span>var<span class="br0">&#41;</span><br />
&nbsp; <span class="kw3">puts</span> <span class="st0">&quot;yes&quot;</span><br />
<span class="kw1">end</span><br />
<span class="co1">#=&gt; &quot;yes&quot;</span></div></div>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=RMomS659T7Q:jL6WLw0E8eQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=RMomS659T7Q:jL6WLw0E8eQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=RMomS659T7Q:jL6WLw0E8eQ:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/easily-compare-a-variable-with-multiple-values/feed</wfw:commentRss>
		</item>
		<item>
		<title>Setting the session base domain in Rails 2.3</title>
		<link>http://ramblingsonrails.com/setting-the-session-base-domain-in-rails-23</link>
		<comments>http://ramblingsonrails.com/setting-the-session-base-domain-in-rails-23#comments</comments>
		<pubDate>Wed, 29 Apr 2009 04:26:38 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=111</guid>
		<description><![CDATA[Prior to Rails 2.3, you could set the session base domain as follows:
ActionController::Base.session_options&#91;:session_domain&#93; = '.example.com'
In Rails 2.3, this needs to change to:
config.action_controller.session&#91;:domain&#93; = '.example.com'
I usually set this in my config/environments/.rb configuration files but it could be set in config/environment.rb if you want it to apply across configurations.
Background
This setting will allow for a shared session across [...]]]></description>
			<content:encoded><![CDATA[<p>Prior to Rails 2.3, you could set the session base domain as follows:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="re2">ActionController::Base</span>.<span class="me1">session_options</span><span class="br0">&#91;</span><span class="re3">:session_domain</span><span class="br0">&#93;</span> = <span class="st0">'.example.com'</span></div></div>
<p>In Rails 2.3, this needs to change to:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">config.<span class="me1">action_controller</span>.<span class="me1">session</span><span class="br0">&#91;</span><span class="re3">:domain</span><span class="br0">&#93;</span> = <span class="st0">'.example.com'</span></div></div>
<p>I usually set this in my config/environments/<environment>.rb configuration files but it could be set in config/environment.rb if you want it to apply across configurations.</p>
<h2>Background</h2>
<p>This setting will allow for a shared session across multiple subdomains.</p>
<p>This is useful where you want a user to login at www.example.com and then be able to remain logged in when accessing user.example.com</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=tGTj-1hwpuY:xjv5eMJrdxc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=tGTj-1hwpuY:xjv5eMJrdxc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=tGTj-1hwpuY:xjv5eMJrdxc:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/setting-the-session-base-domain-in-rails-23/feed</wfw:commentRss>
		</item>
		<item>
		<title>Using Webrat’s save_and_open_page on Linux</title>
		<link>http://ramblingsonrails.com/using-webrats-save_and_open_page-on-linux</link>
		<comments>http://ramblingsonrails.com/using-webrats-save_and_open_page-on-linux#comments</comments>
		<pubDate>Tue, 17 Mar 2009 15:28:11 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[testing]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[ruby webrat test cucumber]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=106</guid>
		<description><![CDATA[Mmmm, this year has flown and I have done hardly any blogging, despite my intention to blog at least once a week. Oh, well. My excuse is working extra hard to cover a family holiday and the upcoming trip to Scottland on Rails.
The best way to get going on something is to just do it [...]]]></description>
			<content:encoded><![CDATA[<p>Mmmm, this year has flown and I have done hardly any blogging, despite my intention to blog at least once a week. Oh, well. My excuse is working extra hard to cover a family holiday and the upcoming trip to Scottland on Rails.</p>
<p>The best way to get going on something is to just do it so here is a quick post on how to view the page you&#8217;re working on in Webrat with it&#8217;s save page feature when on Linux (It is currently only works on Windows and Mac)</p>
<p>A quick monkey patch in your test helper or Cucumber env file:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">module</span> <span class="re2">Webrat::SaveAndOpenPage</span><br />
&nbsp; alias_method <span class="re3">:old_open_in_browser</span>, <span class="re3">:open_in_browser</span><br />
&nbsp; <span class="kw1">def</span> open_in_browser<span class="br0">&#40;</span>path<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> ruby_platform =~ /linux/i<br />
&nbsp; &nbsp; &nbsp; <span class="st0">`firefox #{path}`</span><br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; old_open_in_browser path<br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<p>This is not perfect because it is specific to using Firefox, but I know most of you use Firefox anyway, and at least it will continue to work for those using Windows or Mac</p>
<p>Now let&#8217;s hope I can get my work load under control and post more frequently.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=t_cD3-WyEr0:SVlocEPM1B4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~ff/RamblingsOnRails?a=t_cD3-WyEr0:SVlocEPM1B4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/RamblingsOnRails?i=t_cD3-WyEr0:SVlocEPM1B4:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/using-webrats-save_and_open_page-on-linux/feed</wfw:commentRss>
		</item>
		<item>
		<title>New Rails plugin - Quick Scopes</title>
		<link>http://ramblingsonrails.com/new-rails-plugin-quick-scopes</link>
		<comments>http://ramblingsonrails.com/new-rails-plugin-quick-scopes#comments</comments>
		<pubDate>Tue, 27 Jan 2009 10:17:58 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[plugins]]></category>

		<category><![CDATA[named_scopes]]></category>

		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=100</guid>
		<description><![CDATA[I&#8217;ve just release a new Rails plugin called Quick Scopes that adds some generic named_scopes to your models to quickly manipulate the results you receive from associations.
It&#8217;s great to have easy access to methods to get all associations but sometimes you need to manipulate how you receive those results.
Included named_scopes:

limit - to limit the number [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just release a new Rails plugin called <a href="http://github.com/internuity/quick_scopes">Quick Scopes</a> that adds some generic named_scopes to your models to quickly manipulate the results you receive from associations.</p>
<p>It&#8217;s great to have easy access to methods to get all associations but sometimes you need to manipulate how you receive those results.</p>
<h2>Included named_scopes:</h2>
<ul>
<li>limit - to limit the number of results</li>
<li>order - to order the results</li>
<li>where - alias for conditions</li>
<li>with - alias for include</li>
</ul>
<h2>Examples</h2>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="co1"># Returns all the comments on the post</span><br />
post.<span class="me1">comments</span><br />
<br />
<span class="co1"># Using quick scopes, you will be able to do the following:</span><br />
<br />
<span class="co1"># Limit the number of results</span><br />
post.<span class="me1">comments</span>.<span class="me1">limit</span><span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># and, order the results</span><br />
post.<span class="me1">comments</span>.<span class="me1">order</span><span class="br0">&#40;</span><span class="st0">'created_at desc'</span><span class="br0">&#41;</span>.<span class="me1">limit</span><span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># and, add conditions to the query</span><br />
post.<span class="me1">comments</span>.<span class="me1">where</span><span class="br0">&#40;</span><span class="re3">:approved</span> =&gt; <span class="kw2">true</span><span class="br0">&#41;</span>.<span class="me1">order</span><span class="br0">&#40;</span><span class="st0">'created_at desc'</span><span class="br0">&#41;</span>.<span class="me1">limit</span><span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span><br />
<br />
<span class="co1"># and, include sub-associations</span><br />
post.<span class="me1">comments</span>.<span class="me1">with</span><span class="br0">&#40;</span><span class="re3">:author</span><span class="br0">&#41;</span>.<span class="me1">where</span><span class="br0">&#40;</span><span class="re3">:approved</span> =&gt; <span class="kw2">true</span><span class="br0">&#41;</span>.<span class="me1">order</span><span class="br0">&#40;</span><span class="st0">'created_at desc'</span><span class="br0">&#41;</span>.<span class="me1">limit</span><span class="br0">&#40;</span><span class="nu0">5</span><span class="br0">&#41;</span></div></div>
<p>If you need all the manipulation of the last couple of examples, you probably should create a specific named_scope but this can be very useful to have available on the console.</p>
<p>Have a look and let me know how it works for you and what you would do differently.</p>
<p>Quick Scopes: <a href="http://github.com/internuity/quick_scopes">http://github.com/internuity/quick_scopes</a></p>
<h3>Install</h3>
<div class="codecolorer-container bash"><div class="codecolorer" style="font-family: monospace;">./script/plugin install git://github.com/internuity/quick_scopes.git</div></div>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=Jn57A1Bv"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=nbggSDAS"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=nbggSDAS" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/new-rails-plugin-quick-scopes/feed</wfw:commentRss>
		</item>
		<item>
		<title>How to protect downloads but still have nginx serve the files</title>
		<link>http://ramblingsonrails.com/how-to-protect-downloads-but-still-have-nginx-serve-the-files</link>
		<comments>http://ramblingsonrails.com/how-to-protect-downloads-but-still-have-nginx-serve-the-files#comments</comments>
		<pubDate>Tue, 13 Jan 2009 05:37:03 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[authorization]]></category>

		<category><![CDATA[downloads]]></category>

		<category><![CDATA[files]]></category>

		<guid isPermaLink="false">http://ramblingsonrails.com/?p=88</guid>
		<description><![CDATA[I&#8217;ve just been working on a project where a number of downloads needed to be restricted to specific users. I needed to authenticate the user and then allow them access to the file. This is not too difficult in rails:
def download
&#160; if authenticated?
&#160; &#160; send_file #{RAILS_ROOT}/downloads/images/myfile.zip'
&#160; end
end
The problem with this is that if the file [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just been working on a project where a number of downloads needed to be restricted to specific users. I needed to authenticate the user and then allow them access to the file. This is not too difficult in rails:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">def</span> download<br />
&nbsp; <span class="kw1">if</span> authenticated?<br />
&nbsp; &nbsp; send_file <span class="co1">#{RAILS_ROOT}/downloads/images/myfile.zip'</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<p>The problem with this is that if the file is large, rails will spend a lot of time sending this file to the browser. The solution, hand it off to the webserver (in my case, nginx) to send the file once the authentication has succeeded.</p>
<p>nginx supports a header named <i>X-Accel-Redirect</i>. Using this header, you send a full path to the file to be downloaded:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">def</span> download<br />
&nbsp; <span class="kw1">if</span> authenticated?<br />
&nbsp; &nbsp; <span class="co1">#Set the X-Accel-Redirect header with the path relative to the /downloads location in nginx</span><br />
&nbsp; &nbsp; response.<span class="me1">headers</span><span class="br0">&#91;</span><span class="st0">'X-Accel-Redirect'</span><span class="br0">&#93;</span> = <span class="st0">'/downloads/myfile.zip'</span><br />
&nbsp; &nbsp; <span class="co1">#Set the Content-Type header as nginx won't change it and Rails will send text/html</span><br />
&nbsp; &nbsp; response.<span class="me1">headers</span><span class="br0">&#91;</span><span class="st0">'Content-Type'</span><span class="br0">&#93;</span> = <span class="st0">'application/octet-stream'</span><br />
&nbsp; &nbsp; <span class="co1">#If you want to force download, set the Content-Disposition header (which nginx won't change)</span><br />
&nbsp; &nbsp; response.<span class="me1">headers</span><span class="br0">&#91;</span><span class="st0">'Content-Disposition'</span><span class="br0">&#93;</span> = <span class="st0">'attachment; filename=myfile.zip'</span><br />
&nbsp; &nbsp; <span class="co1">#Make sure we don't render anything</span><br />
&nbsp; &nbsp; render <span class="re3">:nothing</span> =&gt; <span class="kw2">true</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<p>You will need to add a <i>location</i> directive in nginx marked as <i>internal</i> which nginx will use along with your path to get to the physical file.</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">location /downloads <span class="br0">&#123;</span><br />
&nbsp; root /rails_deploy/current/downloads;<br />
&nbsp; <span class="co1">#Marked internal so that this location cannot be accessed directly.</span><br />
&nbsp; internal;<br />
<span class="br0">&#125;</span></div></div>
<p><b>Notes: </b> </p>
<ul>
<li>You need to include the <i>Content-Type</i> header because nginx won&#8217;t change it and Rails sets it to text/html by default.</li>
<li>The path you send in the <i>X-Accel-Redirect</i> header must be relative to a <i>location</i> directive within your nginx config.</li>
</ul>
<p>You can also set additional control using the following headers:</p>
<div class="codecolorer-container text">X-Accel-Limit-Rate: 1024<br />
X-Accel-Buffering: yes|no<br />
X-Accel-Charset: utf-8</div>
<p>See the <a href="http://wiki.codemongers.com/NginxXSendfile">nginx documentation on X-Accel-Redirect</a> for more information.</p>
<p>Updated: Thanks to rick&#8217;s comment below I&#8217;ve included information on the <i>location</i> directive within nginx to ensure the &#8216;downloads&#8217; are not accessible from outside</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=11PCu8QO"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=YZftHKIA"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=YZftHKIA" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/how-to-protect-downloads-but-still-have-nginx-serve-the-files/feed</wfw:commentRss>
		</item>
		<item>
		<title>How to make a custom form builder in Rails</title>
		<link>http://ramblingsonrails.com/how-to-make-a-custom-form-builder-in-rails</link>
		<comments>http://ramblingsonrails.com/how-to-make-a-custom-form-builder-in-rails#comments</comments>
		<pubDate>Tue, 06 Jan 2009 06:11:56 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[form builder]]></category>

		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=37</guid>
		<description><![CDATA[A quick run through creating a custom form builder in rails. This particular form builder will inline error messages into your form labels.]]></description>
			<content:encoded><![CDATA[<p>A Form builder is a great way to remove repetative code from your form views or to include some custom code into the existing helpers.<br />
I wanted to change how I displayed error information in my forms and decided to do it in a form builder and this is how.</p>
<h2>Overview</h2>
<p>There are two common ways of displaying error information, in an error block at the top of the page via <i>error_messages_for :model</i> or inline above or below the field using <i>error_message_on :model, :field</i></p>
<p>When using <i>error_message_on :model, :field</i> I find that I always have to use the <i>:prepend_text</i> to get the error message to display nicely. So my error handling always looks like this:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">&lt;%= form.<span class="me1">label</span> <span class="re3">:name</span> %&gt;<br />
&lt;%= error_message_on <span class="re3">:user</span>, <span class="re3">:name</span>, <span class="re3">:prepend_text</span> =&gt; <span class="st0">'Name '</span> %&gt;<br />
&lt;%= form.<span class="me1">text_field</span> <span class="re3">:name</span> %&gt;</div></div>
<p>and the form is displayed as:</p>
<p><b>Name</b><br />
<span style="color: #ff0000">Name can&#8217;t be blank</span></p>
<p>I then thought that the label is already displaying the &#8220;prepend_text&#8221; so why not inline the error message directly after the label. With a custom form builder (code below), my code just looks like this and the errors will still be displayed:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">&lt;%= form.<span class="me1">label</span> <span class="re3">:name</span> %&gt;<br />
&lt;%= form.<span class="me1">text_field</span> <span class="re3">:name</span> %&gt;</div></div>
<p>and the form is displayed as:</p>
<p><strong>Name</strong><span style="color: #ff0000;"> can&#8217;t be blank</span></p>
<h2>The code</h2>
<p>This form builder is going to be very simple because I&#8217;m only changing the handling of the label helper but the concepts carry through to any of the form helpers you want to extend.</p>
<p>Because I need to get to the errors object on the model, I had to bring in some repeat code from the label_tag helper. The default Rails form builder can be found in [rails/gem path]/actionpack/lib/action_view/helpers/form_helper.rb starting just after line 700.<br />
Unfortunately the FormBuilder seems to be undocumented so you won&#8217;t find documentation in the Rails API docs.</p>
<p>I&#8217;ve written comments throughout the code to explain what I&#8217;ve done.</p>
<p>[lib/error_form_builder.rb]</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">class</span> ErrorFormBuilder &lt; <span class="re2">ActionView::Helpers::FormBuilder</span><br />
&nbsp; <span class="co1">#Adds error message directly inline to a form label</span><br />
&nbsp; <span class="co1">#Accepts all the options normall passed to form.label as well as:</span><br />
&nbsp; <span class="co1">#&nbsp; :hide_errors - true if you don't want errors displayed on this label</span><br />
&nbsp; <span class="co1">#&nbsp; :additional_text - Will add additional text after the error message or after the label if no errors</span><br />
&nbsp; <span class="kw1">def</span> label<span class="br0">&#40;</span>method, text = <span class="kw2">nil</span>, options = <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="co1">#Check to see if text for this label has been supplied and humanize the field name if not.</span><br />
&nbsp; &nbsp; text = text || method.<span class="me1">to_s</span>.<span class="me1">humanize</span><br />
&nbsp; &nbsp; <span class="co1">#Get a reference to the model object</span><br />
&nbsp; &nbsp; object = <span class="re1">@template</span>.<span class="me1">instance_variable_get</span><span class="br0">&#40;</span><span class="st0">&quot;@#{@object_name}&quot;</span><span class="br0">&#41;</span><br />
<br />
&nbsp; &nbsp; <span class="co1">#Make sure we have an object and we're not told to hide errors for this label</span><br />
&nbsp; &nbsp; <span class="kw1">unless</span> object.<span class="kw2">nil</span>? || options<span class="br0">&#91;</span><span class="re3">:hide_errors</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">#Check if there are any errors for this field in the model</span><br />
&nbsp; &nbsp; &nbsp; errors = object.<span class="me1">errors</span>.<span class="me1">on</span><span class="br0">&#40;</span>method.<span class="me1">to_sym</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> errors<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">#Generate the label using the text as well as the error message wrapped in a span with error class</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; text += <span class="st0">&quot; &lt;span class=<span class="es0">\&quot;</span>error<span class="es0">\&quot;</span>&gt;#{errors.is_a?(Array) ? errors.first : errors}&lt;/span&gt;&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; <span class="co1">#Add any additional text that might be needed on the label</span><br />
&nbsp; &nbsp; text += <span class="st0">&quot; #{options[:additional_text]}&quot;</span> <span class="kw1">if</span> options<span class="br0">&#91;</span><span class="re3">:additional_text</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="co1">#Finally hand off to super to deal with the display of the label</span><br />
&nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>method, text, options<span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></div>
<h2>Using your custom form builder</h2>
<p>If you want to use your custom form builder for a single form, include this in your form declaration:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">&lt;% form_for <span class="re3">:object</span>, <span class="re3">:builder</span> =&gt; ErrorFormBuilder <span class="kw1">do</span> |form| %&gt;<br />
&lt;% <span class="kw1">end</span> %&gt;</div></div>
<p>If you want to make your custom form builder the default builder for your project, you can add the following line to your config/environment.rb file:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="re2">ActionView::Base</span>.<span class="me1">default_form_builder</span> = ErrorFormBuilder</div></div>
<p>If you have any questions on how this works, feel free to ask in the comments.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=ZJgogepG"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=CyQCCgbl"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=CyQCCgbl" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/how-to-make-a-custom-form-builder-in-rails/feed</wfw:commentRss>
		</item>
		<item>
		<title>How to migrate a Rails app from using Attachment_fu to Paperclip</title>
		<link>http://ramblingsonrails.com/how-to-migrate-a-rails-app-from-attachment_fu-to-paperclip</link>
		<comments>http://ramblingsonrails.com/how-to-migrate-a-rails-app-from-attachment_fu-to-paperclip#comments</comments>
		<pubDate>Fri, 02 Jan 2009 14:30:40 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[attachments]]></category>

		<category><![CDATA[attachment_fu]]></category>

		<category><![CDATA[paperclip]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=70</guid>
		<description><![CDATA[A run through on how to migrate a project from using Attachment_fu to Paperclip as attachment plugin. This includes all the steps for a seamless upgrade including changing the file layouts on Amazon S3.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just had to migrate a Rails app from using <a href="http://github.com/technoweenie/attachment_fu/tree/master">Attachment_fu</a> to <a href="http://www.thoughtbot.com/projects/paperclip">Paperclip</a> and I decided I&#8217;d better document the process.</p>
<p>Most importantly, the app has a couple of thousand photos and I&#8217;m going to have to make the live transition as smooth as possible so it&#8217;s important that I can do all the development without affecting the live app and then I need to move all the Amazon S3 files using access to the original Attachment_fu model information and then go live with the Paperclip code.</p>
<h2>Creating a copy of the Amazon S3 bucket</h2>
<p>First step is to create a copy of the live S3 bucket which is important for testing. I have written a set of rake tasks to do most of the heavy lifting.<br />
All of the S3 work is done using right_aws which is needed by Paperclip and can be installed by running:</p>
<div class="codecolorer-container text">gem install right_aws</div>
<p>To create a copy of your S3 bucket, run</p>
<div class="codecolorer-container text">rake utils:attachments:copy_s3_bucket FROM=production_bucket_name TO=backup_bucket_name</div>
<h2>Moving the Amazon S3 keys from Attachment_fu scheme to Paperclips</h2>
<p>Paperclip supports a completely configurable naming scheme while Attachment_fu is prescribed.</p>
<p>I wrote a <a href="https://gist.github.com/42523/88326b56495669dea9d2236dc1e653ff0b7c0b8a">rake task</a> to physically move the keys around so that they matched my required Paperclip scheme. Initially I performed this task on the backup bucket so that I could begin writing code against the backup bucket.</p>
<p>The paperclip naming scheme I&#8217;m using is <em>:id/:style.:extension</em></p>
<p>The migration is also handled by a rake task <em>utils:attachments:migrate_attachment_fu_to_paperclip</em></p>
<p>This rake task is specific to the code being refactored and you will need to do some editing.</p>
<ul>
<li><strong>Line 63 - </strong>Change Klass to the class of your model, in my case it is Photo</li>
<li><strong>Lines 75 &amp; 83 - </strong>Change the format of the <em>new_key_name</em> if you want to use a naming scheme other than<em> :id/:style.:extension</em></li>
</ul>
<p>The rake task must then be run (do it first on your backup bucket)</p>
<div class="codecolorer-container text">rake utils:attachments:<span class="ss">migrate_attachment_fu_to_paperclip BUCKET=backup_bucket_name</div>
<p></span></p>
<h2>Changing the code</h2>
<p>Now time to change the code itself. There are links to various gist files in the resources section at the end of this article.</p>
<h3>Migration</h3>
<p>First we&#8217;ll need a migration to change the model table format. The migration is specific to my Photo model so you&#8217;ll have to change both the model and table references to your specific project details.</p>
<p>The migration first renames the re-usable columns such as filename, content_type and size and then removes the columns that paperclip doesn&#8217;t use/support. Finally the migration removes all of Attachment_fu&#8217;s child entries from the database table.</p>
<h3>Model</h3>
<p>This is where everything gets tricky and we have to be careful not to mess up the order.</p>
<p>We have created a backup of our S3 bucket and now we have run a migration on our development database. The migration uses the Attachment_fu model information which we are now going to change. <strong>If you try to run the migration after you&#8217;ve changed the model, things won&#8217;t work</strong> so remember this for when the changes go live.</p>
<p>View the diff of my changes here: <a href="http://gist.github.com/42525">http://gist.github.com/42525</a></p>
<h3>Controller</h3>
<p>In your controller, Attachment_fu relies on a single attribute <em>uploaded_data</em> where Paperclip relies on an attribute the same as your attachment, in my case <em>photo</em>.</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">owner.<span class="me1">photo</span>.<span class="me1">create</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:uploaded_data</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></div>
<p>becomes</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">owner.<span class="me1">photo</span> = params<span class="br0">&#91;</span><span class="re3">:owner</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="re3">:photo</span><span class="br0">&#93;</span><br />
owner.<span class="me1">save</span></div></div>
<p>or, simply</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">owner = Owner.<span class="me1">create</span><span class="br0">&#40;</span>params<span class="br0">&#91;</span><span class="re3">:owner</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></div>
<h2>Going live</h2>
<p>OK, so you&#8217;ve finished working on development and you&#8217;re happy that everything works as intended against your backup S3 bucket. Now it&#8217;s time for the nail-biting push to live.</p>
<p>Do everything in the following order<strong> (Please don&#8217;t try to  do any of these steps at the same time - I did and it bit me!)</strong>:</p>
<ol>
<li>Backup your production database</li>
<li>Upload just your rake task to your server</li>
<li>Run the following rake tasks:
<ul>
<li><em>rake utils:attachments:clear_s3_bucket BUCKET=backup_bucket_name</em> - Clears out all the files you&#8217;ve been testing with.</li>
<li><em>rake utils:attachments:copy_s3_bucket FROM=production_bucket_name TO=backup_bucket_name</em> - Re-backs up the production files (just in case)</li>
<li><em>rake utils:attachments:</em><span class="ss"><em>migrate_attachment_fu_to_paperclip BUCKET=production_bucket_name</em> - Does the migration on the production S3 bucket<br />
</span></li>
</ul>
</li>
<li>Upload your migration to the live server</li>
<li>Run your migration</li>
<li>Run your normal deployment to get the new files on the server</li>
<li>Congratulations! You&#8217;ve done it.</li>
</ol>
<p>Rolling back</p>
<p>Should anything go wrong, you simply do the following:</p>
<ol>
<li>Run the rake tasks
<ul>
<li><em>rake utils:attachments:clear_s3_bucket BUCKET=production_bucket_name</em> - Clears out all the files that are in the wrong format.</li>
<li><em>rake utils:attachments:copy_s3_bucket FROM=backup_bucket_name TO=production_bucket_name</em> - Restores the production files from the backup bucket (this is why we did all that work :-))</li>
</ul>
</li>
<li><span class="ss">Restore your production database</span></li>
<li><span class="ss">Restore your previous code<br />
</span></li>
</ol>
<h2>Resources</h2>
<ul>
<li>S3 rake tasks - <a href="http://gist.github.com/42523">http://gist.github.com/42523</a></li>
<li>Model migration - <a href="http://gist.github.com/42524">http://gist.github.com/42524</a></li>
<li>Model code diff - <a href="http://gist.github.com/42525">http://gist.github.com/42525</a></li>
</ul>
<h2>Final words</h2>
<p>This was quite tricky and I only hope that my code and examples help a little. If you have any questions, feel free to leave a comment and I&#8217;ll help where I can.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=RH5oq1Nv"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=rOARPRCb"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=rOARPRCb" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/how-to-migrate-a-rails-app-from-attachment_fu-to-paperclip/feed</wfw:commentRss>
		</item>
		<item>
		<title>A Rails log parser to show how your actions are performing</title>
		<link>http://ramblingsonrails.com/a-rails-log-parser-to-show-how-your-actions-are-performing</link>
		<comments>http://ramblingsonrails.com/a-rails-log-parser-to-show-how-your-actions-are-performing#comments</comments>
		<pubDate>Wed, 31 Dec 2008 10:15:17 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[utils]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=55</guid>
		<description><![CDATA[I&#8217;ve been battling with some performance issues on a Rails project I&#8217;m working on and I wanted to see which actions could be the culprit.
I wrote a quick log parser which will read a log file and print out the call time information by controller#action. It supports sorting by various columns and outputs the results [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been battling with some performance issues on a Rails project I&#8217;m working on and I wanted to see which actions could be the culprit.</p>
<p>I wrote a quick log parser which will read a log file and print out the call time information by controller#action. It supports sorting by various columns and outputs the results in pretty table format (similar to mysql)</p>
<p>View usage information by running:</p>
<div class="codecolorer-container text">ruby_log_parser.rb --help</div>
<h2>Example</h2>
<div class="codecolorer-container bash"><div class="codecolorer" style="font-family: monospace;">andrew:~$ ruby rails_log_parser.rb --sort median &lt; log/development.log<br />
+----------------------+-------+------------+------+------+------+--------+<br />
| Uri&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Calls | Total Time | Max&nbsp; | Min&nbsp; | Avg&nbsp; | Median |<br />
+----------------------+-------+------------+------+------+------+--------+<br />
| TestController<span class="re3">#index |&nbsp; &nbsp; &nbsp;<span class="nu0">7</span> |&nbsp; &nbsp; &nbsp; &nbsp;<span class="nu0">9316</span> | <span class="nu0">1748</span> | <span class="nu0">1053</span> | <span class="nu0">1330</span> |&nbsp; &nbsp;<span class="nu0">1221</span> |</span><br />
| TestController<span class="re3">#show&nbsp; |&nbsp; &nbsp; &nbsp;<span class="nu0">1</span> |&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">764</span> |&nbsp; <span class="nu0">764</span> |&nbsp; <span class="nu0">764</span> |&nbsp; <span class="nu0">764</span> |&nbsp; &nbsp; <span class="nu0">764</span> |</span><br />
+----------------------+-------+------------+------+------+------+--------+</div></div>
<h2>The code</h2>
<p>You can find the parser here:<br />
<a href="http://github.com/andrewtimberlake/scripts/tree/master/rails/utils/rails_log_parser.rb">http://github.com/andrewtimberlake/scripts/tree/master/rails/utils/rails_log_parser.rb</a></p>
<p>I have also stripped out the table pretty printing here:<br />
<a href="http://gist.github.com/41938">http://gist.github.com/41938</a></p>
<p><b>Usage:</b></p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw3">require</span> <span class="st0">'tabalize_array'</span><br />
<br />
arr = <span class="br0">&#91;</span><br />
&nbsp; <span class="br0">&#91;</span><span class="st0">'John'</span>, <span class="nu0">18</span><span class="br0">&#93;</span>,<br />
&nbsp; <span class="br0">&#91;</span><span class="st0">'Jack'</span>, <span class="nu0">21</span><span class="br0">&#93;</span>,<br />
&nbsp; <span class="br0">&#91;</span><span class="st0">'Mary'</span>, <span class="nu0">22</span><span class="br0">&#93;</span>,<br />
&nbsp; <span class="br0">&#91;</span><span class="st0">'Jane'</span>, <span class="nu0">24</span><span class="br0">&#93;</span><br />
<span class="br0">&#93;</span><br />
arr.<span class="me1">tabalize</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span class="st0">'Name'</span>, <span class="st0">'Age'</span><span class="br0">&#93;</span>, <span class="br0">&#91;</span><span class="re3">:left</span>, <span class="re3">:right</span><span class="br0">&#93;</span>, STDOUT<span class="br0">&#41;</span></div></div>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=sQtEg7W9"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=bn04CR3Q"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=bn04CR3Q" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/a-rails-log-parser-to-show-how-your-actions-are-performing/feed</wfw:commentRss>
		</item>
		<item>
		<title>Automatically handle unexpected Ajax errors in Rails</title>
		<link>http://ramblingsonrails.com/automatically-handle-unexpected-ajax-errors-in-rails</link>
		<comments>http://ramblingsonrails.com/automatically-handle-unexpected-ajax-errors-in-rails#comments</comments>
		<pubDate>Tue, 30 Dec 2008 14:33:31 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[ajax]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=52</guid>
		<description><![CDATA[I&#8217;m busy working on a project that uses a lot of Ajax to deal with updates and lookups etc. Occasionally I write rubbish code and one of these methods break.
When using normal HTML this is not a problem because Rails presents the user with a nice message saying &#8220;We&#8217;re sorry but something went wrong&#8230;&#8221;.
But, with [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m busy working on a project that uses a lot of Ajax to deal with updates and lookups etc. Occasionally I write rubbish code and one of these methods break.</p>
<p>When using normal HTML this is not a problem because Rails presents the user with a nice message saying &#8220;We&#8217;re sorry but something went wrong&#8230;&#8221;.<br />
But, with Ajax, Rails returns the exact same page which is useless in an Ajax call. Because of this, users are generally left without knowing if their request is taking a long time or has failed.</p>
<p>I dug into Rails error handling and decided to deal with this so that errors pop-up an alert message with the same message as the HTML 500 error. I also wanted to get more error information if I get an error in development.<br />
The two magic methods you need to override in your application controller are: <a href="http://api.rubyonrails.org/classes/ActionController/Rescue.html#M000260">rescue_action_in_public</a> and <a href="http://api.rubyonrails.org/classes/ActionController/Rescue.html#M000263">rescue_action_locally</a>.</p>
<p>I simply defined my own version of these methods and checked for an Ajax call with a respond_to block. If the request is for standard HTML, I delegate the call back to the superclass so everything continues as normal and if it&#8217;s a Javascript call, I send back an alert message.</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">class</span> ApplicationController &lt; <span class="re2">ActionController::Base</span><br />
<br />
...<br />
<br />
<span class="me1">private</span><br />
&nbsp; <span class="kw1">def</span> rescue_action_in_public<span class="br0">&#40;</span>exception<span class="br0">&#41;</span><br />
&nbsp; &nbsp; respond_to <span class="kw1">do</span> |want|<br />
&nbsp; &nbsp; &nbsp; want.<span class="me1">html</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>exception<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; want.<span class="me1">js</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; render <span class="re3">:update</span> <span class="kw1">do</span> |page|<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page.<span class="me1">alert</span> <span class="st0">&quot;We're sorry, but something went wrong.<span class="es0">\n</span>We've been notified about this issue and we'll take a look at it shortly.<span class="es0">\n</span><span class="es0">\n</span>Please check that any update you tried has not been successful before trying it again.&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="kw1">end</span><br />
<br />
&nbsp; <span class="kw1">def</span> rescue_action_locally<span class="br0">&#40;</span>exception<span class="br0">&#41;</span><br />
&nbsp; &nbsp; respond_to <span class="kw1">do</span> |want|<br />
&nbsp; &nbsp; &nbsp; want.<span class="me1">html</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">super</span><span class="br0">&#40;</span>exception<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; want.<span class="me1">js</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; render <span class="re3">:update</span> <span class="kw1">do</span> |page|<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page.<span class="me1">alert</span> <span class="st0">&quot;Oops! I made a mistake<span class="es0">\n</span>#{exception.class}: #{exception.message}<span class="es0">\n</span>Check the logs for more detail.&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="kw1">end</span><br />
<br />
...<br />
<br />
<span class="kw1">end</span></div></div>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=IWL0z3vR"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=OLIa2oSW"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=OLIa2oSW" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/automatically-handle-unexpected-ajax-errors-in-rails/feed</wfw:commentRss>
		</item>
		<item>
		<title>Display your current GIT branch in your prompt</title>
		<link>http://ramblingsonrails.com/display-your-current-git-branch-in-your-prompt</link>
		<comments>http://ramblingsonrails.com/display-your-current-git-branch-in-your-prompt#comments</comments>
		<pubDate>Mon, 29 Dec 2008 12:52:02 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[git]]></category>

		<category><![CDATA[git bash tip]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=44</guid>
		<description><![CDATA[I spotted a customised prompt on someone&#8217;s computer and remembered that you can control what&#8217;s displayed in your prompt. This led to an immediate Ah-ha moment that I should display my current working GIT branch there to stop having to keep running git branch to remember which branch I&#8217;m working in.
I quickly Googled to see [...]]]></description>
			<content:encoded><![CDATA[<p>I spotted a customised prompt on someone&#8217;s computer and remembered that you can control what&#8217;s displayed in your prompt. This led to an immediate Ah-ha moment that I should display my current working GIT branch there to stop having to keep running git branch to remember which branch I&#8217;m working in.</p>
<p>I quickly Googled to see if someone else had the same idea (which they invariably have) and found <a href="http://www.simplisticcomplexity.com/2008/03/13/show-your-git-branch-name-in-your-prompt/">a solution</a> which I have adjusted to the standard Ubuntu prompt.</p>
<p>Add this to your .bashrc file in your home directory:</p>
<div class="codecolorer-container bash"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">function</span> parse_git_branch <span class="br0">&#123;</span><br />
&nbsp; git branch --no-color <span class="nu0">2</span>&gt; /dev/null | sed -e <span class="st0">'/^[^*]/d'</span> -e <span class="st0">'s/* (.*)/(1)/'</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re2">PS1=</span><span class="st0">&quot;${debian_chroot:+($debian_chroot)}u@h:w$(parse_git_branch)$ &quot;</span></div></div>
<p>When done, save the file and run</p>
<div class="codecolorer-container text">. ~/.bashrc</div>
<p>to reload the settings and see your new prompt</p>
<p>Mine is: (outside of a git repository)</p>
<div class="codecolorer-container text">andrew@thinkpad:~$</div>
<p>and within a repository</p>
<div class="codecolorer-container text">andrew@thinkpad:~/dev/test(master)$</div>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=CWGfI7Ln"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=yhDPMHtU"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=yhDPMHtU" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/display-your-current-git-branch-in-your-prompt/feed</wfw:commentRss>
		</item>
		<item>
		<title>How to use the new templates in Rails</title>
		<link>http://ramblingsonrails.com/how-to-use-the-new-templates-in-rails</link>
		<comments>http://ramblingsonrails.com/how-to-use-the-new-templates-in-rails#comments</comments>
		<pubDate>Sat, 27 Dec 2008 17:38:28 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[howto]]></category>

		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=20</guid>
		<description><![CDATA[One of the new features in the upcoming Rails 2.3 is templates. I&#8217;ve been playing around with them and have documented some ways of using them below.
To start with, there&#8217;s a great write-up on most of the template methods on Pratik Naik&#8217;s blog
I want to play with some ideas around how you can further customise [...]]]></description>
			<content:encoded><![CDATA[<p>One of the new features in the upcoming Rails 2.3 is templates. I&#8217;ve been playing around with them and have documented some ways of using them below.</p>
<p>To start with, there&#8217;s a great write-up on most of the template methods on <a href="http://m.onkey.org/2008/12/4/rails-templates">Pratik Naik&#8217;s blog</a></p>
<p>I want to play with some ideas around how you can further customise an initial rails project.</p>
<h2>Initial template</h2>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="co1">#Install gems</span><br />
gem <span class="st0">'mocha'</span><br />
gem <span class="st0">'thoughtbot-shoulda'</span><br />
gem <span class="st0">'thoughtbot-factory_girl'</span><br />
gem <span class="st0">'thoughtbot-quietbacktrace'</span><br />
gem <span class="st0">'mislav-will_paginate'</span>, <span class="re3">:version</span> =&gt; <span class="st0">'~&gt; 2.2.3'</span>, <span class="re3">:lib</span> =&gt; <span class="st0">'will_paginate'</span>, <span class="re3">:source</span> =&gt; <span class="st0">'http://gems.github.com'</span><br />
<br />
rake <span class="st0">'gems:install'</span><br />
rake <span class="st0">'gems:unpack'</span><br />
<br />
<span class="co1">#install plugins</span><br />
plugin <span class="st0">'hoptoad_notifier'</span>, <span class="re3">:git</span> =&gt; <span class="st0">'git://github.com/thoughtbot/hoptoad_notifier.git'</span><br />
<br />
<span class="co1">#Delete all unecessary files</span><br />
run <span class="st0">&quot;rm README&quot;</span><br />
run <span class="st0">&quot;rm public/index.html&quot;</span><br />
run <span class="st0">&quot;rm public/favicon.ico&quot;</span><br />
run <span class="st0">&quot;rm public/robots.txt&quot;</span><br />
<br />
<span class="co1">#Setup git ignore file</span><br />
file <span class="st0">'.gitignore'</span>, &lt;&lt;-<span class="kw1">END</span><br />
config/database.<span class="me1">yml</span><br />
db/schema.<span class="me1">rb</span><br />
log/*.<span class="me1">log</span><br />
public/stylesheets/*.<span class="me1">css</span><br />
*.<span class="me1">swo</span><br />
*.<span class="me1">swp</span><br />
tmp/<br />
<span class="kw1">END</span><br />
run <span class="st0">'touch tmp/.gitignore log/.gitignore'</span><br />
<br />
<span class="co1">#add to git</span><br />
git <span class="re3">:init</span><br />
git <span class="re3">:add</span> =&gt; <span class="st0">'.'</span><br />
git <span class="re3">:commit</span> =&gt; <span class="st0">&quot;-a -m 'Initial commit'&quot;</span></div></div>
<h2>Writing files</h2>
<p>I like to use HAML which uses a less than conventional way of generating the plugin. First, the gem needs to be installed via
<pre>gem install haml</pre>
<p> and then the plugin is installed via
<pre>haml --rails <rails_dir></pre>
<p>The plugin file is verry simple so we can include it directly in our script.</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">gem <span class="st0">'haml'</span><br />
<br />
file <span class="st0">'vendor/plugins/haml/init.rb'</span>, &lt;&lt;-<span class="kw1">END</span><br />
<span class="kw3">require</span> <span class="st0">'rubygems'</span><br />
<span class="kw1">begin</span><br />
<span class="kw3">require</span> <span class="kw4">File</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="kw4">File</span>.<span class="me1">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span>, <span class="st0">'lib'</span>, <span class="st0">'haml'</span><span class="br0">&#41;</span> <span class="co1"># From here</span><br />
<span class="kw1">rescue</span> <span class="kw4">LoadError</span><br />
<span class="kw3">require</span> <span class="st0">'haml'</span> <span class="co1"># From gem</span><br />
<span class="kw1">end</span><br />
<br />
<span class="co1"># Load Haml and Sass</span><br />
Haml.<span class="me1">init_rails</span><span class="br0">&#40;</span><span class="kw3">binding</span><span class="br0">&#41;</span><br />
<span class="kw1">END</span></div></div>
<h2>Modifying existing files</h2>
<p>Rails generates some existing files which you might want to modify using your template such as un-commenting a line or inserting a line. I&#8217;ll demonstrate both by making adjustments to the application controller.</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">gsub_file <span class="st0">'app/controllers/application_controller.rb'</span>, /<span class="br0">&#40;</span><span class="kw1">class</span> ApplicationController.<span class="me1">*</span><span class="br0">&#41;</span>/, <span class="st0">&quot;<span class="es0">\\</span>1<span class="es0">\n</span>  include HoptoadNotifier&quot;</span><br />
gsub_file <span class="st0">'app/controllers/application_controller.rb'</span>, /<span class="co1">#\s*(filter_parameter_logging :password)/, '\1'</span></div></div>
<p>In the above lines, I am adding the Hoptoad notifier include line and un-commenting the
<pre>filter_parameter_logging</pre>
<p> line.</p>
<h2>Asking questions</h2>
<p>For a totally custom template, you can ask questions and use the results in your template output.</p>
<p>If you&#8217;re installing the HoptoadNotifier plugin, the initialization script requires the API code, we can retrieve that as follows:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">hoptoad_api_key = ask<span class="br0">&#40;</span><span class="st0">'What is your Hoptoad API key?'</span><span class="br0">&#41;</span><br />
<br />
initializer <span class="st0">'hoptoad.rb'</span>, &lt;&lt;-<span class="kw1">END</span><br />
HoptoadNotifier.<span class="me1">configure</span> <span class="kw1">do</span> |config|<br />
config.<span class="me1">api_key</span> = <span class="st0">'#{hoptoad_api_key}'</span><br />
<span class="kw1">end</span><br />
<span class="kw1">END</span></div></div>
<h2>The complete template</h2>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="co1">#Install gems</span><br />
gem <span class="st0">'mocha'</span><br />
gem <span class="st0">'thoughtbot-shoulda'</span><br />
gem <span class="st0">'thoughtbot-factory_girl'</span><br />
gem <span class="st0">'thoughtbot-quietbacktrace'</span><br />
gem <span class="st0">'mislav-will_paginate'</span>, <span class="re3">:version</span> =&gt; <span class="st0">'~&gt; 2.2.3'</span>, <span class="re3">:lib</span> =&gt; <span class="st0">'will_paginate'</span>, <span class="re3">:source</span> =&gt; <span class="st0">'http://gems.github.com'</span><br />
gem <span class="st0">'haml'</span><br />
<br />
rake <span class="st0">'gems:install'</span><br />
rake <span class="st0">'gems:unpack'</span><br />
<br />
<span class="co1">#install plugins</span><br />
plugin <span class="st0">'hoptoad_notifier'</span>, <span class="re3">:git</span> =&gt; <span class="st0">'git://github.com/thoughtbot/hoptoad_notifier.git'</span><br />
file <span class="st0">'vendor/plugins/haml/init.rb'</span>, &lt;&lt;-<span class="kw1">END</span><br />
<span class="kw3">require</span> <span class="st0">'rubygems'</span><br />
<span class="kw1">begin</span><br />
<span class="kw3">require</span> <span class="kw4">File</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="kw4">File</span>.<span class="me1">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span>, <span class="st0">'lib'</span>, <span class="st0">'haml'</span><span class="br0">&#41;</span> <span class="co1"># From here</span><br />
<span class="kw1">rescue</span> <span class="kw4">LoadError</span><br />
<span class="kw3">require</span> <span class="st0">'haml'</span> <span class="co1"># From gem</span><br />
<span class="kw1">end</span><br />
<br />
<span class="co1"># Load Haml and Sass</span><br />
Haml.<span class="me1">init_rails</span><span class="br0">&#40;</span><span class="kw3">binding</span><span class="br0">&#41;</span><br />
<span class="kw1">END</span><br />
<br />
<span class="co1">#Configure Application Controller</span><br />
gsub_file <span class="st0">'app/controllers/application_controller.rb'</span>, /<span class="br0">&#40;</span><span class="kw1">class</span> ApplicationController.<span class="me1">*</span><span class="br0">&#41;</span>/, <span class="st0">&quot;<span class="es0">\\</span>1<span class="es0">\n</span>&nbsp; include HoptoadNotifier&quot;</span><br />
gsub_file <span class="st0">'app/controllers/application_controller.rb'</span>, /<span class="co1">#\s*(filter_parameter_logging :password)/, '\1'</span><br />
<br />
<span class="co1">#Setup Hoptoad</span><br />
hoptoad_api_key = ask<span class="br0">&#40;</span><span class="st0">'What is your Hoptoad API key?'</span><span class="br0">&#41;</span><br />
<br />
initializer <span class="st0">'hoptoad.rb'</span>, &lt;&lt;-<span class="kw1">END</span><br />
HoptoadNotifier.<span class="me1">configure</span> <span class="kw1">do</span> |config|<br />
config.<span class="me1">api_key</span> = <span class="st0">'#{hoptoad_api_key}'</span><br />
<span class="kw1">end</span><br />
<span class="kw1">END</span><br />
<br />
<span class="co1">#Delete all unecessary files</span><br />
run <span class="st0">&quot;rm README&quot;</span><br />
run <span class="st0">&quot;rm public/index.html&quot;</span><br />
run <span class="st0">&quot;rm public/favicon.ico&quot;</span><br />
run <span class="st0">&quot;rm public/robots.txt&quot;</span><br />
<br />
<span class="co1">#Setup git ignore file</span><br />
file <span class="st0">'.gitignore'</span>, &lt;&lt;-<span class="kw1">END</span><br />
config/database.<span class="me1">yml</span><br />
db/schema.<span class="me1">rb</span><br />
log/*.<span class="me1">log</span><br />
public/stylesheets/*.<span class="me1">css</span><br />
*.<span class="me1">swo</span><br />
*.<span class="me1">swp</span><br />
tmp/<br />
<span class="kw1">END</span><br />
run <span class="st0">'touch tmp/.gitignore log/.gitignore'</span><br />
<br />
<span class="co1">#add to git</span><br />
git <span class="re3">:init</span><br />
git <span class="re3">:add</span> =&gt; <span class="st0">'.'</span><br />
git <span class="re3">:commit</span> =&gt; <span class="st0">&quot;-a -m 'Initial commit'&quot;</span></div></div>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=5OjvWrse"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=KibESpwe"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=KibESpwe" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/how-to-use-the-new-templates-in-rails/feed</wfw:commentRss>
		</item>
		<item>
		<title>How to update the Rails scaffold generator to suit your own applications</title>
		<link>http://ramblingsonrails.com/how-to-update-the-rails-scaffold-generator-to-suit-your-own-applications</link>
		<comments>http://ramblingsonrails.com/how-to-update-the-rails-scaffold-generator-to-suit-your-own-applications#comments</comments>
		<pubDate>Sat, 27 Dec 2008 13:15:26 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[customise]]></category>

		<category><![CDATA[customize]]></category>

		<category><![CDATA[generator]]></category>

		<category><![CDATA[scaffold]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=7</guid>
		<description><![CDATA[Learn about how to extend the built-in Rails scaffold generator to modify it to suite your personal coding style.]]></description>
			<content:encoded><![CDATA[<p>Rails contains generators that often make your programming a lot easier. One of these is the scaffold generator which creates a base of code that allows you to work with your models immediately.</p>
<p>The code that the scaffold generator creates is quite basic and as such I found that very early on I stopped using it alltogether - in fact I don&#8217;t think I&#8217;ve ever used scaffold code in any project I&#8217;ve done.<br />
Now a large number of projects later, I realise that I&#8217;ve been scaffolding my own code by hand for every controller in every action - not very DRY or efficient.</p>
<p>Today I decided to roll my sleeves up and put the effort into creating my own scaffold generator. It&#8217;s really not difficult and will speed up a lot of my development in the future.</p>
<h2>The objectives</h2>
<ul>
<li>The generated views should use <a href="http://haml.hamptoncatlin.com/">HAML</a></li>
<li>The generated tests should use <a href="http://www.thoughtbot.com/projects/shoulda/">Shoulda</a></li>
<li>The new and edit view should use the same form partial</li>
<li>No layout or css should be generated (I tend to use the main application layout except for special circumstances)</li>
</ul>
<h2>The process</h2>
<p>Rails will look for user generators in the ~/.rails/generators/ directory and it will use any generators there before the built-in generators so this is where we will build our custom scaffold generator.  First copy the original generator from (if you have the Rails source code) RAILS_SOURCE/railties/lib/rails_generator/generators/components/scaffold/ or (if you have Rails installed as a gem) GEM_SOURCE/rails-x.y.z/lib/rails_generator/generators/components/scaffold  In my case it was:</p>
<div class="codecolorer-container bash"><div class="codecolorer" style="font-family: monospace;">mkdir -p ~/.rails/generators<br />
cp -r ~/dev/rails/railties/lib/rails_generators/generators/components/scaffold ~/.rails/generators/</div></div>
<p>There are three parts to a generator:</p>
<ul>
<li>The USAGE file - this contains information on how the generator works</li>
<li>The &lt;generator_name&gt;_generator.rb file - this is the actual generator code (in our case it&#8217;s named scaffold_generator.rb)</li>
<li>The templates directory - this contains template files that can be used during generation</li>
</ul>
<p>To use HAML instead of Erb, I editted the template generation at line 56 from &#8220;#{action}.html.erb&#8221; to &#8220;#{action}.html.haml&#8221; so now all views are saved with the .haml extension but the views still need to be changed to HAML code.</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">for</span> action <span class="kw1">in</span> scaffold_views<br />
m.<span class="me1">template</span><span class="br0">&#40;</span><br />
<span class="st0">&quot;view_#{action}.html.erb&quot;</span>,<br />
<span class="kw4">File</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">'app/views'</span>, controller_class_path, controller_file_name, <span class="st0">&quot;#{action}.html.haml&quot;</span><span class="br0">&#41;</span><br />
<span class="br0">&#41;</span><br />
<span class="kw1">end</span></div></div>
<p>While I may be changing the view to HAML code, the template must still be in Erb as the template system will run Erb on the template to allow us to insert code such as class names etc.  Here is an example view template after I&#8217;ve made changes:</p>
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;">-title <span class="st0">&quot;&lt;%= plural_name %&gt;&quot;</span><br />
.<span class="me1">actions</span><br />
&nbsp; =link_to <span class="st0">'New &lt;%= singular_name %&gt;'</span>, new_&lt;%= singular_name %&gt;_path<br />
%table<span class="br0">&#123;</span>:cellspacing =&gt; <span class="nu0">0</span><span class="br0">&#125;</span><br />
&nbsp; %thead<br />
&nbsp; &nbsp; %tr<br />
&lt;% <span class="kw1">for</span> attribute <span class="kw1">in</span> attributes -%&gt;<br />
&nbsp; &nbsp; &nbsp; %th &lt;%= attribute.<span class="me1">column</span>.<span class="me1">human_name</span> %&gt;<br />
&lt;% <span class="kw1">end</span> -%&gt;<br />
&nbsp; %tbody<br />
&nbsp; &nbsp; -@&lt;%= plural_name %&gt;.<span class="me1">each</span> <span class="kw1">do</span> |&lt;%= singular_name %&gt;|<br />
&nbsp; &nbsp; &nbsp; %tr<span class="br0">&#123;</span>:<span class="kw1">class</span> =&gt; cycle<span class="br0">&#40;</span><span class="re3">:odd</span>, <span class="re3">:even</span><span class="br0">&#41;</span><span class="br0">&#125;</span><br />
&lt;% <span class="kw1">for</span> attribute <span class="kw1">in</span> attributes -%&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; %td= &lt;%= singular_name %&gt;.&lt;%= attribute.<span class="me1">name</span> %&gt;<br />
&lt;% <span class="kw1">end</span> -%&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; %td= link_to <span class="st0">'view'</span>, &lt;%= singular_name %&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; %td= link_to <span class="st0">'edit'</span>, edit_&lt;%= singular_name %&gt;_path<span class="br0">&#40;</span>&lt;%= singular_name %&gt;<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; %td= link_to <span class="st0">'delete'</span>, &lt;%= singular_name %&gt;, <span class="re3">:confirm</span> =&gt; <span class="st0">'Are you sure you want to delete this &lt;%= singular_name %&gt;?'</span>, <span class="re3">:method</span> =&gt; <span class="re3">:delete</span></div></div>
<p>If you are modifying scaffold views and want to continue to use Erb, you will need to escape all Erb code that should remain in the template with &lt;%% (This is done in the original view templates)  The rest of the modification are pretty simple modifications of the scaffold_generator.rb code and the templates. </p>
<p>I have put my code on GitHub and you can see a diff of my changes at http://github.com/andrewtimberlake/scripts/commit/095b8615dcff5d37ef94edcc9affed5396fe9731  Some of my modifications depend on the following:</p>
<ul>
<li>Shoulda plugin being installed</li>
<li>HAML plugin being installed</li>
<li>An application helper method being present called title which allows me to set the page title in a view:
<div class="codecolorer-container ruby"><div class="codecolorer" style="font-family: monospace;"><span class="kw1">def</span> title<span class="br0">&#40;</span>title_text<span class="br0">&#41;</span><br />
<span class="re1">@title</span> = title_text<br />
<span class="kw1">end</span></div></div>
</li>
</ul>
<p>To make this really useful, I&#8217;m going to be working on a Rails template which is coming in Rails 2.3. I&#8217;ll write about generating a template in a future post.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=aztORTqd"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=bTJ92USr"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=bTJ92USr" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/how-to-update-the-rails-scaffold-generator-to-suit-your-own-applications/feed</wfw:commentRss>
		</item>
		<item>
		<title>Hello world!</title>
		<link>http://ramblingsonrails.com/hello-world</link>
		<comments>http://ramblingsonrails.com/hello-world#comments</comments>
		<pubDate>Fri, 26 Dec 2008 08:39:29 +0000</pubDate>
		<dc:creator>Andrew Timberlake</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://andrewtimberlake.com/?p=1</guid>
		<description><![CDATA[Every good programmer needs to start with Hello World so this is it, making sure all works and then I can start with some real content.
]]></description>
			<content:encoded><![CDATA[<p>Every good programmer needs to start with Hello World so this is it, making sure all works and then I can start with some real content.</p>
<div class="feedflare">
<a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=8LUGsDtH"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?d=41" border="0"></img></a> <a href="http://feeds.ramblingsonrails.com/~f/RamblingsOnRails?a=PjWmXXf3"><img src="http://feeds.feedburner.com/~f/RamblingsOnRails?i=PjWmXXf3" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://ramblingsonrails.com/hello-world/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
