<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Codebeef</title>
 
 <link href="http://codebeef.com/" />
 <updated>2012-02-13T13:57:28+00:00</updated>
 <id>http://codebeef.com/</id>
 <author>
   <name>Codebeef</name>
   <email>matt@codebeef.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/codebeef" /><feedburner:info uri="codebeef" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Creating a New Post in Jekyll with Rake</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/ZCiTn0-KJho/creating-a-new-post-in-jekyll-with-rake.html" />
   <updated>2012-02-11T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/creating-a-new-post-in-jekyll-with-rake</id>
   <content type="html">&lt;p&gt;Just a quick and dirty rake task that lets you run this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;rake np -- The Post Title
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;#8230;to set up a new post in Jekyll and open it in &lt;a href='http://www.sublimetext.com/2'&gt;Sublime Text 2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you prefer another editor, then swap the &lt;code&gt;subl&lt;/code&gt; command for the appropriate CLI command for your editor.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;optparse&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;yaml&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;task&lt;/span&gt; &lt;span class='ss'&gt;:np&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='no'&gt;OptionParser&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;parse!&lt;/span&gt;
  &lt;span class='no'&gt;ARGV&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;shift&lt;/span&gt;
  &lt;span class='n'&gt;title&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;ARGV&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

  &lt;span class='n'&gt;path&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;_posts/&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='no'&gt;Date&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;today&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;-&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;title&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;downcase&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gsub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/[^[:alnum:]]+/&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;.markdown&amp;quot;&lt;/span&gt;
  
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;exist?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;path&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  	&lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;[WARN] File exists - skipping create&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;else&lt;/span&gt;
    &lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;open&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;path&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;puts&lt;/span&gt; &lt;span class='no'&gt;YAML&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dump&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;layout&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;post&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;published&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;title&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;title&lt;/span&gt;&lt;span class='p'&gt;})&lt;/span&gt;
      &lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;---&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='sb'&gt;`subl &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;path&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;

  &lt;span class='nb'&gt;exit&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Also &lt;a href='https://gist.github.com/1801090'&gt;available here&lt;/a&gt; as a gist.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/ZCiTn0-KJho" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/creating-a-new-post-in-jekyll-with-rake.html</feedburner:origLink></entry>
 
 <entry>
   <title>Industrial Revolutions</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/xsYr-q7d2HM/danny-macaskill-industrial-revolutions.html" />
   <updated>2011-08-16T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/danny-macaskill-industrial-revolutions</id>
   <content type="html">&lt;iframe width="549" height="342" src="http://www.youtube.com/embed/ShbC5yVqOdI" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/xsYr-q7d2HM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/danny-macaskill-industrial-revolutions.html</feedburner:origLink></entry>
 
 <entry>
   <title>IE and PDF downloads over HTTPS in Rails</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/85tf9PMreoc/ie-and-pdf-downloads-over-https-in-rails.html" />
   <updated>2011-04-22T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/ie-and-pdf-downloads-over-https-in-rails</id>
   <content type="html">&lt;p&gt;So you have a controller that renders PDF&amp;#8217;s, and all looks great. You decide to move from HTTP to HTTPS, and everything checks out. You deploy, and suddenly some of your users can&amp;#8217;t see the PDF downloads anymore. These users are all running some version of IE - all the way from IE6 up to IE8.&lt;/p&gt;

&lt;p&gt;The solution is to set your response headers as follows:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;show&lt;/span&gt;
    &lt;span class='n'&gt;inst&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Model&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
	
    &lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Content-Transfer-Encoding&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;binary&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Content-Disposition&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;attachment;filename=&lt;/span&gt;&lt;span class='se'&gt;\&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;inst&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;.pdf&lt;/span&gt;&lt;span class='se'&gt;\&amp;quot;&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Content-Description&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;File Transfer&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Expires&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;0&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Pragma&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;public&amp;#39;&lt;/span&gt;
	
    &lt;span class='n'&gt;render&lt;/span&gt; &lt;span class='c1'&gt;# Render your pdf&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/85tf9PMreoc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/ie-and-pdf-downloads-over-https-in-rails.html</feedburner:origLink></entry>
 
 <entry>
   <title>Diary (2010) by Tim Hetherington</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/MEMrBpFjwi0/diary-%282010%29-by-tim-hetherington.html" />
   <updated>2011-04-21T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/diary-(2010)-by-tim-hetherington</id>
   <content type="html">&lt;iframe src='http://player.vimeo.com/video/18497543?byline=0&amp;amp;portrait=0' frameborder='0' height='309' width='549' /&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/MEMrBpFjwi0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/diary-%282010%29-by-tim-hetherington.html</feedburner:origLink></entry>
 
 <entry>
   <title>Truncating HTML while Preserving Structure</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/gQZtkUhlXzM/truncating-html-while-preserving-structure.html" />
   <updated>2011-04-15T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/truncating-html-while-preserving-structure</id>
   <content type="html">&lt;p&gt;Truncating HTML is a bit of a pain - in a recent effory to change the layout of my site, I updated the index page to show the last five posts - truncated, of course.&lt;/p&gt;

&lt;p&gt;The problem with doing this is that the most common method of truncating a post is to remove all markup and truncate the remaining string. This would be fine, but for a site with a fair amount of colorized code examples (courtesy of &lt;a href='http://pygments.org/'&gt;Pigments&lt;/a&gt;), it can look a little weird.&lt;/p&gt;

&lt;p&gt;A better solution would be to truncate based on the number of characters, yet retain the markup, which is where &lt;a href='https://github.com/MattHall/truncatehtml'&gt;this cheeky snippet&lt;/a&gt; of code comes in.&lt;/p&gt;

&lt;h2 id='requirements'&gt;Requirements&lt;/h2&gt;

&lt;p&gt;The truncator requires &lt;a href='http://nokogiri.org/'&gt;Nokogiri&lt;/a&gt; to parse out the HTML string.&lt;/p&gt;

&lt;h2 id='usage'&gt;Usage&lt;/h2&gt;

&lt;p&gt;If you&amp;#8217;re using Jekyll, add the html_filters.rb file to your _plugins directory - this will give you the helper &lt;code&gt;truncatehtml&lt;/code&gt; as a &lt;a href='http://liquidmarkup.org'&gt;Liquid&lt;/a&gt; filter. In your views, you can use this function in the same way as you would use the normal &lt;code&gt;truncate&lt;/code&gt; filter:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;page&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;content&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;truncatehtml&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='mi'&gt;500&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='how_it_works'&gt;How it works&lt;/h2&gt;

&lt;p&gt;Given a snippet of HTML, we use Nokogiri to parse it into a tree. This takes care of all of the messiness of dealing with HTML, and gives us back a tree of nodes representing the parsed snippet.&lt;/p&gt;

&lt;p&gt;Now that we have the tree of nodes, we can traverse it depth-first. All text nodes are leaf nodes, so when we encounter one, we can count the length of the text.&lt;/p&gt;

&lt;p&gt;Once we have all of the text we need, we continue traversing, but instead of counting text lengths, we delete all of the nodes we see after we&amp;#8217;ve reached our maximum length.&lt;/p&gt;

&lt;p&gt;After that, we have a tree of nodes that represent the truncated tree, and the can output the appropriate HTML.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/gQZtkUhlXzM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/truncating-html-while-preserving-structure.html</feedburner:origLink></entry>
 
 <entry>
   <title>The Beta - Branch Bacardi</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/XDCDHu72z6Q/branch-bacardi.html" />
   <updated>2011-03-30T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/branch-bacardi</id>
   <content type="html">&lt;iframe src="http://player.vimeo.com/video/16035165?byline=0&amp;amp;portrait=0" width="549" height="309" frameborder="0"&gt;&lt;/iframe&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/XDCDHu72z6Q" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/branch-bacardi.html</feedburner:origLink></entry>
 
 <entry>
   <title>Getting Work as a Freelancer</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/sbE1Y6BQQuA/getting-work-as-a-freelancer.html" />
   <updated>2011-03-21T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/getting-work-as-a-freelancer</id>
   <content type="html">&lt;p&gt;I recently quit my day job in order to pursue a career as a freelance Rails developer. I went from having a steady income each month to potentially having no money coming in at all.&lt;/p&gt;

&lt;p&gt;This is how I managed to get clients and not die in a ditch during my first few months:&lt;/p&gt;

&lt;h3 id='the_big_change'&gt;The Big Change&lt;/h3&gt;

&lt;p&gt;Moving from having a full-time job to a freelancer is hard, but like most difficult tasks, it is ultimately worthwhile.&lt;/p&gt;

&lt;p&gt;I decided to take the plunge into freelancing after putting it off for around 12 months - I pretty much committed to it in as short a time period as possible, thereby preempting any possible weaselling out on the part of my reasonable side.&lt;/p&gt;

&lt;p&gt;The actual quitting of my job was fairly easy - write a letter, have a meeting then work my month&amp;#8217;s notice. Simple.&lt;/p&gt;

&lt;p&gt;Then what?&lt;/p&gt;

&lt;h3 id='finding_work'&gt;Finding Work&lt;/h3&gt;

&lt;p&gt;By far the most troubling part of becoming a freelancer (for me, at least) was not knowing where my customers were going to come from. If I can&amp;#8217;t see where my next job is, it obviously makes me nervous - how can I pay the bills and mortgage unless I know I have the money coming in?&lt;/p&gt;

&lt;p&gt;This is where things got interesting: I put the call out, and almost immediately got too much work to reasonable book in. My previous employer also immediately booked me for a four week contract that would start the day after I finished my notice.&lt;/p&gt;

&lt;p&gt;This may not be representative of your own experience, however, it does go to show that work can pretty much come from anywhere. These are a few places that I&amp;#8217;ve been able to get jobs so far:&lt;/p&gt;

&lt;h4 id='other_freelancers'&gt;Other Freelancers&lt;/h4&gt;

&lt;p&gt;Having a network of friends in the same field as yourself (in my case web developemnt) gives you a competitive advantage: If you can&amp;#8217;t allocate the time for a project, you can pass it to a friend, creating goodwill on the part of the client you&amp;#8217;ve passed on and potentially gaining a reciprocal referral.&lt;/p&gt;

&lt;p&gt;Having a network of people - with skills that are complementary to your own - will allow you to provide recommendations if it turns out the client needs additional services like graphic design or copywriting.&lt;/p&gt;

&lt;p&gt;It is important to not see other freelancers as &amp;#8216;the enemy&amp;#8217;, and instead to actively seek out new contacts in your field.&lt;/p&gt;

&lt;h4 id='existing_clients'&gt;Existing Clients&lt;/h4&gt;

&lt;p&gt;Once you&amp;#8217;ve completed a project for a client, and the job went well, you should occasionally give them a nudge to see if they have anything else they want looking at. Discounts for repeat custom can help grease the wheels, and you may end up taking on a retainer if it turns out they do need regular work.&lt;/p&gt;

&lt;h4 id='word_of_mouth'&gt;Word of Mouth&lt;/h4&gt;

&lt;p&gt;Happy clients will recommend you. It is sometimes worth going slightly above and beyond in order to delight your customers, though how far you take this needs to be balanced.&lt;/p&gt;

&lt;p&gt;If you do go above and beyond their expectations, this will probably set their baseline expectations higher for future work. Be aware of this if you later need to quote for work with a tight deadline.&lt;/p&gt;

&lt;h4 id='advertising'&gt;Advertising&lt;/h4&gt;

&lt;p&gt;It seems that the first place people check for Freelancers is often Google, and as it happens, Google AdWords makes it really easy to get a campaign set up to start bringing in interested people.&lt;/p&gt;

&lt;p&gt;These types of leads greatly vary in quality, from enquiries along the lines of &amp;#8220;Build me a Facebook clone for $500&amp;#8221; to the more reasonable &amp;#8220;I have a spec, can you help me build it?&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Keep in mind that getting an enquiry from this avenue may need a little more massaging before it becomes a fully booked-in job, and like all enquiries, they are bordering on meaningless until the first invoice is paid and the job has begun.&lt;/p&gt;

&lt;h4 id='events'&gt;Events&lt;/h4&gt;

&lt;p&gt;If you&amp;#8217;re near a major city, there should be a fair few events on that you can get to. In Manchester, there is the local &lt;a href='http://geekup.org/'&gt;Geekup&lt;/a&gt; along with the &lt;a href='http://nwrug.org/'&gt;NWRUG&lt;/a&gt; and now &lt;a href='http://twitter.com/freelancenorth'&gt;Freelance North&lt;/a&gt;. Such events are great for getting to know fellow freelancers and developers in a more social setting than IRC.&lt;/p&gt;

&lt;h4 id='twitter'&gt;Twitter&lt;/h4&gt;

&lt;p&gt;Announcing on Twitter when you go freelance or when you&amp;#8217;ve got &lt;a href='https://twitter.com/codebeef/status/38600560634499072'&gt;a bit of slack time&lt;/a&gt; coming up is a very good way of making people aware you&amp;#8217;re available. Equally, trawling for people looking for freelancers is an excellent way of getting new leads.&lt;/p&gt;

&lt;p&gt;When you announce you&amp;#8217;re going freelance, try and get other developers (freelance or not) to retweet your announcement. You should notice you get a few new followers - agencies and other freelancers especially.&lt;/p&gt;

&lt;h3 id='conclusion'&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;It&amp;#8217;s not hard to find the work once you start making connections - the point is that you need to embrace the social aspect of freelancing to carve out a position. Don&amp;#8217;t hang on to work you don&amp;#8217;t have time for - give it away and gain karma. Do good work, and don&amp;#8217;t forget about your existing contacts.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/sbE1Y6BQQuA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/getting-work-as-a-freelancer.html</feedburner:origLink></entry>
 
 <entry>
   <title>How I got into iOS Development</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/ik4Cd3YkyCE/how-i-got-into-ios-development.html" />
   <updated>2011-01-04T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/how-i-got-into-ios-development</id>
   <content type="html">&lt;p&gt;I recently got an email asking how best to get into iOS development - a request for links, tutorials, and so on. Now, I don&amp;#8217;t necessarily know how &lt;em&gt;best&lt;/em&gt; to get into developing for iOS, but I know I didn&amp;#8217;t have a predefined set of links to run through, or even much reading material outside of some upcoming books, which I didn&amp;#8217;t really bother with anyway.&lt;/p&gt;

&lt;h2 id='tl_dr'&gt;tl; dr:&lt;/h2&gt;

&lt;p&gt;The method I used to get into iOS dev was to build stuff. Constantly.&lt;/p&gt;

&lt;h2 id='more_detail'&gt;More Detail&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m not sure how much C you know, but when I started in Obj-C, I already had a good grasp of C and C++ and many concepts from these two languages map directly into Obj-C (Obj-C is a superset of C). I&amp;#8217;d definitely recommend getting a basic grasp of C before jumping into Obj-C. The only book you need on C is called &amp;#8221;&lt;a href='http://www.amazon.com/gp/product/0131103628?ie=UTF8&amp;amp;tag=codebeef-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0131103628'&gt;The C Programming Language&lt;/a&gt;&amp;#8221; by Brian Kernighan and Dennis Ritchie.&lt;/p&gt;

&lt;p&gt;There are lots of projects on Github that you can clone and comb through the source of. Try to pick one that has an active and well regarded community - so you don&amp;#8217;t begin studying crap unintentionally. As I was building sync stuff into my apps, I first looked through &lt;a href='https://github.com/yfactorial/objectivesync'&gt;ObjectiveSync&lt;/a&gt; and &lt;a href='https://github.com/yfactorial/objectiveresource'&gt;ObjectiveResource&lt;/a&gt; (from &lt;a href='https://github.com/yfactorial'&gt;Ryan Daigle&lt;/a&gt;), though dev seems to have slowed somewhat. &lt;a href='https://github.com/facebook/three20'&gt;Facebook&amp;#8217;s three20&lt;/a&gt; library is also worth a look, too. If you &lt;a href='https://github.com/languages/Objective-C'&gt;look on this page&lt;/a&gt;, you&amp;#8217;ll find lots of links to really good, interesting projects on Github right now.&lt;/p&gt;

&lt;p&gt;If you just want to dive right in to iOS development, then the path I took was:&lt;/p&gt;

&lt;h3 id='1_get_the_single_dev_plan'&gt;1. Get the single dev plan&lt;/h3&gt;

&lt;p&gt;If you want the enterprise plan, then do whatever you see fit. It&amp;#8217;s a detail that is of little consequence. The enterprise plan will give you more support requests and provisioning for more developers, but if you&amp;#8217;re working alone, then the single plan works just fine.&lt;/p&gt;

&lt;h3 id='2_think_of_a_nontrivial_app'&gt;2. Think of a non-trivial app&lt;/h3&gt;

&lt;p&gt;I chose to build an app for rock climbers - a universal guidebook, and includes things like synchronisation, mapping, image manipulation and location services. It needs to be ambitious enough for you to think you&amp;#8217;re not going to be able to do it.&lt;/p&gt;

&lt;h3 id='3_begin_building_version_1'&gt;3. Begin building version 1&lt;/h3&gt;

&lt;p&gt;This version will be awful, but you&amp;#8217;ll learn a lot.&lt;/p&gt;

&lt;p&gt;Strip your idea down to a minimum. The first version of Bouldr was read-only, and simply displayed a list of climbs nearby with a detail screen for each entry. It had no sync - it required a connection, no editing and only basic map integration. My code at this point was pretty ropey, but I learned how to put things together, and I could see where I was going wrong when I came back to add additional features.&lt;/p&gt;

&lt;p&gt;I didn&amp;#8217;t buy any books - the developer resources on Apples site are really good, so long as you actually use them. Additionally, StackOverflow is an amazing source of information - all of the problems you run into will already be covered somewhere on the web, and most likely, there will be a question and answer right there on StackOverflow. I&amp;#8217;ve not read any books, so I can&amp;#8217;t recommend any.&lt;/p&gt;

&lt;h3 id='4_release'&gt;4. Release&lt;/h3&gt;

&lt;p&gt;This is important - get your version 1 out. You&amp;#8217;ll gather some interest, and have some users you can later get to help you beta test. Note that being able to set up and manage a beta test is not trivial. Once your first version is out, you&amp;#8217;ll get feedback.&lt;/p&gt;

&lt;h3 id='5_begin_version_2'&gt;5. Begin version 2&lt;/h3&gt;

&lt;p&gt;Don&amp;#8217;t leave it at that - dive back into the code and begin adding features that you think are needed. Learn how to &lt;a href='http://codebeef.com/getting-the-data-with-mixpanel-and-ios'&gt;use Mixpanel&lt;/a&gt; to gather data on what people are actually using. &lt;a href='http://hoptoadapp.com/pages/ios-notifier'&gt;Integrate Hoptoad&lt;/a&gt; to get better error reporting. You&amp;#8217;ll probably begin to notice how bad the code is in your first version.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This next bit scared me, and took longer than anticipated, but it also taught me a massive amount, and let me improve my codebase:&lt;/em&gt;&lt;/p&gt;

&lt;h3 id='6_scrap_your_first_version_and_build_a_new_version_from_scratch'&gt;6. Scrap your first version, and build a new version from scratch&lt;/h3&gt;

&lt;p&gt;Re-implement all of the functionality, but concentrate on making your code maintainable - don&amp;#8217;t add new features. I started building out a test-suite at this point, too.&lt;/p&gt;

&lt;h3 id='7_beta_test_your_next_release'&gt;7. Beta test your next release&lt;/h3&gt;

&lt;p&gt;Get a beta group together. Gather their UDID&amp;#8217;s and send them a beta build. Gather feedback and bug reports, and fix your app up as you need to.&lt;/p&gt;

&lt;h3 id='8_release_version_2'&gt;8. Release version 2&lt;/h3&gt;

&lt;p&gt;It&amp;#8217;s important to make sure you&amp;#8217;ve covered migrating your data store if you&amp;#8217;re using Core Data, and you should test as much as you can to ensure that you&amp;#8217;ve not fundamentally broken your app. I&amp;#8217;ve submitted a version of the Bouldr app before that contained a crashing bug. Apple won&amp;#8217;t necessarily catch problems with your app unless they are obvious. If the upgrade process within your app is complex (migrations, moving data files around, etc&amp;#8230;), then it&amp;#8217;s vital you test, and test on actual devices.&lt;/p&gt;

&lt;p&gt;Keep building out your app and you&amp;#8217;ll keep learning. Start new apps, and try implementing individual features as standalone apps to get an understanding of how it works. I built a GPS tracker as a separate app along with a basic line drawing app and image resizing app. These were simple systems I put together just so I could isolate the functionality I was implementing, and build without needing it to fit into any existing design.&lt;/p&gt;

&lt;p&gt;Keep building, keep learning, get on StackOverflow and try &lt;em&gt;answering&lt;/em&gt; some questions, and you&amp;#8217;ll find you pick up the language and SDK with time and effort.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://www.assoc-amazon.com/e/ir?t=codebeef-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0131103628' alt='' /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/ik4Cd3YkyCE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/how-i-got-into-ios-development.html</feedburner:origLink></entry>
 
 <entry>
   <title>Getting the data with Mixpanel and iOS</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/-ObVgWAe9OI/getting-the-data-with-mixpanel-and-ios.html" />
   <updated>2010-12-30T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/getting-the-data-with-mixpanel-and-ios</id>
   <content type="html">&lt;p&gt;It&amp;#8217;s easy to get used to having detailed statistics when developing web apps, using split tests to determine the better optimisations and finding patterns in usage that lead to your most profitable customers and features. When developing iOS apps, these stats are much harder to collect.&lt;/p&gt;

&lt;p&gt;Thankfully, there is a service that helps aleviate this problem: &lt;a href='http://mixpanel.com/'&gt;Mixpanel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://mixpanel.com/projects/getting-started/11243/iphone'&gt;Integrating your app with the Mixpanel API&lt;/a&gt; is a simple case of grabbing their library, importing the MPLib filder and adding the include to your prefix header:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='objectivec'&gt;&lt;span class='cp'&gt;#import &amp;quot;MixpanelAPI.h&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;#8230; initialising the lib in your app delegate:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='objectivec'&gt;&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;BOOL&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='nl'&gt;application:&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;UIApplication&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='n'&gt;application&lt;/span&gt; &lt;span class='nl'&gt;didFinishLaunchingWithOptions:&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;NSDictionary&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='n'&gt;launchOptions&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='n'&gt;MixpanelAPI&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;mixpanel&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;MixpanelAPI&lt;/span&gt; &lt;span class='nl'&gt;sharedAPIWithToken:&lt;/span&gt;&lt;span class='s'&gt;@&amp;quot;Your Token&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
	
  &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;mixpanel&lt;/span&gt; &lt;span class='nl'&gt;registerSuperProperties:&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;NSDictionary&lt;/span&gt; &lt;span class='nl'&gt;dictionaryWithObjectsAndKeys:&lt;/span&gt;
      &lt;span class='p'&gt;[[&lt;/span&gt;&lt;span class='n'&gt;UIDevice&lt;/span&gt; &lt;span class='n'&gt;currentDevice&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='n'&gt;systemVersion&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='s'&gt;@&amp;quot;OS Version&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;[[&lt;/span&gt;&lt;span class='n'&gt;NSBundle&lt;/span&gt; &lt;span class='n'&gt;mainBundle&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='nl'&gt;objectForInfoDictionaryKey:&lt;/span&gt;&lt;span class='s'&gt;@&amp;quot;CFBundleVersion&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='s'&gt;@&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;nil&lt;/span&gt;
    &lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='p'&gt;];&lt;/span&gt;

  &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;mixpanel&lt;/span&gt; &lt;span class='nl'&gt;track:&lt;/span&gt;&lt;span class='s'&gt;@&amp;quot;App Launch&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;

  &lt;span class='c1'&gt;// Override point for customization after app launch    &lt;/span&gt;
  &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;window&lt;/span&gt; &lt;span class='nl'&gt;addSubview:&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;navigationController&lt;/span&gt; &lt;span class='n'&gt;view&lt;/span&gt;&lt;span class='p'&gt;]];&lt;/span&gt;
  &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;window&lt;/span&gt; &lt;span class='n'&gt;makeKeyAndVisible&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;

  &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;YES&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;#8230; and collecting metrics as you see fit:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='objectivec'&gt;&lt;span class='n'&gt;MixpanelAPI&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;mixpanel&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;MixpanelAPI&lt;/span&gt; &lt;span class='n'&gt;sharedAPI&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;mixpanel&lt;/span&gt; &lt;span class='nl'&gt;track:&lt;/span&gt;&lt;span class='s'&gt;@&amp;quot;Checkin&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Instead of synchronously sending data back to your Mixpanel, individual events are queued up and sent as a connection is available - good news if your app is going to be used when net connectivity may be poor.&lt;/p&gt;

&lt;p&gt;Additionally, you can send properties that allow you to segment your data further. In the above example, I send the OS version and app bundle version with every request. Collecting these additional details will let me determine whether a particular pattern can be attributed to either of these attributes.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/-ObVgWAe9OI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/getting-the-data-with-mixpanel-and-ios.html</feedburner:origLink></entry>
 
 <entry>
   <title>An Improved Interface for Migrating to Jekyll</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/6G8TBqWiSWU/migrating-to-jekyll.html" />
   <updated>2010-12-27T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/migrating-to-jekyll</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m a sucker for shiny new services, which means I&amp;#8217;ve swapped out blog hosts around half a dozen times. This is the third time I&amp;#8217;ve come back to &lt;a href='http://jekyllrb.com/'&gt;Jekyll&lt;/a&gt;, and the importing system hasn&amp;#8217;t really changed since I first migrated from self-hosted &lt;a href='http://wordpress.org/download/'&gt;Wordpress&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My latest migration is from &lt;a href='http://posterous.com'&gt;Posterous&lt;/a&gt; - a solid blogging system, but lacking in customisation, and with my recent move to self-hosting, I wanted to consolidate my stuff.&lt;/p&gt;

&lt;p&gt;There is no easy export option for Posterous - the only method of getting your data out is to use their &lt;a href='posterous.com/api'&gt;API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I set about writing &lt;a href='https://github.com/MattHall/jekyll/tree/posterous'&gt;an importer for Posterous&lt;/a&gt;, then noticed &lt;a href='https://github.com/mojombo/jekyll/issues#issue/20'&gt;this ticket&lt;/a&gt; asking for a better import CLI.&lt;/p&gt;

&lt;p&gt;After a little hacking around, I present: &lt;a href='https://github.com/MattHall/jekyll/commits/cli'&gt;A Blog import command set for Jekyll&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='usage'&gt;Usage&lt;/h3&gt;

&lt;p&gt;To import a blog from another service or export file:&lt;/p&gt;

&lt;h4 id='csv'&gt;CSV&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import csv --file&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;/path/to/csv.csv&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='typo'&gt;Typo&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import typo --dbname&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;database name&amp;gt; --user&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;username&amp;gt; --pass&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='textpattern'&gt;TextPattern&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import textpattern --dbname&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;database name&amp;gt; --user&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;username&amp;gt; --pass&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;password&amp;gt; --host&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;hostname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='mt'&gt;MT&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import mt --dbname&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;database name&amp;gt; --user&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;username&amp;gt; --pass&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='mephisto'&gt;Mephisto&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import mephisto --dbname&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;database name&amp;gt; --user&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;username&amp;gt; --pass&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='drupal'&gt;Drupal&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import drupal --dbname&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;database name&amp;gt; --user&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;username&amp;gt; --pass&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='wordpress'&gt;Wordpress&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import wordpress --dbname&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;database name&amp;gt; --user&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;username&amp;gt; --pass&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='wordpresscom'&gt;Wordpress.com&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import wordpressdotcom --file&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;/path/to/export.xml&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='posterous'&gt;Posterous&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;jekyll import posterous --user&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;email&amp;gt; --pass&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;password&amp;gt; --site&lt;span class='o'&gt;=&lt;/span&gt;&amp;lt;sitename &lt;span class='o'&gt;(&lt;/span&gt;default is primary site&lt;span class='o'&gt;)&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that the &lt;a href='https://github.com/MattHall/jekyll/tree/posterous'&gt;Posterous importer&lt;/a&gt; is required for this to work.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/6G8TBqWiSWU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/migrating-to-jekyll.html</feedburner:origLink></entry>
 
 <entry>
   <title>Automated Deploy with Unicorn and Git</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/silOQa7aFQE/automated-deploy-with-unicorn-and-git.html" />
   <updated>2010-12-14T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/automated-deploy-with-unicorn-and-git</id>
   <content type="html">&lt;p&gt;As part of my recent move to &lt;a href='http://codebeef.com/self-hosting-private-git/'&gt;self-hosting my private git repos&lt;/a&gt;, I have built a simple &lt;a href='http://www.sinatrarb.com/'&gt;Sinatra&lt;/a&gt; app that lets me view and browse them.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m using Unicorn behind Nginx to serve this little app up, and as I&amp;#8217;m self-hosting, I decided to give automatic deployment a try; Capistrano just felt like added overhead in this case.&lt;/p&gt;

&lt;p&gt;My ideal deploy path for this app is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make changes on master branch&lt;/li&gt;

&lt;li&gt;Rebase changes to production branch as required&lt;/li&gt;

&lt;li&gt;Push&lt;/li&gt;

&lt;li&gt;Post receive hook deploys app, and restarts unicorn&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After creating the repo on my server, I added the following script to myapp.git/hooks/post-receive, and ran &lt;code&gt;chmod ug+x post-receive&lt;/code&gt; to make the file executable.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;APP_ROOT&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;/path/to/app
&lt;span class='nv'&gt;UNICORN_PID&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='nv'&gt;$APP_ROOT&lt;/span&gt;/tmp/pids/unicorn.pid

&lt;span class='c'&gt;# Deploy the updated code&lt;/span&gt;
mkdir -p &lt;span class='nv'&gt;$APP_ROOT&lt;/span&gt;

&lt;span class='c'&gt;# Only want to export from the production branch&lt;/span&gt;
git archive production | tar -x -C &lt;span class='nv'&gt;$APP_ROOT&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; -f &lt;span class='nv'&gt;$UNICORN_PID&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;
  &lt;span class='k'&gt;then&lt;/span&gt;
&lt;span class='k'&gt;    &lt;/span&gt;&lt;span class='nb'&gt;kill&lt;/span&gt; -USR2 &lt;span class='sb'&gt;`&lt;/span&gt;cat &lt;span class='nv'&gt;$UNICORN_PID&lt;/span&gt;&lt;span class='sb'&gt;`&lt;/span&gt;
  &lt;span class='k'&gt;else&lt;/span&gt;
&lt;span class='k'&gt;    &lt;/span&gt;unicorn -c &lt;span class='nv'&gt;$APP_ROOT&lt;/span&gt;/unicorn.rb -D -E production
&lt;span class='k'&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that there are assumptions as to the location of the app and it&amp;#8217;s structure. You&amp;#8217;ll need a tmp folder in the app root which contains the pid folder. I&amp;#8217;ve not included the unicorn config, as it not really related to this post.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/silOQa7aFQE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/automated-deploy-with-unicorn-and-git.html</feedburner:origLink></entry>
 
 <entry>
   <title>Self Hosted Private Git</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/vdKCsAZ350Y/self-hosting-private-git.html" />
   <updated>2010-12-12T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/self-hosting-private-git</id>
   <content type="html">&lt;p&gt;I switched back to &lt;a href='https://github.com/mojombo/jekyll'&gt;Jekyll&lt;/a&gt; from &lt;a href='http://posterous.com'&gt;Posterous&lt;/a&gt; as I prefer having control over my data. Posterous&amp;#8217; auto formatting never really worked out well for me, and I like having the opportunity to customise pages as I see fit rather than having to conform to one particular format.&lt;/p&gt;

&lt;p&gt;Anyhow, I&amp;#8217;ve ended up with a share on &lt;a href='http://gandi.net'&gt;Gandi&lt;/a&gt; and decided to take the opportunity to cut my repo hosting bills by self-hosting. At the time of writing, I&amp;#8217;ve got a maxed out medium plan, which has become more of a problem as time has gone on - the next larger plan is by request, and will obviously cost more than the $22 I&amp;#8217;m paying per month at the moment.&lt;/p&gt;

&lt;p&gt;Looking around, the only self-hosting system I could find that had decent documentation was Gitolite.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/sitaramc/gitolite'&gt;Gitolite&lt;/a&gt; integrates with ssh, meaning there are no daemons running, so there is nothing to monitor or worry about. The &lt;a href='https://github.com/sitaramc/gitolite/tree/pu/doc'&gt;installation instructions&lt;/a&gt; are thorough and correct, and I was able to get a running installation in under an hour. Additionally, it has permissions that run down to branch granularity, and it can be managed through git. Perfect.&lt;/p&gt;

&lt;p&gt;To migrate my repos from Github to Gitolite, I firstly created the repos by updating my gitolite-admin repo (as per the instructions) and pushing those changes. Once I had the new remotes ready to go, I used the following script to automatically migrate:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;#! /bin/bash&lt;/span&gt;

&lt;span class='nv'&gt;repos&lt;/span&gt;&lt;span class='o'&gt;=(&lt;/span&gt; repo1 repo2 repo3 &lt;span class='o'&gt;)&lt;/span&gt;

&lt;span class='k'&gt;for &lt;/span&gt;repo in &lt;span class='k'&gt;${&lt;/span&gt;&lt;span class='nv'&gt;repos&lt;/span&gt;&lt;span class='p'&gt;[@]&lt;/span&gt;&lt;span class='k'&gt;}&lt;/span&gt;
&lt;span class='k'&gt;do&lt;/span&gt;
&lt;span class='nb'&gt;echo&lt;/span&gt; &lt;span class='nv'&gt;$repo&lt;/span&gt;
git clone --bare git@github.com:MattHall/&lt;span class='nv'&gt;$repo&lt;/span&gt;
&lt;span class='nb'&gt;cd&lt;/span&gt; &lt;span class='nv'&gt;$repo&lt;/span&gt;.git
git push --mirror git@your-server.com:&lt;span class='nv'&gt;$repo&lt;/span&gt;.git
&lt;span class='nb'&gt;cd&lt;/span&gt; ..
rm -fr &lt;span class='nv'&gt;$repo&lt;/span&gt;.git
&lt;span class='k'&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&amp;#8216;repos&amp;#8217; contain the names of the repos to be migrated. Note that collaborators, comments and anything outside of git itself will not be migrated.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/vdKCsAZ350Y" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/self-hosting-private-git.html</feedburner:origLink></entry>
 
 <entry>
   <title>Imagemagick Error in Textmate</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/qhC377fxpNo/imagemagick-error-in-textmate.html" />
   <updated>2010-11-26T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/imagemagick-error-in-textmate</id>
   <content type="html">&lt;p&gt;If you are getting the &amp;quot;... is not recognized by the &amp;#39;identify&amp;#39; command&amp;quot; runaround in Textmate, yet your examples pass when run via the command line, then your Textmate shell path might be wrong.&lt;/p&gt; 
&lt;p&gt;To fix, add the path to ImageMagick (run &amp;quot;which identify&amp;quot; in Terminal) to the beginning of Textmate&amp;#39;s Preferences &amp;gt; Shell Variables &amp;gt; PATH entry.&lt;p /&gt;
&lt;p&gt;Rerun your examples, and all should be hoopy.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/qhC377fxpNo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/imagemagick-error-in-textmate.html</feedburner:origLink></entry>
 
 <entry>
   <title>Flight 404 and Kinect</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/ZzrBlsRQcVc/flight-404-and-kinect.html" />
   <updated>2010-11-22T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/flight-404-and-kinect</id>
   <content type="html">&lt;iframe src="http://player.vimeo.com/video/17107669?portrait=0" frameborder="0" height="309" width="549"&gt;&lt;/iframe&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/ZzrBlsRQcVc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/flight-404-and-kinect.html</feedburner:origLink></entry>
 
 <entry>
   <title>Bundler no metadata found problem</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/Eb7Uouwh5lc/bundler-no-metadata-found-problem.html" />
   <updated>2010-09-28T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/bundler-no-metadata-found-problem</id>
   <content type="html">&lt;p&gt;On installing bundler, and getting into Rails 3.0.0, I began to get
the following error when running bundle install:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;/Library/Ruby/Site/1.8/rubygems/package/tar_input.rb:113:in &lt;span class="sb"&gt;`&lt;/span&gt;initialize&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;: No metadata found! &lt;span class="o"&gt;(&lt;/span&gt;Gem::Package::FormatError&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;There are sporadic posts about this, but the one that solved the
problem for me was the second comment on &lt;a href="http://github.com/carlhuda/bundler/issues/issue/704"&gt;this issue&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
	&lt;p&gt;I tracked this down to a corrupt .gem file in rubygems/cache folder. I submitted a patch to the rubygems team to provide better diagnostic output message which identifies the offending file. It still doesn&amp;rsquo;t address the root cause, but should help people find the problem faster.&lt;/p&gt;
	&lt;p&gt;At line 111 in /rubygems/package/tar_input.rb, change to:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;has_meta&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; may be corrupt! Delete it and retry the operation&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Package&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FormatError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No metadata found!&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;The problem (im my case) was caused by a corrupt .gem file. Adding those lines to tar_input will give you a more meaningful error message, and allow you to delete the offending gem files.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/Eb7Uouwh5lc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/bundler-no-metadata-found-problem.html</feedburner:origLink></entry>
 
 <entry>
   <title>Removing duplicate error messages in Rails</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/CIw9t2hfCU8/removing-duplicate-error-messages-in-rails.html" />
   <updated>2010-09-04T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/removing-duplicate-error-messages-in-rails</id>
   <content type="html">&lt;p&gt;If you have a number of validations on a model, then you can quickly end up with something like this appearing in your error blocks:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/temp-2010-09-04/IzofbJDcmAjvmGlvfxnpHBanvgxCFzEIBEFhCJqxAwJEyJIhFiotBimIrdue/Screen_shot_2010-09-04_at_08.50.06.png.scaled500.png" width="480" height="324"/&gt;
&lt;/p&gt;
&lt;p&gt;I'd prefer to see only one error message for each attribute:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/temp-2010-09-04/kkBCvBJpynGzasaHzGlflIiGaEibziFJaEfcIBqFBCbIHzgkwhcifbkuvwlo/Screen_shot_2010-09-04_at_08.49.40.png.scaled500.png" width="482" height="98"/&gt;
This can be achieved by creating an errors_helper.rb file in your apps helpers folder, and pasting the following code (mercilessly modified from &lt;a href="http://railsforum.com/viewtopic.php?id=38068"&gt;this post by Bert&lt;/a&gt; over on RailsForum):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ErrorsHelper&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;error_messages_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extract_options!&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;symbolize_keys&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;object_name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;instance_variable_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;@&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;object_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compact&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;count&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero?&lt;/span&gt;
      &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:class&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
          &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blank?&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;errorExplanation&amp;#39;&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:object_name&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;

      &lt;span class="no"&gt;I18n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with_options&lt;/span&gt; &lt;span class="ss"&gt;:locale&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:locale&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:scope&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:activerecord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:template&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;header_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:header_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:header_message&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="n"&gt;object_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:object_name&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;
          &lt;span class="n"&gt;object_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;I18n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;object_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:scope&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:activerecord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:models&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ss"&gt;:header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:model&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;object_name&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        
        &lt;span class="n"&gt;error_messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;full_flat_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:li&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ERB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Util&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html_safe&lt;/span&gt;

        &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
        &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:header_tag&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="ss"&gt;:h2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;header_message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blank?&lt;/span&gt;
        &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blank?&lt;/span&gt;
        &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ul&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error_messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;content_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:div&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;html_safe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  

  &lt;span class="c1"&gt;####################&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# added to make the errors display in a single line per field&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;####################&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;full_flat_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;message_bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;full_messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;

    &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;message_bucket&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
        &lt;span class="n"&gt;message_bucket&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
        
        &lt;span class="n"&gt;full_messages&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;titleize&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;full_messages&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/CIw9t2hfCU8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/removing-duplicate-error-messages-in-rails.html</feedburner:origLink></entry>
 
 <entry>
   <title>Be careful with UIImage imageNamed</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/1UIiXLKyz58/be-careful-with-uiimage-imagenamed.html" />
   <updated>2010-09-04T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/be-careful-with-uiimage-imagenamed</id>
   <content type="html">&lt;p&gt;An iPad app I have been working on recently began being jettisoned by
the OS for using too much memory. The annoying this was that there was
no sign of leaks, and while running the app through the Allocations
Instrument, there was no sign of excessive memory usage.&lt;/p&gt;

&lt;p&gt;The app requires the main screen to have a large background image that
changed as a UI control is modified by the user.&lt;/p&gt;

&lt;p&gt;I checked the usual suspects &amp;ndash; leaks, allocations and the stack traces
therein. What I found was that there were several large blocks of
memory being malloc'ed from within CoreGraphics, and that this memory
appeared to have been allocated outside of the scope of the code I&amp;rsquo;d
written:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://imgur.com/HrmjZ.png'&gt;&lt;img src="http://imgur.com/HrmjZ.png" alt="Stack Trace" width='500px' /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a lot of tracing this problem, I found the culprit:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="objc"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UIImage&lt;/span&gt; &lt;span class="nl"&gt;imageNamed:&lt;/span&gt;&lt;span class="err"&gt;@&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;Someimage&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;p&gt;Calls to this method cause the named image to be loaded into memory
and &lt;strong&gt;cached&lt;/strong&gt;. The image will remain in memory for the duration of
your apps lifetime, and, if you have enough large images and calls to
this function, they will cause the OS to jettison your program.&lt;/p&gt;

&lt;h2&gt;The Solution&lt;/h2&gt;

&lt;p&gt;Don&amp;rsquo;t use [UIImage imageNamed:@&amp;lsquo;Someimage&amp;rsquo;] unless the image is small
and you want to use it repeatedly in your app. Instead, the following
snippet will allow you to load the image, then release it&amp;rsquo;s memory
once you&amp;rsquo;re finished:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="objc"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UIImage&lt;/span&gt; &lt;span class="nl"&gt;imageWithContentsOfFile:&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;Note that imageNamed is not evil, it just needs some extra thought
when using it. If there are enough images of a significant size, then
the memory retained by this call may get your program forceably
removed by the OS.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/1UIiXLKyz58" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/be-careful-with-uiimage-imagenamed.html</feedburner:origLink></entry>
 
 <entry>
   <title>WEH</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/Onl9vArZjNg/weh.html" />
   <updated>2010-08-19T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/weh</id>
   <content type="html">&lt;iframe title="YouTube video player" width="549" height="442" src="http://www.youtube.com/embed/qbecmZdIh0E" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/Onl9vArZjNg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/weh.html</feedburner:origLink></entry>
 
 <entry>
   <title>This Book is Made (of Rabbits and Lemonade)</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/qLCw_sMyLb4/this-book-is-made-of-rabbits-and-lemonade.html" />
   <updated>2010-08-19T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/this-book-is-made-of-rabbits-and-lemonade</id>
   <content type="html">&lt;p&gt;My favourite track from&amp;nbsp;&lt;a href="http://mislav.uniqpath.com/poignant-guide/"&gt;_why's&amp;nbsp;(poignant) guide to ruby&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;
       &lt;div class='downloadFlyout'&gt;
       &lt;div class="downloadIcon"&gt;&lt;a href='http://posterous.com/getfile/files.posterous.com/bouldr/mqLQxuqwDeohfK2SHScG42UYxrh9Ltm2tTcLoLw0mDVuyfKAx9aGCNh4TG8D/chapter-2-this-book-is-made.mp3'&gt;&lt;img src='http://posterous.com/images/filetypes/mp3.png' style='border: none;'/&gt;&lt;/a&gt;&lt;/div&gt;
       &lt;div class="downloadlinkInstructions"&gt;&amp;nbsp;&amp;nbsp;&lt;br/&gt;Download now or &lt;a href='http://codebeef.com/this-book-is-made-of-rabbits-and-lemonade' style='color: #bc7134;'&gt;listen on posterous&lt;/a&gt;&lt;/div&gt;
       &lt;b&gt;&lt;a href='http://posterous.com/getfile/files.posterous.com/bouldr/mqLQxuqwDeohfK2SHScG42UYxrh9Ltm2tTcLoLw0mDVuyfKAx9aGCNh4TG8D/chapter-2-this-book-is-made.mp3'&gt;chapter-2-this-book-is-made.mp3&lt;/a&gt;&lt;/b&gt; &lt;span class="downloadSize"&gt;(4374 KB)&lt;/span&gt;
       &lt;br class="clearboth"/&gt;&lt;/div&gt;
      &lt;/p&gt;
&lt;div&gt;Happy #whyday!&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/qLCw_sMyLb4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/this-book-is-made-of-rabbits-and-lemonade.html</feedburner:origLink></entry>
 
 <entry>
   <title>Steph Davies and Friends</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/nMF4i23vvPA/steph-davies-and-friends.html" />
   <updated>2010-08-17T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/steph-davies-and-friends</id>
   <content type="html">&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="309" width="549"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=14019614&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/nMF4i23vvPA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/steph-davies-and-friends.html</feedburner:origLink></entry>
 
 <entry>
   <title>Lasse Gjertsen</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/QuadqDbmprc/lasse-gjertsen.html" />
   <updated>2010-08-12T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/lasse-gjertsen</id>
   <content type="html">&lt;div&gt;Forgot about this. Old(ish), but still awesome.&lt;/div&gt;&lt;p /&gt;&lt;object height="417" width="500"&gt;&lt;param name="movie" value="http://www.youtube.com/v/JzqumbhfxRo&amp;hl=en&amp;fs=1" /&gt;&lt;/param&gt;&lt;param name="wmode" value="window" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/JzqumbhfxRo&amp;hl=en&amp;fs=1" allowfullscreen="true" type="application/x-shockwave-flash" allowscriptaccess="always" wmode="window" height="417" width="500"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/QuadqDbmprc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/lasse-gjertsen.html</feedburner:origLink></entry>
 
 <entry>
   <title>Maptastic - Formtastic Map Location Selector</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/5ELfWTi5b4g/maptastic-formtastic-map-location-selector.html" />
   <updated>2010-07-28T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/maptastic-formtastic-map-location-selector</id>
   <content type="html">&lt;p&gt;If you&amp;rsquo;ve spent time with Rails, you&amp;rsquo;ll already know that Formtastic is ace, and constructing forms using the SemanticFormBuilder keeps your code neat, and the output sensible and semantic.&lt;/p&gt;

&lt;p&gt;More often, I find the need to include a control in my forms that allows the user to find and select a single LatLng, and, up until now, I&amp;rsquo;ve been adding in hidden fields and creating js that allows me to present a map control.&lt;/p&gt;

&lt;p&gt;In an effort to reduce this duplication, I&amp;rsquo;ve built a Rails plugin for Formtastic that provides a new map_input and multi_input function, which means if you have a lat/lng pair, and you want to let the user fill out these values, all you need do is:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="erb"&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;semantic_form_for&lt;/span&gt; &lt;span class="vi"&gt;@venue&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;multi_input&lt;/span&gt; &lt;span class="ss"&gt;:latitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:longitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:map&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;Note you&amp;rsquo;ll also need to include the Google Maps script in your header:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;http://maps.google.com/maps/api/js?sensor=true&amp;#39;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;h3&gt;Installation&lt;/h3&gt;

&lt;p&gt;You&amp;rsquo;ll need &lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install Maptastic as a plugin:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;script/plugin install http://github.com/MattHall/maptastic
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;h3&gt;Development&lt;/h3&gt;

&lt;p&gt;This plugin is under development. It&amp;rsquo;s pretty simple, and patches are very welcome.&lt;/p&gt;

&lt;p&gt;The Repo is available on GitHub: &lt;a href="http://github.com/MattHall/maptastic"&gt;http://github.com/MattHall/maptastic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Report bugs here: &lt;a href="https://matt.purifyapp.com/projects/maptastic/issues"&gt;https://matt.purifyapp.com/projects/maptastic/issues&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/5ELfWTi5b4g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/maptastic-formtastic-map-location-selector.html</feedburner:origLink></entry>
 
 <entry>
   <title>The Longest Way</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/juJvTPA35GI/the-longest-way.html" />
   <updated>2010-07-27T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/the-longest-way</id>
   <content type="html">&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="309" width="549"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=4636202&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/juJvTPA35GI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/the-longest-way.html</feedburner:origLink></entry>
 
 <entry>
   <title>Beta Testing Features in Rails</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/vABXPpPcymc/beta-testing-features-in-rails.html" />
   <updated>2010-07-19T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/beta-testing-features-in-rails</id>
   <content type="html">&lt;p&gt;When building a new feature into a web app, it&amp;rsquo;s useful to have beta testers use it for a a while before it&amp;rsquo;s fully launched in order to catch any last minute bugs, to get an idea of whether the new feature feels right and if it actually solves the original problem.&lt;/p&gt;

&lt;p&gt;It is also sometimes desirable to have the beta testing process work from within the existing production app, in order for the production data to be used, and to prevent beta users from being isolated from other users. This may not be the case with an application that does not promote interaction between users, and in such cases, it is probably desirable to create a beta deploy of the application.&lt;/p&gt;

&lt;p&gt;The following is the method by which I beta test features in my own (Rails) apps &amp;ndash; YMMV.&lt;/p&gt;

&lt;h3&gt;Give certain users beta status&lt;/h3&gt;

&lt;p&gt;This is fairly simple &amp;ndash; either add a boolean beta field to the user model or, if you&amp;rsquo;re using something to manage roles, add a beta role to the users you&amp;rsquo;re adding to your beta program. Be sure to protect this attribute:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;attr_protected&lt;/span&gt; &lt;span class="ss"&gt;:is_beta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;If you&amp;rsquo;re using roles, then you can segment your beta users, granting access to individual features if necessary.&lt;/p&gt;

&lt;h3&gt;Hiding actions fron non-beta users&lt;/h3&gt;

&lt;p&gt;In your application_controller.rb define the following function:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;require_beta&lt;/span&gt;
  &lt;span class="vi"&gt;@current_user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_beta?&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;In any controllers that have actions that need to be protected, you can then write:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;before_filter&lt;/span&gt; &lt;span class="ss"&gt;:require_beta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;h3&gt;Hiding UI elements&lt;/h3&gt;

&lt;p&gt;There will probably be links, forms and UI elements that you&amp;rsquo;ll need to only display to beta users, so, in your application helper:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;beta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:is_beta?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;non_beta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:is_beta?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Then, whenever you have a UI element you only want to appear to beta users, just wrap it in the beta call:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="erb"&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;beta&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  This text will only be shown to logged in beta testers&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;non_beta&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;  This text will only be shown to normal users and non-logged in users&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/vABXPpPcymc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/beta-testing-features-in-rails.html</feedburner:origLink></entry>
 
 <entry>
   <title>Flight404</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/2H8gVi1OLdg/flight404.html" />
   <updated>2010-07-16T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/flight404</id>
   <content type="html">&lt;p&gt;If you haven't seen &lt;a href="http://www.vimeo.com/flight404"&gt;Flight404&lt;/a&gt;'s stuff yet, you're missing out.&lt;/p&gt;
&lt;p /&gt;
&lt;div&gt;&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="281" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=658158&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;&lt;/div&gt;
&lt;p /&gt;
&lt;div&gt;&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="281" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=7578615&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;&lt;/div&gt;
&lt;p /&gt;
&lt;div&gt;&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="345" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=935317&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;&lt;/div&gt;
&lt;p /&gt;
&lt;div&gt;&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="281" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=13172823&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/2H8gVi1OLdg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/flight404.html</feedburner:origLink></entry>
 
 <entry>
   <title>Last Day Dream</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/adtwp6BVoTc/last-day-dream.html" />
   <updated>2010-07-15T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/last-day-dream</id>
   <content type="html">&lt;div&gt;&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="281" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=4155700&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;&lt;/div&gt;
&lt;p /&gt;
&lt;p&gt;&lt;a href="http://www.vimeo.com/chrismilk"&gt;Chris Milk&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/adtwp6BVoTc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/last-day-dream.html</feedburner:origLink></entry>
 
 <entry>
   <title>Hacking Through Rails' Multi Parameter Date Handling</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/cDq4oR3UUwY/hacking-through-rails-multi-parameter-date-handling.html" />
   <updated>2010-07-15T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/hacking-through-rails-multi-parameter-date-handling</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;This code supersedes the code in &lt;a href="/2010/07/14/multiparameter-exception-hack/"&gt;this post&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Given a date_select, a user might (intentionally or otherwise) neglect
to enter a value for one of the selects. Rather than add an error to
the instance or default the missing date attributes to the current
date, Rails will throw an exception. This is problematic, as it leads
to the following sequence of events:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User commits a form with a missing date_select value&lt;/li&gt;
&lt;li&gt;Rails throws an exception&lt;/li&gt;
&lt;li&gt;User sees a 500&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The following code patches Activerecord::Base &amp;ndash; adding a validation
and messing with #execute_callstack_for_multiparameter_attributes. The
end result is that on submitting an invalid date, an error is added to
the instance when validations are run:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User commits a form with a missing date_select value&lt;/li&gt;
&lt;li&gt;multipart_error_on_attribute gets set to the name of the attribute
that contains the invalid date&lt;/li&gt;
&lt;li&gt;In the controller, when save is called, the validations fail, and
an error is added to the instance&lt;/li&gt;
&lt;li&gt;Typically, the user will then see the form rendered and an error message.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;strong&gt;This will only work for a narrow set of problems &amp;ndash; this code isn&amp;rsquo;t
really fit for stuffing back into Rails, so use with caution.&lt;/strong&gt;&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt; 

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;MultiparameterHack&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;included&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
    &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_to_base&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;humanize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is invalid&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;undef&lt;/span&gt; &lt;span class="ss"&gt;:execute_callstack_for_multiparameter_attributes&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_callstack_for_multiparameter_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;callstack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;callstack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values_with_empty_parameters&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="k"&gt;begin&lt;/span&gt;
            &lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reflect_on_aggregation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;column_for_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;
            &lt;span class="c1"&gt;# in order to allow a date to be set without a year, we must keep the empty values.&lt;/span&gt;
            &lt;span class="c1"&gt;# Otherwise, we wouldn&amp;#39;t be able to distinguish it from a date with an empty day.&lt;/span&gt;
            &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;values_with_empty_parameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:nil?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
              &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;=&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
              &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
                &lt;span class="n"&gt;instantiate_time_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
                &lt;span class="k"&gt;begin&lt;/span&gt;
                  &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;values_with_empty_parameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
                  &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;ArgumentError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="c1"&gt;# if Date.new raises an exception on an invalid date&lt;/span&gt;
                  &lt;span class="n"&gt;instantiate_time_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_date&lt;/span&gt; &lt;span class="c1"&gt;# we instantiate Time object and convert it back to a date thus using Time&amp;#39;s logic in handling invalid dates&lt;/span&gt;
                &lt;span class="k"&gt;end&lt;/span&gt;
              &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;

              &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;=&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;AttributeAssignmentError&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;error on assignment &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MultiparameterHack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/cDq4oR3UUwY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/hacking-through-rails-multi-parameter-date-handling.html</feedburner:origLink></entry>
 
 <entry>
   <title>The Tarantino Mixtape</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/z35wT1kErc8/the-tarantino-mixtape.html" />
   <updated>2010-07-14T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/the-tarantino-mixtape</id>
   <content type="html">&lt;p&gt;&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="281" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=4368246&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;Cheeky video remix by &lt;a href="http://www.vimeo.com/eclecticmethod"&gt;Eclectic Method&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/z35wT1kErc8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/the-tarantino-mixtape.html</feedburner:origLink></entry>
 
 <entry>
   <title>MultiParameter Exception Hack</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/wBRY3UGPHXU/multiparameter-exception-hack.html" />
   <updated>2010-07-14T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/multiparameter-exception-hack</id>
   <content type="html">&lt;p&gt;When using date_select or datetiime_select form helpers in rails, the
valies of the individual time fields are sent separately, and
reassembled back into a date within ActiveRecord::Base. Unfortunately,
if the user enters an invalid date, then this process fails with a
ActiveRecord::MultiparameterAssignmentErrors exception.&lt;/p&gt;

&lt;p&gt;The exception occurs before we actually get anywhere near our
application code, &lt;a href="http://robots.thoughtbot.com/post/159808527/ruby-on-fails"&gt;so it&amp;rsquo;s by no means a trivial problem&lt;/a&gt;, so it&amp;rsquo;s
unfortunately necessary to monkey patch the offending function. &lt;strong&gt;The
following code represents a substantial hack &amp;ndash; there are probably
better ways of taking care of this problem, but this is the best I
could come up with in the short space of time I had available.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The solution I came to involved reimplementing the
execute_callstack_for_multiparameter_attributes function in
ActiveRecord::Base, and removing the exception throw. An instance
variable (multipart_error_on_attribute) is then used to store the
invalid attributes which is checked in a custom validation. If
multipart_error_on_attribute contains any number of attribute symbols,
then the validation fails, and an error is added to the object.&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;MultiparameterHack&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;included&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
    &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_to_base&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;humanize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is invalid&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;undef&lt;/span&gt; &lt;span class="ss"&gt;:execute_callstack_for_multiparameter_attributes&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_callstack_for_multiparameter_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;callstack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;callstack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values_with_empty_parameters&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="k"&gt;begin&lt;/span&gt;
            &lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reflect_on_aggregation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;column_for_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;
            &lt;span class="c1"&gt;# in order to allow a date to be set without a year, we must keep the empty values.&lt;/span&gt;
            &lt;span class="c1"&gt;# Otherwise, we wouldn&amp;#39;t be able to distinguish it from a date with an empty day.&lt;/span&gt;
            &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;values_with_empty_parameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:nil?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty?&lt;/span&gt;
              &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;=&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
              &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
                &lt;span class="n"&gt;instantiate_time_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
                &lt;span class="k"&gt;begin&lt;/span&gt;
                  &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;values_with_empty_parameters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
                  &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;ArgumentError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="c1"&gt;# if Date.new raises an exception on an invalid date&lt;/span&gt;
                  &lt;span class="n"&gt;instantiate_time_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_date&lt;/span&gt; &lt;span class="c1"&gt;# we instantiate Time object and convert it back to a date thus using Time&amp;#39;s logic in handling invalid dates&lt;/span&gt;
                &lt;span class="k"&gt;end&lt;/span&gt;
              &lt;span class="k"&gt;else&lt;/span&gt;
                &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;

              &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;=&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;AttributeAssignmentError&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;error on assignment &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="vi"&gt;@multipart_error_on_attribute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MultiparameterHack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/wBRY3UGPHXU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/multiparameter-exception-hack.html</feedburner:origLink></entry>
 
 <entry>
   <title>One Issue Per Ticket, Please!</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/BXZYMpLN514/one-issue-per-ticket-please.html" />
   <updated>2010-07-13T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/one-issue-per-ticket-please</id>
   <content type="html">&lt;p&gt;&lt;a href="http://purifyapp.com"&gt;Bug tracking&lt;/a&gt; systems exist to help many people organise their efforts
in order to fix a problem or add a feature.&lt;/p&gt;

&lt;p&gt;The lifecycle of a bug may go something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reporter opens a ticket&lt;/li&gt;
&lt;li&gt;A developer gets assigned the ticket&lt;/li&gt;
&lt;li&gt;The developer completes work on the ticket&lt;/li&gt;
&lt;li&gt;The developer marks the ticket as resolved, and assigns it back to
the Reporter&lt;/li&gt;
&lt;li&gt;The reporter checks the fix, and closes the ticket.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Though there are many versions of this lifecycle, the purpose is to
move an issue from new to closed, logging the steps taken on that
particular issue.&lt;/p&gt;

&lt;p&gt;Problems arise when one ticket contains many issues.&lt;/p&gt;

&lt;p&gt;Someone will see that a bug has been worked on or resolved, and on
testing the feature will find another semi-related issue that has
either snuck in with the work for the original issue, or not been
detected up until that point. Spotting this, they will add a comment
to the original ticket. This is wrong.&lt;/p&gt;

&lt;p&gt;The correct course of action in this situation is to open a new ticket
&amp;ndash; not to add the problem to the discussion on the original issue. The
latter course of action quickly degrades the ticket into an email-like
exchange which can cause confusion. If email were a good enough
solution, we wouldn&amp;rsquo;t need bug tracking systems. The only time it is
reasonable to add a comment to an existing ticket is when the comment
relates only to the original issue.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/BXZYMpLN514" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/one-issue-per-ticket-please.html</feedburner:origLink></entry>
 
 <entry>
   <title>Showing the Commits You've Yet to Push in Git</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/7xWX3Llth0w/showing-the-commits-you-ve-yet-to-push-in-git.html" />
   <updated>2010-07-08T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/showing-the-commits-you-ve-yet-to-push-in-git</id>
   <content type="html">&lt;p&gt;If you&amp;rsquo;re using Git, and have set up a local branch that tracks a
remote branch, you&amp;rsquo;ll probably have seen the following message in your
git status at some point:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="c"&gt;# On branch master &lt;/span&gt;
&lt;span class="c"&gt;# Your branch is ahead of &amp;#39;origin/master&amp;#39; by 2 commits.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;This tells us that there are two commits in this branch that don&amp;rsquo;t
exist in the remote branch. To find out which commits these are, we
can do the following:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;git log origin/master..
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;Note the double period &amp;ndash; it&amp;rsquo;s not a typo.&lt;/p&gt;

&lt;p&gt;This command can be used to compare the branch you&amp;rsquo;re currently on
with any other branch, showing the commits yet to be pushed.&lt;/p&gt;

&lt;p&gt;To see commits on the remote branch you have yet to pull, use:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;git log origin/master...
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/7xWX3Llth0w" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/showing-the-commits-you-ve-yet-to-push-in-git.html</feedburner:origLink></entry>
 
 <entry>
   <title>I've just asked you to print it for me!</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/caoY6u4H67g/i-ve-just-asked-you-to-print-it-for-me.html" />
   <updated>2010-07-08T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/i-ve-just-asked-you-to-print-it-for-me</id>
   <content type="html">&lt;p&gt;Having a common name and an email address comprised of that name means I do occasionally get email that was intended for other people. What I find disturbing is the insistance by some of these people that I am in fact the intended recipient:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From:&lt;/strong&gt; Anne Hall&lt;br /&gt;
&lt;strong&gt;To:&lt;/strong&gt; me&lt;br /&gt;
&lt;strong&gt;Subject:&lt;/strong&gt; please print&lt;/p&gt;

&lt;p&gt;Hi Mrs. Hall,&lt;/p&gt;

&lt;p&gt;I hope you&amp;rsquo;re having a good summer.  I will be retaking my math 2 subject test in november and I have signed up to take the SAT again in november.  I&amp;rsquo;m going to be college tripping in on the east coast in august.  I will most likely visit Haverford, Swarthmore, schools around the D.C. area, and other colleges.  I haven&amp;rsquo;t decided completely yet.  Right now, everything that we had is still on my list, and I will e-mail Mrs. Mack about the recommendations.&lt;/p&gt;

&lt;p&gt;,Chris&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;From:&lt;/strong&gt; me&lt;br /&gt;
&lt;strong&gt;To:&lt;/strong&gt; Anne Hall&lt;br /&gt;
&lt;strong&gt;Subject:&lt;/strong&gt; RE: please print&lt;/p&gt;

&lt;p&gt;Hi,&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t think this email was intended for me.&lt;/p&gt;

&lt;p&gt;Thanks,&lt;/p&gt;

&lt;p&gt;Matthew Hall&lt;/p&gt;

&lt;p&gt;codebeef.com&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;From:&lt;/strong&gt; Anne Hall&lt;br /&gt;
&lt;strong&gt;To:&lt;/strong&gt; me&lt;br /&gt;
&lt;strong&gt;Subject:&lt;/strong&gt; RE: RE: please print&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I&amp;rsquo;ve just asked you to print it for me!&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;From:&lt;/strong&gt; me&lt;br /&gt;
&lt;strong&gt;To:&lt;/strong&gt; Anne Hall&lt;br /&gt;
&lt;strong&gt;Subject:&lt;/strong&gt; RE: RE: RE: please print&lt;/p&gt;

&lt;p&gt;Ok, I&amp;rsquo;ve printed it. Come round and pick it up.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/caoY6u4H67g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/i-ve-just-asked-you-to-print-it-for-me.html</feedburner:origLink></entry>
 
 <entry>
   <title>Rails Try with Parameters</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/VgyBNmh7cT4/rails-try-with-parameters.html" />
   <updated>2010-07-07T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/rails-try-with-parameters</id>
   <content type="html">&lt;p&gt;When dealing with a collection of different objects in Rails, it is often
necessary to call a method that may or may not be defined on all of the
instances in the collection. For example, formatting the following array of
DateTimes will throw an ArgumentError:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ago&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;The reason being that nil.to_s takes zero arguments.&lt;/p&gt;

&lt;h2&gt;Trying&lt;/h2&gt;

&lt;p&gt;Rails provides try, which can be used in association with a list of
parameters to attempt to invoke a method on an object:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ago&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:to_s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/VgyBNmh7cT4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/rails-try-with-parameters.html</feedburner:origLink></entry>
 
 <entry>
   <title>Splitting an Array in Half in Ruby</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/aj-8YR6TJTc/splitting-an-array-in-half-in-ruby.html" />
   <updated>2010-07-06T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/splitting-an-array-in-half-in-ruby</id>
   <content type="html">&lt;p&gt;So I have a collection of objects I need to split into two approximately
equal arrays. Luckily, there is &lt;a href="http://ruby-doc.org/core/classes/Enumerable.html#M003130"&gt;the partition method&lt;/a&gt; in Ruby:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;
&lt;span class="n"&gt;group_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;partition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;The partition method iterates over each object, with the object being pushed
to the first array if the block evaluates to true, and vice-versa.&lt;/p&gt;

&lt;p&gt;Alternatively, we could use &lt;a href="http://apidock.com/rails/Array/in_groups_of"&gt;in_groups_of&lt;/a&gt; if we&amp;rsquo;re using Rails:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;group_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in_groups_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/aj-8YR6TJTc" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/splitting-an-array-in-half-in-ruby.html</feedburner:origLink></entry>
 
 <entry>
   <title>Variable number of Objects on has_many in Factory_Girl</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/Ay44OWT1WdA/variable-number-of-objects-on-has-many-in-factory-girl.html" />
   <updated>2010-06-29T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/variable-number-of-objects-on-has-many-in-factory-girl</id>
   <content type="html">&lt;p&gt;When creating a (&lt;a href="http://github.com/thoughtbot/factory_girl"&gt;factory_girl&lt;/a&gt;) factory for an object that has an
optional has_many relation, I would like for the factory to create a
variable number of objects on the relation. I have the following code,
which works, but I suspect there is a better way of doing this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Factory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Faker&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Lorem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;

  &lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;instances&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
    &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;instances&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Factory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:image&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="n"&gt;instances&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Anyone have any thoughts?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/Ay44OWT1WdA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/variable-number-of-objects-on-has-many-in-factory-girl.html</feedburner:origLink></entry>
 
 <entry>
   <title>Two Views of my Job</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/fhAAGUCNOyw/two-views-of-my-job.html" />
   <updated>2010-06-25T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/two-views-of-my-job</id>
   <content type="html">&lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="375" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=12076820&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;&lt;p /&gt; &lt;object data="http://vimeo.com/moogaloop.swf" type="application/x-shockwave-flash" height="375" width="500"&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf" /&gt;&lt;param name="flashvars" value="clip_id=11902358&amp;amp;color=00adef&amp;amp;fullscreen=1&amp;amp;server=vimeo.com&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;show_title=1" /&gt;&lt;/object&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/fhAAGUCNOyw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/two-views-of-my-job.html</feedburner:origLink></entry>
 
 <entry>
   <title>Avoiding Short-Circuit Evaluation when Validating in Rails</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/Tjw6lU6VtGs/avoiding-short-circuit-evaluation-when-validating-in-rails.html" />
   <updated>2010-06-25T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/avoiding-short-circuit-evaluation-when-validating-in-rails</id>
   <content type="html">&lt;p&gt;Say you are saving two unrelated models at the same time, and you want
to validate them before doing so. The following code is usually the
first thought:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valid?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;model2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valid?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# Save and redirect&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="c1"&gt;# Render form again to show errors&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;The problem is that if both models are invalid, then we need to show
the error messages for both, however the use of AND will mean that
only the first of the two components of the if statement will be
executed, leaving model2 unchecked. The user will correct the errors
shown in model1 and resubmit, but validation will fail on model2, and
the form rendered with error messages a second time.&lt;/p&gt;

&lt;p&gt;A better solution is to avoid the short-circuit evaluation:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;model1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model2&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:valid?&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;This will validate both models, and only return true if they are both
valid, meaning that the user will see the errors for both models
before resubmitting the corrected form.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/Tjw6lU6VtGs" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/avoiding-short-circuit-evaluation-when-validating-in-rails.html</feedburner:origLink></entry>
 
 <entry>
   <title>Showing the Change History for a File in Git</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/4PfAAzk7cO4/showing-the-change-history-for-a-file-in-git.html" />
   <updated>2010-06-24T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/showing-the-change-history-for-a-file-in-git</id>
   <content type="html">&lt;p&gt;To view a list of changes in a git repo, we can use:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;git log
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;To view the list of changes for a single file:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;git log filename
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;To view the actual patches and commit messages:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;git log -p filename
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/4PfAAzk7cO4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/showing-the-change-history-for-a-file-in-git.html</feedburner:origLink></entry>
 
 <entry>
   <title>Comparing a DateTime with a Time in Ruby</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/XY1OH447iJs/comparing-a-datetime-with-a-time-in-ruby.html" />
   <updated>2010-06-23T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/comparing-a-datetime-with-a-time-in-ruby</id>
   <content type="html">&lt;p&gt;For anyone that comes across this problem:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; 
&lt;span class="go"&gt;=&amp;gt; Wed Jun 23 13:50:35 +0100 2010 &lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="go"&gt;=&amp;gt; Wed, 23 Jun 2010 13:50:35 +0100 &lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; 
&lt;span class="go"&gt;=&amp;gt; Wed Jun 23 13:50:35 +0100 2010 &lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; 
&lt;span class="go"&gt;=&amp;gt; Wed, 23 Jun 2010 13:50:35 +0100 &lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; 
&lt;span class="go"&gt;=&amp;gt; false &lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_datetime&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; 
&lt;span class="go"&gt;=&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;The solution is to use ===&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="irb"&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_datetime&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; 
&lt;span class="go"&gt;=&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;From &lt;a href="http://corelib.rubyonrails.org/classes/Date.html#M001270"&gt;the docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote class="posterous_short_quote"&gt;&lt;p&gt;Compares dates by Julian Day Number. When comparing two DateTime instances, or a DateTime with a Date, the instances will be regarded as equivalent if they fall on the same date in local time.&lt;/p&gt;&lt;/blockquote&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/XY1OH447iJs" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/comparing-a-datetime-with-a-time-in-ruby.html</feedburner:origLink></entry>
 
 <entry>
   <title>Rocks</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/24zt48GthZA/rocks.html" />
   <updated>2010-06-22T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/rocks</id>
   <content type="html">&lt;p&gt;Building a site around rock climbing has meant that my photos folder contains stuff like this.&lt;/p&gt;
&lt;p&gt;&lt;a href='http://posterous.com/getfile/files.posterous.com/bouldr/71quLwYVNSWFsGMAxuPmgYC8OgtfLPXVlyubRZT1ZKOaw30Ojpvtcjsaoc6r/100_1456.jpg.scaled.1000.jpg'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/bouldr/UduCuI1pPU483VuSrJAKN6NIvT1Ovf9lkFoLGTWuRykp4YQ8tvd8A3OWMqCz/100_1456.jpg.scaled.500.jpg" width="500" height="375"/&gt;&lt;/a&gt;
&lt;a href='http://posterous.com/getfile/files.posterous.com/bouldr/FrHUywTLvMHgK4UMQadRM9zwbVjDQTkTzm3Bc2R3sEm8XkkuCtYG26a7LF82/100_1458.jpg.scaled.1000.jpg'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/bouldr/89OhOeVjLEqSs2uY6KBVF931rEasZvLBJtQEFZkLwwgE3Z8YVeMV8GsZGWym/100_1458.jpg.scaled.500.jpg" width="500" height="375"/&gt;&lt;/a&gt;
&lt;a href='http://posterous.com/getfile/files.posterous.com/bouldr/3461FiWUMZ74XV9fuugo4KiJ07rYFnnpBakV9qjSz8nwfKG76beoo9RJnmC3/100_1756.jpg.scaled.1000.jpg'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/bouldr/OEgUI3vkk6PibKHsgAhmXWNkbNplLd3zsb8zeLsbAebmzZ0JMFagmA1oA6lv/100_1756.jpg.scaled.500.jpg" width="500" height="667"/&gt;&lt;/a&gt;
&lt;a href='http://posterous.com/getfile/files.posterous.com/bouldr/QBeedRIiS9PMKB6wzhbP3Z7UDVEchJlcdAqCs2XJEojkl3dBGGGIs50W61gj/100_1700.jpg.scaled.1000.jpg'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/bouldr/8p4peDrQR9Mb74C3NlQLohcZKnloWM5vKhmWwa9np8h4J3HHN2TzYAl5IgIn/100_1700.jpg.scaled.500.jpg" width="500" height="375"/&gt;&lt;/a&gt;
&lt;img src="http://posterous.com/getfile/files.posterous.com/temp-2010-06-22/uycFxDoAbwBFolHqnEqgsiGCbblueIvlvnocljahgFCqkqfpBlzocbqBpxAx/100_1364.jpg.scaled500.jpg" width="400" height="300"/&gt;
&lt;img src="http://posterous.com/getfile/files.posterous.com/temp-2010-06-22/fmIgzIxxoAHpEfnFuEHAnvpkltzgarjAaFEDErDaGHAdnspcckezxzmIxrCe/100_1349.jpg.scaled500.jpg" width="400" height="300"/&gt;
&lt;a href='http://posterous.com/getfile/files.posterous.com/temp-2010-06-22/qtozpItkFFzhCzfdmeykerrHcdfcuAFArkFJrgkuiEBstEGaHBszJlivfAaj/100_1754.jpg.scaled1000.jpg'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/temp-2010-06-22/qtozpItkFFzhCzfdmeykerrHcdfcuAFArkFJrgkuiEBstEGaHBszJlivfAaj/100_1754.jpg.scaled500.jpg" width="500" height="375"/&gt;&lt;/a&gt;
&lt;a href='http://posterous.com/getfile/files.posterous.com/temp-2010-06-22/xdqdezsqfGjoHBkatcpvvkxgkIooJfjJjEimGHDrvtkgrGszBEhkEuBbfrzh/100_1692-1.jpg.scaled1000.jpg'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/temp-2010-06-22/xdqdezsqfGjoHBkatcpvvkxgkIooJfjJjEimGHDrvtkgrGszBEhkEuBbfrzh/100_1692-1.jpg.scaled500.jpg" width="500" height="375"/&gt;&lt;/a&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/24zt48GthZA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/rocks.html</feedburner:origLink></entry>
 
 <entry>
   <title>SSL_requirement and RSpec</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/X8W2rzYZRyI/ssl-requirement-and-rspec.html" />
   <updated>2010-02-17T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/ssl-requirement-and-rspec</id>
   <content type="html">&lt;p&gt;If you&amp;rsquo;re using ssl_requirement, and speccing with RSpec, you&amp;rsquo;ll probably run into a problem whereby the before_filter ensure_proper_protocol redirects during your controller specs. To fix this, you can stub the call to ensure_proper_protocol, and make it return true. Add the following to your spec_helper.rb:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Spec&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Runner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:each&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ensure_proper_protocol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/X8W2rzYZRyI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/ssl-requirement-and-rspec.html</feedburner:origLink></entry>
 
 <entry>
   <title>Checking for a WiFi Connection in One Line</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/W6Cz543MVk8/checking-for-a-wifi-connection-in-one-line.html" />
   <updated>2009-08-22T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/checking-for-a-wifi-connection-in-one-line</id>
   <content type="html">&lt;p&gt;So if you have an app that requires a WiFi network connection in order to reliably synchronize some large-ish data set, you need to notify your user if the connection is not available. Apple provides the &lt;a href="http://developer.apple.com/iphone/library/samplecode/Reachability/index.html"&gt;Reachability example app&lt;/a&gt; that demonstrates how to do this, and you can use the Reachablility class from that app in your own app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the Reachability.h and Reachability.m files to your project.&lt;/li&gt;
&lt;li&gt;Include Reachablility.h in the header of the file you&amp;rsquo;re going to do the check&lt;/li&gt;
&lt;li&gt;Add the following line:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="objc"&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;Reachability&lt;/span&gt; &lt;span class="n"&gt;reachabilityForLocalWiFi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;currentReachabilityStatus&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ReachableViaWiFi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/W6Cz543MVk8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/checking-for-a-wifi-connection-in-one-line.html</feedburner:origLink></entry>
 
 <entry>
   <title>Easy Linking with Polymorphic Associations in Rails</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/iOvU_ePLYsM/easy-linking-with-polymorphic-associations-in-rails.html" />
   <updated>2009-07-24T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/easy-linking-with-polymorphic-associations-in-rails</id>
   <content type="html">&lt;p&gt;Just a quick tip, this one! If you have a model that is polymorphic, say a comment model:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Comment&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt; 
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:commentable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:polymorphic&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;and you want to link to the item the comment relates to in the admin system, you can do this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commentable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commentable&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;Note this assumes all of your commentable models have a title attribute or method, and that you have used normal RESTful routes. The :admin symbol will namespace the link to /admin&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/iOvU_ePLYsM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/easy-linking-with-polymorphic-associations-in-rails.html</feedburner:origLink></entry>
 
 <entry>
   <title>Bort updated to Rails 2.2</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/v2fYNYC4ybg/bort-updated-to-rails-2-2.html" />
   <updated>2008-11-10T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/bort-updated-to-rails-2-2</id>
   <content type="html">&lt;p&gt;If you don't already know, Bort has now been updated to Rails 2.2. For more information on exactly what has changed, &lt;a href="http://jimneath.org/2008/11/06/bort-update-to-rails-22/"&gt;please see Jim's post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have also updated my &lt;a href="http://github.com/MattHall/bort/tree/master"&gt;email-as-login fork of bort&lt;/a&gt; to include this release.&lt;/p&gt;

&lt;p&gt;Please give us your feedback over on &lt;a href="http://bort.uservoice.com/"&gt;our Uservoice page&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/v2fYNYC4ybg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/bort-updated-to-rails-2-2.html</feedburner:origLink></entry>
 
 <entry>
   <title>A Helper for Testing Access Control with RSpec</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/kD4a_Z7ZNjo/a-helper-for-testing-access-control-with-rspec.html" />
   <updated>2008-10-14T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/a-helper-for-testing-access-control-with-rspec</id>
   <content type="html">&lt;p&gt;When testing Controller actions for access restriction, I was building a set of tests for each controller that were in a similar format to this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;access control&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;should prevent access by non-logged-in users&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;should prevent access by normal users&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;should prevent access by editor users&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;should prevent access by admin users&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;should allow access by super admin users&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Unforunately, this was neither dry, complete, nor very readable, so I have come up with the following helper that allows you to specify the access restrictions for a number of methods: In your spec_helper.rb file, add the following function:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;access_control&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:allow&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:disallow&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:allow&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; should allow &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;login_as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;redirect_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:disallow&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; should disallow &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;login_as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;redirect_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Then in the specs for your controller, call the function as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;get :show, :id =&amp;gt; 0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;get :new&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;post :create, :setting_value =&amp;gt; {:value =&amp;gt; &amp;#39;A new setting&amp;#39;, :group =&amp;gt; 0}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;get :edit&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;put :update, :id =&amp;gt; SettingValue.first.id, :setting_value =&amp;gt; {:value =&amp;gt; &amp;#39;changed&amp;#39;}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;delete :destroy, :id =&amp;gt; SettingValue.first.id&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;access_control&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:allow&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:super_admin&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:disallow&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:quentin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This allows you to very quickly build a set of specs that fully describe how access control to your methods should restrict your users:&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/kD4a_Z7ZNjo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/a-helper-for-testing-access-control-with-rspec.html</feedburner:origLink></entry>
 
 <entry>
   <title>A Bort Fork - Rails Base Application</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/teJ66cdFhnY/a-bort-fork-rails-base-application.html" />
   <updated>2008-09-09T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/a-bort-fork-rails-base-application</id>
   <content type="html">&lt;p&gt;In order to DRY-up our process of creating new rails projects over at &lt;a href="http://fudgestudios.com"&gt;Fudge&lt;/a&gt;, we recently created &lt;a href="https://github.com/fudgestudios/bort/tree"&gt;Bort&lt;/a&gt; - a base rails application that contains all of the bits that we push together when starting out.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://jimneath.org/2008/09/09/bort-base-rails-application"&gt;Jim has more about the base system&lt;/a&gt;, but there is also &lt;a href="https://github.com/MattHall/bort/tree"&gt;a fork&lt;/a&gt; that contains all of the bort goodness, with the notable difference that instead of using usernames to authenticate, the users email address is used instead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MattHall/bort/tree"&gt;Enjoy.&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/teJ66cdFhnY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/a-bort-fork-rails-base-application.html</feedburner:origLink></entry>
 
 <entry>
   <title>Unterminated String Literal with Asset Packager</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/-nhUaGAR0zY/unterminated-string-literal-with-asset-packager.html" />
   <updated>2008-05-20T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/unterminated-string-literal-with-asset-packager</id>
   <content type="html">&lt;p&gt;A recent release of Bouldr threw a bit of a spanner in the works when the excellent Asset Packager began choking when attempting to create our concatenated and compressed javascript file.  It turns out that as I am developing in Windows (gah!), I need to run dos2unix in order to ensure that the js files are in the appropriate file format (our server is running CentOS). In order to automate this process, I added the following to our deploy script:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# Need to ensure files are in UNIX format for the asset packager to run correctly &lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;cd &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;release_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/public/javascripts &amp;amp;&amp;amp; find . -name &amp;#39;*.js&amp;#39; -exec dos2unix &amp;#39;{}&amp;#39; &lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;;&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# Run the asset packager to create the production javascript and css files &lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;cd &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;release_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; rake asset:packager:build_all RAILS_ENV=production&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/-nhUaGAR0zY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/unterminated-string-literal-with-asset-packager.html</feedburner:origLink></entry>
 
 <entry>
   <title>Really Simple History (RSH) Initial URL</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/fWe1bt6ydbE/really-simple-history-rsh-initial-url.html" />
   <updated>2008-04-07T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/really-simple-history-rsh-initial-url</id>
   <content type="html">&lt;p&gt;I recently came across a small problem in RSH whereby on loading a page with a state in the url (e.g. localhost.com/test_page#test) would not trigger the history listener function on it&amp;rsquo;s initial load. To fix this, I needed to modify my window onload function to include a call to my history listener, as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="nx"&gt;history_listener&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newLocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;historyData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;  &lt;span class="c1"&gt;// Window.onload calls this &lt;/span&gt;

&lt;span class="nx"&gt;initialize_history&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dhtmlHistory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;dhtmlHistory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;history_listener&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bindAsEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;                        

  &lt;span class="c1"&gt;// Added this line to force a call to my history listener&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;history_listener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dhtmlHistory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getCurrentLocation&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This ensures that when the page is freshly loaded, the history listener is called with the contents of our initial location.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/fWe1bt6ydbE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/really-simple-history-rsh-initial-url.html</feedburner:origLink></entry>
 
 <entry>
   <title>Installing MySQL Gem - CentOS</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/SZofaC7Mz_o/installing-mysql-gem-centos.html" />
   <updated>2008-01-24T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/installing-mysql-gem-centos</id>
   <content type="html">&lt;p&gt;This one had me for a while: When attempting to install the MySQL gem on my shiny new Slicehost slice, I was getting the folowing error:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;Building native extensions.  This could take a &lt;span class="k"&gt;while&lt;/span&gt;...
ERROR:  Error installing mysql:
ERROR: Failed to build gem native extension.

/usr/local/bin/ruby extconf.rb install mysql -- --with-mysql-include&lt;span class="o"&gt;=&lt;/span&gt;/usr/include/mysql --with-mysql-lib&lt;span class="o"&gt;=&lt;/span&gt;/usr/lib/mysql
checking &lt;span class="k"&gt;for &lt;/span&gt;mysql_query&lt;span class="o"&gt;()&lt;/span&gt; in -lmysqlclient... no
checking &lt;span class="k"&gt;for &lt;/span&gt;main&lt;span class="o"&gt;()&lt;/span&gt; in -lm... yes
checking &lt;span class="k"&gt;for &lt;/span&gt;mysql_query&lt;span class="o"&gt;()&lt;/span&gt; in -lmysqlclient... no
checking &lt;span class="k"&gt;for &lt;/span&gt;main&lt;span class="o"&gt;()&lt;/span&gt; in -lz... yes
checking &lt;span class="k"&gt;for &lt;/span&gt;mysql_query&lt;span class="o"&gt;()&lt;/span&gt; in -lmysqlclient... no
checking &lt;span class="k"&gt;for &lt;/span&gt;main&lt;span class="o"&gt;()&lt;/span&gt; in -lsocket... no
checking &lt;span class="k"&gt;for &lt;/span&gt;mysql_query&lt;span class="o"&gt;()&lt;/span&gt; in -lmysqlclient... no
checking &lt;span class="k"&gt;for &lt;/span&gt;main&lt;span class="o"&gt;()&lt;/span&gt; in -lnsl... yes
checking &lt;span class="k"&gt;for &lt;/span&gt;mysql_query&lt;span class="o"&gt;()&lt;/span&gt; in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file &lt;span class="k"&gt;for &lt;/span&gt;more
details.  You may need configuration options.

Provided configuration options:
   --with-opt-dir
   --without-opt-dir
   --with-opt-include
   --without-opt-include&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;-dir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/include
   --with-opt-lib
   --without-opt-lib&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;-dir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/lib
   --with-make-prog
   --without-make-prog
   --srcdir&lt;span class="o"&gt;=&lt;/span&gt;.
   --curdir
   --ruby&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin/ruby
   --with-mysql-config
   --without-mysql-config
   --with-mysql-dir
   --without-mysql-dir
   --with-mysql-include&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mysql&lt;/span&gt;&lt;span class="p"&gt;-dir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/include
   --with-mysql-lib&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mysql&lt;/span&gt;&lt;span class="p"&gt;-dir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/lib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-mlib
   --without-mlib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-zlib
   --without-zlib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-socketlib
   --without-socketlib
   --with-mysqlclientlib
   --without-mysqlclientlib
   --with-nsllib
   --without-nsllib
   --with-mysqlclientlib
   --without-mysqlclientlib

Gem files will remain installed in /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7 &lt;span class="k"&gt;for &lt;/span&gt;inspection.
Results logged to /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/gem_make.out
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It turns out, all I needed was to run the following:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;gem install mysql -- --with-mysql-config&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/mysql_config
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Hope this saves someone the hour or so I spent scratching my head!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/SZofaC7Mz_o" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/installing-mysql-gem-centos.html</feedburner:origLink></entry>
 
 <entry>
   <title>Stopping a submit_tag from Sending it's Value</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/SlD0AknMzyY/stopping-a-submit-tag-from-sending-it-s-value.html" />
   <updated>2007-12-12T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/stopping-a-submit-tag-from-sending-it-s-value</id>
   <content type="html">&lt;p&gt;OK, so say you have a form as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="erb"&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;form_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:method&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:get&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;-%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;text_field_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:q&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;submit_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Search&amp;#39;&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;That form will send the contents of the text box to the page at ‘/’. Unfortunately, it will also send through the value of the submit button, which is ‘Search’ in this case. The url generated will be:&lt;/p&gt;

&lt;p&gt;/?q=something&amp;amp;commit=Search&lt;/p&gt;

&lt;p&gt;In this case, we would want only the ‘q’ parameter passing through, and in order to do this, all we need do is nullify the name parameter:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="erb"&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;form_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:method&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:get&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="cp"&gt;-%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;text_field_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;q&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:q&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;submit_tag&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Search&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt; &lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This will create the following url on submission:&lt;/p&gt;

&lt;p&gt;/?q=something&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/SlD0AknMzyY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/stopping-a-submit-tag-from-sending-it-s-value.html</feedburner:origLink></entry>
 
 <entry>
   <title>Gem Documentation Server</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/VFrUP0A7fAg/gem-documentation-server.html" />
   <updated>2007-12-06T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/gem-documentation-server</id>
   <content type="html">&lt;p&gt;Just a quick tip I recently came across:  If you want to see the docs for any of the gems installed on your dev machine, type the following in the command line&amp;hellip;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;gem_server
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt; &amp;hellip;and then browse over to &lt;a href="http://localhost:8808/"&gt;http://localhost:8808/&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/VFrUP0A7fAg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/gem-documentation-server.html</feedburner:origLink></entry>
 
 <entry>
   <title>Rails 2.0 is Almost Here - Learn About It!</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/v1pE9D1jL-g/rails-2-0-is-almost-here-learn-about-it.html" />
   <updated>2007-12-04T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/rails-2-0-is-almost-here-learn-about-it</id>
   <content type="html">&lt;p&gt;&lt;a href="http://railscasts.com"&gt;Railscasts&lt;/a&gt; are a Rails developers wet-dream. &lt;/p&gt;

&lt;p&gt;Since Ryan created the site, it has been a fount of knowledge for anyone wishing to learn about the latest and greatest tips and tricks. To make things even better, they are &lt;b&gt;free&lt;/b&gt;, though &lt;a href="http://peepcode.com"&gt;PeepCode&lt;/a&gt; is also very much worth a look for those of us wanting to glean a little (or a lot) of in-depth knowledge; $9 is a menial sum to pay for what amounts to a full-on lecture!&lt;/p&gt;

&lt;p&gt;If you haven't done already, go take a look - there is even &lt;a href="http://railscasts.com/tags/17"&gt;a bunch of screencasts dedicated to Rails 2.0!&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/v1pE9D1jL-g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/rails-2-0-is-almost-here-learn-about-it.html</feedburner:origLink></entry>
 
 <entry>
   <title>Browser History in Web Apps</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/1QKRJuJa4cs/browser-history-in-web-apps.html" />
   <updated>2007-12-03T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/browser-history-in-web-apps</id>
   <content type="html">&lt;p&gt;Given that the back button has been around for many years, and users have grown accustomed to it's use, it's a shame to see so many web applications neglecting this feature. As an example, I'll pick on &lt;a href="http://www.huddletogether.com/projects/lightbox/"&gt;Lightbox&lt;/a&gt;, a tool that I like, yet one that is flawed in it's disregard for the back button. For example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You navigate to a page that contains a thumbnailed image&lt;/li&gt;
&lt;li&gt;You click the image, and Lightbox shows it centered in your browser, full size&lt;/li&gt;
&lt;li&gt;You click back, press the back button on your mouse or whatever&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, I realise that Lightbox has a close button in the image dialog box, but I'm not looking at the box, I'm looking at the image, and furthermore, my natural path back to the originating page is to press the back button, not to close the Lightbox. I therefore end up at the page I was on before I saw the thumbnail.  I've seen this with many users - the back button has been scarred into our mind, and to break it now is frivolous, and will ultimately lead to frustration, and lost users.  It's with relief therefore, that I found &lt;a href="http://blogs.pathf.com/agileajax/really_simple_history/index.html"&gt;Really Simple History&lt;/a&gt;, a JavaScript library for dealing with this exact problem - to create a JS history system that can run across many browsers, and provide developers with a little hope that our apps will no longer break the most fundamental user assumptions.  We tried to get the browser history working in &lt;a href="http://bouldr.net"&gt;Bouldr&lt;/a&gt;, and to an extent, we succeeded. The difference between coding something proprietary, and using an open source solution, though is very great indeed, so without doubt, we'll be refactoring to use this library in the future.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/1QKRJuJa4cs" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/browser-history-in-web-apps.html</feedburner:origLink></entry>
 
 <entry>
   <title>Add your Business to Facebook (for Free)!</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/yQPE4gpJW0A/add-your-business-to-facebook-for-free.html" />
   <updated>2007-11-28T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/add-your-business-to-facebook-for-free</id>
   <content type="html">&lt;p&gt;From a business standpoint, Facebook's killer feature is it's Social Network, which gives even none-techies the ability to share nuggets of information found both on Facebook and the web at large with their friends.&lt;/p&gt;
&lt;p&gt;What I didn't realise until recently is that &lt;a href="http://www.facebook.com/business/?pages"&gt;Facebook also allows businesses&lt;/a&gt; to set up pages inside the &lt;a href="http://www.codinghorror.com/blog/archives/000898.html"&gt;walled garden&lt;/a&gt;, that gives FB's users the opportunity to show their support of your business by becoming 'Fans'.&lt;/p&gt;
&lt;p&gt;It doesn't cost anything to set up a business page, which comes with a reporting tool that shows you just how many visits / page views / fans you're getting per day, an update tool that allows you to send news items to your fans, and a bunch of advertising tools that you can use to promote your business page.&lt;/p&gt;
&lt;p&gt;I set Bouldr up on the 21st November 2007 (&lt;a href="http://www.facebook.com/profile.php?id=7509527577"&gt;check it out!&lt;/a&gt;), and already I have around 15 fans, with a slew of visitors coming from Facebook over to Bouldr's main site. If you have a website that could benefit from a little social promotion, I'd suggest taking a look at Facebook's business listing service - it's free, so there is very little risk, really.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/yQPE4gpJW0A" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/add-your-business-to-facebook-for-free.html</feedburner:origLink></entry>
 
 <entry>
   <title>Wheel of Life (V16)</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/4hhu3CPkwew/wheel-of-life-v16.html" />
   <updated>2007-11-22T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/wheel-of-life-v16</id>
   <content type="html">&lt;p&gt;&lt;object height="417" width="500"&gt;&lt;param name="movie" value="http://www.youtube.com/v/D3ZnfqPVJlc&amp;hl=en&amp;fs=1" /&gt;&lt;/param&gt;&lt;param name="wmode" value="window" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/D3ZnfqPVJlc&amp;hl=en&amp;fs=1" allowfullscreen="true" type="application/x-shockwave-flash" allowscriptaccess="always" wmode="window" height="417" width="500"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;Just Awesome.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/4hhu3CPkwew" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/wheel-of-life-v16.html</feedburner:origLink></entry>
 
 <entry>
   <title>Mike Robertson Sends The Eiffel Tower</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/ERJW62Bsq_g/mike-robertson-sends-the-eiffel-tower.html" />
   <updated>2007-11-22T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/mike-robertson-sends-the-eiffel-tower</id>
   <content type="html">&lt;p&gt;&lt;object height="417" width="500"&gt;&lt;param name="movie" value="http://www.youtube.com/v/p4bjmXFcJsc&amp;hl=en&amp;fs=1" /&gt;&lt;/param&gt;&lt;param name="wmode" value="window" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/p4bjmXFcJsc&amp;hl=en&amp;fs=1" allowfullscreen="true" type="application/x-shockwave-flash" allowscriptaccess="always" wmode="window" height="417" width="500"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;In protest at Total's involvement in Burma, Mike Robertson solos the Eiffel Tower. (&lt;a href="http://www.ukclimbing.com/articles/page.php?id=646"&gt;via&lt;/a&gt;)&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/ERJW62Bsq_g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/mike-robertson-sends-the-eiffel-tower.html</feedburner:origLink></entry>
 
 <entry>
   <title>High Fidelity (V13), Caley</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/-1Mxn5mgz_A/high-fidelity-v13-caley.html" />
   <updated>2007-11-22T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/high-fidelity-v13-caley</id>
   <content type="html">&lt;p&gt;&lt;object height="417" width="500"&gt;&lt;param name="movie" value="http://www.youtube.com/v/PdG26UwP1YA&amp;hl=en&amp;fs=1" /&gt;&lt;/param&gt;&lt;param name="wmode" value="window" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/PdG26UwP1YA&amp;hl=en&amp;fs=1" allowfullscreen="true" type="application/x-shockwave-flash" allowscriptaccess="always" wmode="window" height="417" width="500"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://earl-andrewearl.blogspot.com/2007/11/hi-fidelity.html"&gt;Andrew Earl&lt;/a&gt; sends this Highball problem with perfect style - Amazing to watch!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/-1Mxn5mgz_A" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/high-fidelity-v13-caley.html</feedburner:origLink></entry>
 
 <entry>
   <title>Helper for Testing Model Validation in Unit Tests</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/vTKH3v0e_C4/helper-for-testing-model-validation-in-unit-tests.html" />
   <updated>2007-11-21T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/helper-for-testing-model-validation-in-unit-tests</id>
   <content type="html">&lt;p&gt;Here&amp;rsquo;s a little snippet that I use to quickly form tests to ensure that my models validation is working correctly from within unit tests:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# In test_helper.rb   &lt;/span&gt;
&lt;span class="c1"&gt;# Give this function an array of invalid values, an array of valid values, the object and   &lt;/span&gt;
&lt;span class="c1"&gt;# attribute name to test, and it will ensure that only valid values are allowed   &lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validation_tester&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;valid_values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invalid_values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_object&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;valid_values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;       
    &lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;[&lt;/span&gt;&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; should be valid: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;[&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;       
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valid?&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invalid?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;invalid_values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;[&lt;/span&gt;&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; should NOT be valid: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; 
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valid?&lt;/span&gt; 
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invalid?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attribute_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;   
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;Then, use it as follows in your unit tests:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_email_validation&lt;/span&gt; 
  &lt;span class="n"&gt;valid_emails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;matt@test.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;matt.hall@test.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;matt@test.ing.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;matt.hall@test.ing.com&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;invalid_emails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;@test.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;test.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;matt@&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;matt.hall@com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.matt@test.ing.co.uk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;matt@@test.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.@.&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_user&lt;/span&gt;
  &lt;span class="n"&gt;validation_tester&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;valid_emails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invalid_emails&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;Can anyone suggest any improvements?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/vTKH3v0e_C4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/helper-for-testing-model-validation-in-unit-tests.html</feedburner:origLink></entry>
 
 <entry>
   <title>Your Friends are Pokemon</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/6Kx1cO8X-q4/your-friends-are-pokemon.html" />
   <updated>2007-08-28T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/your-friends-are-pokemon</id>
   <content type="html">&lt;p&gt;I first noticed that I was a slave to Facebook when I was talking to a friend of a friend. We talked casually for a while, in the normal 'getting to know you' way, eventually touching on whether each other has a Facebook account. This seemed perfectly natural, however, on reflection, I could see that I had actually been working towards this question for the entire conversation; I wanted to breech The Facebook Threshold, and add this person as a friend.&lt;/p&gt;

&lt;p&gt;This was not the first time I had considered the possibility that I have been trawling my friends friend lists just to increase the friend count on my own profile, rather the first time I have accepted this seemingly innocuous yet worrying prospect.&lt;/p&gt;

&lt;p&gt;Speaking to my own friends, I find that this trend continues: many of those with more than fifty friends have actually collected people that they don't consider to be friends with any more - people from their pre-school days that are now 25 years old or more, and that they haven't spoken to or seen in the intervening period.&lt;/p&gt;

&lt;p&gt;Maybe it's just our social vanity getting the best of us, but escaping from this arms race feels almost impossible from the inside.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/6Kx1cO8X-q4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/your-friends-are-pokemon.html</feedburner:origLink></entry>
 
 <entry>
   <title>How to Use a Table from Another Database for a Model in Rails</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/Sxzmhwz1VeY/how-to-use-a-table-from-another-database-for-a-model-in-rails.html" />
   <updated>2006-12-15T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/how-to-use-a-table-from-another-database-for-a-model-in-rails</id>
   <content type="html">The problem is simple; I wanted a method by which a model in my app could use a table from another MySQL Database (on the same server). The solution is equally simple:

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
    &lt;span class="n"&gt;set_table_name&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;other_db.table_name&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


Where other_db is the database name, and table_name is the table you want to use.
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/Sxzmhwz1VeY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/how-to-use-a-table-from-another-database-for-a-model-in-rails.html</feedburner:origLink></entry>
 
 <entry>
   <title>Selling our Soul (in the Best Possible Way)</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/--FXB0jxzvI/selling-our-soul-in-the-best-possible-way.html" />
   <updated>2006-12-13T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/selling-our-soul-in-the-best-possible-way</id>
   <content type="html">&lt;p&gt;Building sites that both support and derive value from a community is one of our great memes at the moment, and one we have fully embraced when building &lt;a href="http://bouldr.net" title="Climbing Routes and Bouldering Problems"&gt;Bouldr&lt;/a&gt;. One of the biggest problems, however, is how to break even; servers, bandwidth and development all cost money, and someone has to pay.&lt;/p&gt;

&lt;p&gt;Thanks to the legions of advertising networks that have grown out of this rich demand for an easy monetisation method, there are plenty of opportunities to quickly and cheaply monetise a site (so long as you don't end up &lt;a href="http://sethgodin.typepad.com/seths_blog/2006/12/always_a_new_wa.html" title="Always a new way to interrupt"&gt;unintentionally breaking it&lt;/a&gt;, that is!).&lt;/p&gt;

&lt;p&gt;It is important to note that we have been very concious with Bouldr that it should never contain anything that is of no use or consiquence to our users - banner advertisements make any UI look tarnished, and ad networks can often end up showing adverts that are not relevant to the user.&lt;/p&gt;

&lt;p&gt;Bouldr serves climbers from around the world - we are a niche service, and we would like to keep it free for our users. Our niche is so well defined that we decided that a better way to organise the monetisation side of things was not to use a separate advertising publisher service, but to develop our own.  In this way, we are able to moderate the advertisers we accept in order to prevent our users seeing irrelevant ads, and we can integrate them into our site in as many varied ways as we like.&lt;/p&gt;

&lt;p&gt;Bouldr's Advertising network is not ready just yet, but we are well on the way, and hope to be launching soon.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/--FXB0jxzvI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/selling-our-soul-in-the-best-possible-way.html</feedburner:origLink></entry>
 
 <entry>
   <title>5 Ways to Turn Buyers Off</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/XmAMGDQaFw4/5-ways-to-turn-buyers-off.html" />
   <updated>2006-12-13T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/5-ways-to-turn-buyers-off</id>
   <content type="html">&lt;p&gt;Once you have set up your business, spent time and money promoting your services and products, you’ll need to think about how to convert your visitors into customers. I am going to look at methods by which you can improve your conversion rates by discussing some of the reasons that people will &lt;strong&gt;not&lt;/strong&gt; make a purchase after visiting your advertisement or site.&lt;/p&gt;
&lt;h2&gt;1. Getting the wrong people to your site&lt;/h2&gt;
&lt;p&gt;If you are targeting the wrong market sector with your advertising, then it really doesn’t matter how successful in drawing the crowds it is – they are not going to be interested in your products or services.&lt;/p&gt;

&lt;p&gt;Be as specific as possible. If your market is a niche market, then put advertisements in magazines or on Web sites that serve your niche. Decide on your target audience, and bombard them with advertising. You will find that targeted advertising will pay dividends more than generic advertising – if you add your business to our directory, then make sure you add it to relevant categories. Adding your new Website Optimisation service to a ‘Website Hosting’ directory will get you very few interested parties. Add your business to a relevant directory, and you’re target market will find you!&lt;/p&gt;
&lt;h2&gt;2. Poor content quality&lt;/h2&gt;
&lt;p&gt;People &lt;strong&gt;will not&lt;/strong&gt; read everything on your Web site or marketing material. Most people skim read when browsing, and as such, need content that is easy to process and digest.&lt;/p&gt;

&lt;p&gt;Always ensure that you have spellchecked your copy before posting it to your site; misspelled or grammatically incorrect passages will instantly give your visitors a bad impression of your business, after all, if you can’t be bothered to check your own marketing material for correctness, then your products and services are probably going to suffer from the same lack of professionalism.&lt;/p&gt;
&lt;h2&gt;3. Not describing products or services fully&lt;/h2&gt;
&lt;p&gt;Visitors will want to find out more about your products and services before they buy. By not explaining the features or specifications in full, you are leaving questions unanswered in the minds of your customers. If these questions are important enough, there is a good chance that your visitor will look elsewhere for answers, and end up purchasing from your competitors.&lt;/p&gt;

&lt;p&gt;Make sure that you cover as much detail as possible when describing your products – ideally, you should aim to be able to explain enough about the product that the potential customer has no need to research further. They should be ready and willing to make a purchase based on the information you have presented.&lt;/p&gt;
&lt;h2&gt;4. Not providing clear prices&lt;/h2&gt;
&lt;p&gt;There is no better way to lose the trust of potential customers than to provide obfuscated or inaccessable pricelists. If a customer is looking at your prices, then there is a good chance that they are either ready to make a purchase or are comparing prices. If you can present the price of your product or service on a page of your site in a way that allows a user to determine what it is within six seconds, then you're doing well. Any longer, and you risk overloading the user with options, decisions and ultimately turning them away.&lt;/p&gt;
&lt;h2&gt;5. Confusing navigation&lt;/h2&gt;
&lt;p&gt;Navigation is arguably the single most important aspect of any website; if no-one can find what they want, how are they going to buy from you?&lt;/p&gt;

&lt;p&gt;Getting navigation right, however, is no simple feat - books have been written on the subject that can cover it to a far deeper level than I can in a short post such as this. Furthermore, there are an endless number of sites dedicated to disseminating the best practices in navigation design that would make far better reading. For example:&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I have discussed some of the reasons as to why people may come to your site and not make a purchase. If you can avoid some of these common mistakes, then you are effectively reducing the number of barriers standing between a browsing customer becoming a paying customer.&lt;/p&gt;

&lt;p&gt;One final word of advice: Take a look at your site now – can you see any other potential barriers that may prevent a visitor from finding what they want and spontaneously purchasing it? If so, look at how you can remove these barriers – each time you do, you are effectively opening your doors further, and allowing more people to make purchases.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/XmAMGDQaFw4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/5-ways-to-turn-buyers-off.html</feedburner:origLink></entry>
 
 <entry>
   <title>5 Tips for Good Advertising Copy</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/1mU0PTmaSeY/5-tips-for-good-advertising-copy.html" />
   <updated>2006-12-13T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/5-tips-for-good-advertising-copy</id>
   <content type="html">&lt;p&gt;Advertising copy is the meat of your marketing campaigns – the actual information presented to your customers in order to get them to buy your products rather than a competitor’s.&lt;/p&gt;

&lt;p&gt;If you create great advertising copy, your advertising campaigns can only benefit, bringing more custom to your business, however, creating bad copy can waste both time and money – it can even give your company a bad reputation in your target market’s eyes.&lt;/p&gt;

&lt;p&gt;What I present here are a few points that I feel are vital to get right in order to produce marketing copy that is effective. These few points can be applied to many areas of marketing, whether it be creating a marketing brochure, a banner advertisement for a website or a point-of-sale display.&lt;/p&gt;
&lt;h2&gt;1. Get to the point&lt;/h2&gt;
&lt;p&gt;Most people will not read more than a single sentence or paragraph, so when it comes to writing advertising copy, it pays to get to the point as quickly as possible. Rambling on with details that have already been covered elsewhere in your advertisement will distract your potential customer, and in the time it has taken for them to read ‘Here at Syndicated System Solutions, our priority…’ they will have lost interest, and more than likely, will have moved on to the next item on the page.&lt;/p&gt;

&lt;p&gt;Start your advertisement with a benefit of your product or service – something that will catch their eye, for example: ‘Kyotee is a leading UK business directory’. At this point, we have set the precedent for the visitor to read on – Why is Kyotee a leading directory service? What do they offer? What can they do for me?&lt;/p&gt;

&lt;p&gt;Now that we have gained the interest of our potential customer, we now must provide the filler – a rich sentence or two describing the unique parts of our products and services that set us apart from the crowd.&lt;/p&gt;
&lt;h2&gt;2. Offer up&lt;/h2&gt;
&lt;p&gt;Your product or service is worth talking about, unfortunately, you will normally only have a finite amount of space or time in which to tell your prospective customer about it.&lt;/p&gt;

&lt;p&gt;Keep to the point – tell your customer how your product can save time or money, provide them with customers, increase sales margins, decrease costs, make a cup of tea in seconds – give the key features or reasons as to why they should come to you rather than a competitor. This is also a good place to add any current offers, sales or special deals you might have. Give the customer a reason to buy from you.&lt;/p&gt;

&lt;p&gt;Always keep your advertising copy focused on the thing you are selling. Do not deviate to tell the customer that you have been in business 15 years if it won’t matter to them, but above all that, make sure you finish your copy with the most important statement – the Call To Action.&lt;/p&gt;
&lt;h2&gt;3. Tell the Customer What To Do&lt;/h2&gt;
&lt;p&gt;A Call To Action is a crucial part of most advertising copy; A Call To Action tells the user what to do next. Our advertisement copy ends with such a phrase: “Submit your advertisements today, and gain valuable exposure!” We want the user to sign up for our service so they can begin advertising, however, if we hadn’t included this important sentence, then we risk leaving the user in limbo. We have got them excited about our service, we tell them how we are unique, and then we walk away? No.&lt;/p&gt;

&lt;p&gt;In order for an advertisement to be compelling, the user needs be told what they should do next in order to get to the thing that you are selling. Writing a good Call To Action will allow you to get your customers in line to make a purchase, but there is still one last detail to take into consideration: What happens when a customer does what you told them to do?&lt;/p&gt;
&lt;h2&gt;4. Land it Right&lt;/h2&gt;
&lt;p&gt;You have told your customer about your new, fantastic service or product, and they click on your web link or pick up the phone and dial the number in your advert. Unfortunately, the phone number you gave was a digit wrong or your Web site is not yet finished. Disaster!&lt;/p&gt;

&lt;p&gt;There is a very high probability that your potential customer won’t try to get through to you a different way – they will just hang up and go to the next advert in the list. At best, they will forget about their experience in trying to get hold of you, but at worst, they will associate your business with that bad experience, and avoid you in the future.&lt;/p&gt;

&lt;p&gt;It is imperative that the contact details you give in your advertisements are correct. Ideally, if you are advertising a particular service or product, then your web link should go directly to a page focused on it rather than your company homepage or contact form. If you give a phone number, then the person answering the phone should at least be the correct person, and even better, be able to help the customer to make a purchase or take the enquiry further.&lt;/p&gt;
&lt;h2&gt;5. Be Professional&lt;/h2&gt;
&lt;p&gt;Spelling, punctuation and grammar are all very important when it comes to writing copy of any type for your business – be it an email, brochure, advertisement or receipt. Lacking in any of these three areas gives a very poor impression of the level of professionalism employed within your business.&lt;/p&gt;

&lt;p&gt;If you are not confident in any of these three key areas, then it is better to have your copy proofread and run through a spell-checker than to leave it to chance. Remember that your customers probably do not know you, so all they a judging you on are the words you have chosen to promote yourself with. If these words don’t make sense, then your customer will disappear.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/1mU0PTmaSeY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/5-tips-for-good-advertising-copy.html</feedburner:origLink></entry>
 
 <entry>
   <title>Simple CSS Star Rating Bar</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/OI-E0asfO-g/simple-css-star-rating-bar.html" />
   <updated>2006-12-12T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/simple-css-star-rating-bar</id>
   <content type="html">&lt;p&gt;Just a quick bit of CSS that we came up with to display a percentage star rating that I'd like to share. This method requires two images - one with all of the stars highlighted, and one with them all greyed out:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://matthall.wordpress.com/files2006/12/five-star.gif"/&gt;&lt;/p&gt;


&lt;p&gt;&lt;img src="http://matthall.wordpress.com/files2006/12/zero-star.gif"/&gt;&lt;/p&gt;


&lt;p&gt;Note that these images are both 100 pixels wide (for simplicity) .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt; CSS&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="css"&gt;&lt;span class="nc"&gt;.starCont&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;moz&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;url(/images/zero-star.gif)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;background-repeat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;background-position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;bottom&lt;/span&gt; &lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;vertical-align&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.stars&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;moz&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;url(/images/five-star.gif)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;background-repeat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;background-position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;bottom&lt;/span&gt; &lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;vertical-align&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;text&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.stars&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;visibility&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;strong&gt;HTML&lt;/strong&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;starCont&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stars&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;span&amp;gt;&lt;/span&gt;%&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Serving Suggestion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use as part of a voting system whereby the percentage values are injected into the page via the value of *percentage*. If your star images are larger than 100px in width, then you will need to adjust the value that is calculated by an amount proportianal to the actual width.&lt;/p&gt;

&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/OI-E0asfO-g" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/simple-css-star-rating-bar.html</feedburner:origLink></entry>
 
 <entry>
   <title>How to Execute a Rails Controller Action via. Cron</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/f-psnjz3dQA/how-to-execute-a-rails-controller-action-via-cron.html" />
   <updated>2006-12-06T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/how-to-execute-a-rails-controller-action-via-cron</id>
   <content type="html">&lt;p&gt;I recently had to create a cron job that controlled the delivery of newsletters to a set of subscribers. Unfortunately, the code required some refactoring, but up until it could be modified, the task still needed firing at specific intervals.  I had a little trouble finding much on this subject, so here is the code I eventually used:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;./script/runner -e production &lt;span class="s2"&gt;&amp;quot;app = ActionController::Integration::Session.new; app.get &amp;#39;account/send_newsletters&amp;#39;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;With any luck, this will help another person save a couple of minutes! &lt;/p&gt;

&lt;h3&gt;Update&lt;/h3&gt;

&lt;p&gt;Since Rails 1.2, this method of executing rails controller actions has been throwing an &amp;ldquo;uninitialized constant ActionController::Integration&amp;rdquo; exception. Adding the following line to your environments.rb file fixes this problem:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="n"&gt;action_controller&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;integration&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



&lt;p&gt;Thanks, Dimitry Hristov!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/f-psnjz3dQA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/how-to-execute-a-rails-controller-action-via-cron.html</feedburner:origLink></entry>
 
 <entry>
   <title>SSH Access to StrongSpace from Textdrive</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/04wLrlpjmVE/ssh-access-to-strongspace-from-textdrive.html" />
   <updated>2006-12-05T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/ssh-access-to-strongspace-from-textdrive</id>
   <content type="html">&lt;p&gt;I came across a few pitfalls in my attempt to get my Textdrive account talking to my StrongSpace account over SSH without needing to enter my StrongSpace password at the prompt. I am setting out all of the steps necessary to get this working here so that others can avoid these same problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You should be familiar with gaining access to and using BASH on your Textdrive account before you go any further - if you don't then I suggest you go here for more information. I accept no responsibility for any damage or problems you may cause when using this tutorial. Make sure you take adequate backups and check any scripts before you run them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Creating the keys&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get started, we need to create a set of keys:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Log into your Textdrive shell, and navigate to  /users/home/USERNAME/.ssh/&lt;/li&gt;
	&lt;li&gt;Run the following command
&lt;code&gt;ssh-keygen -b 1024 -f ss -P '' -t dsa&lt;/code&gt;
&lt;/li&gt;
	&lt;li&gt;This will create two files - ss and ss.pub&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Uploading the public key (ss.pub) to your StrongSpace account&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Download ss.pub to your local machine&lt;/li&gt;
	&lt;li&gt;SFTP to your StrongSpace account&lt;/li&gt;
	&lt;li&gt;Create a new directory called .ssh under your account&lt;/li&gt;
	&lt;li&gt;chmod this directory to 700&lt;/li&gt;
	&lt;li&gt;Upload ss.pub to this new folder&lt;/li&gt;
	&lt;li&gt;rename it to authorized_keys&lt;/li&gt;
	&lt;li&gt;chmod authorized_keys to 600&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Step 3:  Test!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OK, you now have your private key on your Textdrive account, and the corresponding public key on your StrongSpace account. We are good to test.&lt;/p&gt;

&lt;p&gt;Go back to your Textdrive shell, and type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ssh -i ss SS_USERNAME@SS_USERNAME.strongspace.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should now log directly into your account without needing to enter a password.&lt;/p&gt;
&lt;p&gt;&lt;p style="font-weight: bold;"&gt;Notes:&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;If you already have an  keys on separate lines.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/04wLrlpjmVE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/ssh-access-to-strongspace-from-textdrive.html</feedburner:origLink></entry>
 
 <entry>
   <title>Script to Automate Wordpress Update</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/seG04cDLMI4/script-to-automate-wordpress-update.html" />
   <updated>2006-08-01T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/script-to-automate-wordpress-update</id>
   <content type="html">&lt;p&gt;If you are a Textdrive user, and you have one or more WordPress installations under your control, you might find the following BASH script to be of use. The script is fairly straightforward in that it manages the backup of your existing WordPress installation and database to StrongSpace, then it automatically downloads and extracts the latest version of WordPress.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Notes:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;If you do not have a StrongSpace account, then you will need to modify the script to change the safe storage of backups.&lt;/li&gt;
	&lt;li&gt;To take advantage of StrongSpace, you need to get the relevant SSH keys in place on both servers in order to be able to log into your StrongSpace account over SSH without a password.&lt;/li&gt;
	&lt;li&gt;Ensure that you have created both the &lt;b&gt;updates &lt;/b&gt;and &lt;b&gt;backups &lt;/b&gt;directories on your Textdrive account&lt;/li&gt;
	&lt;li&gt;WordPress has an upgrade script that sometimes needs to be run after the system software has been updated. This upgrade script may contain more than one step, and require confirmations or input from the administrator. For these reasons, I have not included that step in the automation script. Make sure you check to verify that the upgrade script is run if necessary.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;The Script:&lt;/b&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;&lt;span class="c"&gt;#!/usr/local/bin/bash  &lt;/span&gt;

&lt;span class="c"&gt;# Configuration&lt;/span&gt;
&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/users/home/username
&lt;span class="nv"&gt;TEMP_UPDATE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/updates
&lt;span class="nv"&gt;TEMP_BACKUP_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/backups  

&lt;span class="nv"&gt;LOCAL_WORDPRESS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/public_html/blog
&lt;span class="nv"&gt;WORDPRESS_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://foo.bar.net  

&lt;span class="nv"&gt;MYSQL_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wordpress_database
&lt;span class="nv"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;username
&lt;span class="nv"&gt;MYSQL_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password  

&lt;span class="nv"&gt;STRONGSPACE_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mailto:foo@foobar.strongspace.com&amp;quot;&lt;/span&gt;&amp;gt;foo@foobar.strongspace.com&amp;lt;/a&amp;gt;

&lt;span class="c"&gt;# No need to change this setting!&lt;/span&gt;
&lt;span class="nv"&gt;LATEST_WORDPRESS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://wordpress.org/latest.tar.gz

&lt;span class="c"&gt;# Prepare the directories&lt;/span&gt;
rm -rf &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TEMP_UPDATE_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/*
rm -rf &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TEMP_BACKUP_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/*  

&lt;span class="c"&gt;# Backup the current database and WP installation&lt;/span&gt;
mysqldump --opt --lock-tables&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; --skip-add-locks --user&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; --password&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MYSQL_PASS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MYSQL_DB&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; |gzip - &amp;amp;gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TEMP_BACKUP_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MYSQL_DB&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;.sql.gz
tar zcf &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TEMP_BACKUP_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/wordpress.tar.gz &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LOCAL_WORDPRESS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &amp;amp;gt;/dev/null  

&lt;span class="c"&gt;# Send the backups to StrongSpace&lt;/span&gt;
scp -i &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/.ssh/ss -r &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TEMP_BACKUP_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/* &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STRONGSPACE_USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:Backups/Wordpress/  

&lt;span class="c"&gt;# Get the latest Wordpress /usr/local/bin/curl -s ${LATEST_WORDPRESS} &amp;amp;gt; ${TEMP_UPDATE_DIR}/latest.tar.gz  &lt;/span&gt;

&lt;span class="c"&gt;# Unzip the wordpress file to a temp location, and update the main wordpress install&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TEMP_UPDATE_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
tar -xzvf latest.tar.gz
cp -R -f &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TEMP_UPDATE_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/wordpress/* &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LOCAL_WORDPRESS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Save all of that into /users/home/username/scripts, and replace all of the configuration options with your own parameters. You should probably be comfortable using the CLI before you start tinkering with this sort of thing - I'm not responsible for any fuckups on your part. Once you are happy with the script, all you need do is run it, and if all goes well, your installation will be backed up and updated all at once!&lt;/p&gt;

&lt;p&gt;Check to make sure that you don't need to run the upgrade script (run it if you do), and then you should be finished!&lt;/p&gt;

&lt;p&gt;I'm going to post more information relating to getting your Textdrive account working with your StrongSpace account soon - particularly with regards to automating backups.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/seG04cDLMI4" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/script-to-automate-wordpress-update.html</feedburner:origLink></entry>
 
 <entry>
   <title>Google Analytics</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/v3Qeu6zxKQ0/google-analytics.html" />
   <updated>2005-11-15T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/google-analytics</id>
   <content type="html">&lt;p&gt;Well, I first came across Google's free &lt;a href="http://googleblog.blogspot.com/2005/11/circle-of-analytics.html" title="Google Analytics"&gt;web analytics program&lt;/a&gt; the other day, and so far my impression is mixed. The idea of having a site analysis system provided by the top-notch design and development teams at Google is fantastic, however, it would appear that they have underestimated the popularity of the service somewhat.&lt;/p&gt;   &lt;p&gt;I added the tracking code to both &lt;a href="http://www.kyotee.co.uk" title="UK Business Directory"&gt;Kyotee&lt;/a&gt; and &lt;a href="http://bouldr.net"&gt;Bouldr&lt;/a&gt;'s holding page yesterday. Google's system recommended that I wait 12 hours for my data to show up (although in the help section, this period was given as 6 hours) - after which, my stats would be updated on an hourly basis. Ace.&lt;/p&gt;   &lt;p&gt;Unfortunately, it was not to be - after 15 hours, still nothing. Also, the help system seems to be a little out of sorts - it keeps displaying 404's when I click through links to get to different articles, then when I retry a second later, the link takes me to the correct document.&lt;/p&gt;   &lt;p&gt;It's like being given a wonderful present, then realising that it's broken, so you won't really be able to use it for a few days. &lt;/p&gt;   &lt;p&gt;Coincidentally, I feel a headache coming on.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/v3Qeu6zxKQ0" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/google-analytics.html</feedburner:origLink></entry>
 
 <entry>
   <title>The Obligatory First Post</title>
   <link href="http://feedproxy.google.com/~r/codebeef/~3/LlwLyZOX0yY/the-obligatory-first-post.html" />
   <updated>2005-11-10T00:00:00+00:00</updated>
   <id>http://codebeef.com/articles/the-obligatory-first-post</id>
   <content type="html">&lt;p&gt;Feeling good to finally be jumping on the biggest web Bandwaggon since BB's - though to be frank, I have nothing wothwhile to say just yet...&lt;/p&gt;&lt;p&gt;I have a couple of projects 'in the pipeline' at the mo, so maybe I could use this to make announcements or discuss their features and so on.&lt;/p&gt;&lt;p&gt;We'll see, I guess. &lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/codebeef/~4/LlwLyZOX0yY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://codebeef.com/articles/the-obligatory-first-post.html</feedburner:origLink></entry>
 
 
</feed>

