http://blog.monkeysthumb.org/ Monkey's thumb blog.monkeysthumb.org 2010-05-08T08:20:44Z http://blog.monkeysthumb.org/deleteput-links-break-your-rails-app 2010-05-08T08:20:44Z 2009-12-12T07:06:21Z Delete/put links break your Rails app <p>In Rails you can easily use the link_to helper in your templates to create links that will generate HTTP POST, PUT and DELETE requests when clicked. You can do this using simply setting the <tt>:method</tt> option, but this ease of use hides a very real problem.</p> <p>In Rails you can easily use the link_to helper in your templates to create links that will generate HTTP POST, PUT and DELETE requests when clicked. You can do this using simply setting the <tt>:method</tt> option, but this ease of use hides a very real problem.</p> <p><!--more--></p> <h2>The problem</h2> <p>These links only work for users with javascript enabled.</p> <p>Visitors without javascript enabled the links will actually take them to the show action of your controller (or a 404 if you con't have a show action), which won't be what you or they expect.</p> <p>It's easy not to notice this behaviour since mostly you test your app with javascript enabled.</p> <p>For example:</p> <pre><code class="ruby">link_to "Delete Image", @image, :method => :delete</code></pre> <p>Generates</p> <pre><code class="html">&lt;a href="/images/9" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href; var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);f.submit();return false;">Delete Image&lt;/a></code></pre> <p>Take note of all the javascript gymnastics to make this work.</p> <h2>The solution</h2> <p>The easy fix is to use the button_to helper instead.</p> <p>For example:</p> <pre><code class="ruby">button_to "Delete Image", @image, :method => :delete</code></pre> <p>Generates</p> <pre><code class="html">&lt;form method="post" action="/images/9" class="button-to"> &lt;input name="_method" type="hidden" value="put" /> &lt;input type="submit" value="Delete Image" /> &lt;/form></code></pre> <p>A nice little submit button with no javascript and no pain.</p> <p>This may even be a better user experience for all your users (with or without javascript) because the button will indicate to them that they are making a change (either updating or deleting something) rather than just visiting a link.</p> <h2>The solution (part II)</h2> <p>Of course perhaps you used the link_to helper because you wanted it to look like a standard link on the page (rather than a submit button).</p> <p>One possible solution would be to use CSS but it's actually very difficult to use CSS to make a submit button look exactly like (rather than just similar to) your other links across a range of browsers.</p> <p>Another is to use javascript to replace the form generated by the button_to helper with a link. Then javascript enabled visitors will see a link just like if you had used the link_to helper, and visitors without javascript enabled will see a button.</p> <p>If you are using jQuery then this can be achieved by adding the following javascript to your site.</p> <pre><code class="javascript">jQuery.fn.convert_submit_button_to_link = function () { this.each( function () { var button = jQuery(this); button. hide(). after(jQuery('&lt;a href="#">' + button.attr('value') + '&lt;/a>').attr('class', button.attr('class')).click(button.attr('onclick'))); }); return this; }; $(document).ready(function () { // Convert any input with the class 'submit-link' to a link $('input.submit-link').convert_submit_button_to_link(); };</code></pre> <p>And then any submit button with the class 'submit-link' will be replaced by a link that will submit the form.</p> <p>For example the submit button generated by the following would be converted to a link</p> <pre><code class="ruby">button_to "Delete Image", @image, :method => :delete, :class => 'submit-link'</code></pre> <p>So there are no excuses for using link_to for destroy/update actions.</p> <p>I will leave it as an exercise for the reader to convert this jQuery specific javascript to your favourite javascript library.</p> Joel Chippindale http://blog.monkeysthumb.org/trigger-integrity-builds-of-your-projects-with-cron 2010-05-05T22:26:50Z 2009-11-27T13:31:42Z Trigger Integrity builds with a cron job <p>I however prefer to poll my project's repositories for changes so that they do not need to be aware of my Integrity server.</p> <p><em><strong>Updated 21 Dec 2009:</strong> modified code to work with integrity v. 0.2.9</em></p> <p><a href="http://integrityapp.com/">Integrity</a> is a great little continuous integration server, even if it is a little rough around the edges.</p> <p>Out of the box Integrity expects that you will trigger all your builds using <a href="http://help.github.com/post-receive-hooks/">github's post receive hooks</a> - although you need to be aware of <a href="http://github.com/integrity/integrity/issues#issue/14">this bug</a> which means you have to miss the .git of the end of the project's git repository URI when setting this up.</p> <p>I however prefer to poll my project's repositories for changes so that they do not need to be aware of my Integrity server.</p> <p><!--more--> If you are using Integrity v0.2.9 or greater then this can be achieved by adding the following rake task to the Rakefile in your Integrity installation.</p> <pre><code class="ruby">desc "Will build the latest commit for any project that has already been built and the latest commit has not already been built" task :build_new_commits do require "init" Integrity.log("Checking for new commits at #{Time.now}") Integrity::Project.all.each do |project| # Don't build if project is just being set up, or a build of 'HEAD' is already outstanding or the latest commit has already # been built. unless project.blank? || project.last_build.commit.identifier == 'HEAD' || (head = Integrity::Repository.new(project.uri, project.branch, 'HEAD').head) == project.last_build.commit.identifier project.build(head) end end end</code></pre> <p>Then set up a cron job by adding the something like the following entry to your crontab. This will to automatically check every 2 minutes to see if there are any outstanding commits of your project to build. You will need to replace the /path/to/ section in each of the paths with appropriate values for your system.</p> <pre><code class="bash">*/2 * * * * cd /path/to/integrity && /path/to/ruby ./bin/rake build_new_commits >> /path/to/cron.log 2>$</code></pre> <p>Alternatively, if you are using for earlier versions of integrity</p> <ul> <li>0.2.0 or greater: use this <a href="http://gist.github.com/261005">rake task</a></li> <li>0.1.1 or greater: use <a href="http://github.com/bkoski/integrity-watcher">bkoski's integrity-watcher</a></li> </ul> <p>Or, if you want to add build triggers to git repositories not on github then take a look at <a href="http://morethanseven.net/2008/12/28/local-continuous-integration-integrity/">morethanseven's post commit hook</a>.</p> Joel Chippindale http://blog.monkeysthumb.org/cucumber-screenshot-gem 2010-05-05T22:26:50Z 2009-11-04T06:52:25Z Cucumber screenshot gem <p><a href="http://cukes.info/">Cucumber</a> is great for integration testing but when a feature fails for a web application you just get the content of the page spewed out onto the console.</p> <p>If only you could see a screenshot of the whole web page that produced the failure.</p> <p><a href="http://cukes.info/">Cucumber</a> is great for integration testing but when a feature fails for a web application you just get the content of the page spewed out onto the console.</p> <p>If only you could see a screenshot of the whole web page that produced the failure.</p> <p><!--more--> The good news for those of you on OS X is that you can.</p> <p>Just install my cucumber-screenshot gem.</p> <pre><code class="bash">gem install cucumber-screenshot</code></pre> <p>And follow the <a href="http://github.com/mocoso/cucumber-screenshot">set up instructions</a> to start snapping.</p> <p>Enjoy.</p> <p>If you are on another platform and want this functionality then feel free to change <a href="http://github.com/mocoso/cucumber-screenshot">the code</a>.</p> <p>Thanks go to <a href="http://jurisgalang.com/">Juris Galang</a> for writing the <a href="http://github.com/jurisgalang/snapurl">snapurl gem</a> (which actually handles making the screenshots) and to <a href="http://aslakhellesoy.com/">Aslak Hellesoy</a> and <a href="http://blog.mattwynne.net/">Matt Wynne</a> for their help and advice integrating this with Cucumber.</p> Joel Chippindale http://blog.monkeysthumb.org/tuning-mail-app-gmail-imap-integration 2010-05-05T22:26:50Z 2009-09-04T05:12:29Z Tuning Mail.app / Gmail IMAP integration <p>When setting up Mail.app on OS X to access your mail in your Gmail (or Google Apps) account via IMAP it is worth tweaking your 'Mailbox behaviours' and mailbox mappings to make them work together more smoothly.</p> <p>However there is conflicting advice on this (from <a href="http://mail.google.com/support/bin/answer.py?answer=78892" title="Recommended IMAP client settings">Gmail</a> and <a href="http://www.macosxhints.com/article.php?story=2008041016554622" title="A better Gmail IMAP to Mail.app sync">Mac OSX Hints</a> for example), so here's my definitive guide.</p> <p>When setting up Mail.app on OS X to access your mail in your Gmail (or Google Apps) account via IMAP it is worth tweaking your 'Mailbox behaviours' and mailbox mappings to make them work together more smoothly.</p> <p>However there is conflicting advice on this (from <a href="http://mail.google.com/support/bin/answer.py?answer=78892" title="Recommended IMAP client settings">Gmail</a> and <a href="http://www.macosxhints.com/article.php?story=2008041016554622" title="A better Gmail IMAP to Mail.app sync">Mac OSX Hints</a> for example), so here's my definitive guide.</p> <p><!--more--></p> <p>In this guide I assume you have already set up your Gmail account access via IMAP in Apple Mail following these clear instructions for <a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;answer=77663" title="Set up Gmail IMAP access on Mail 2.0">Mail 2.0</a> or <a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;answer=81379" title="Set up Gmail IMAP access on Mail 3.0">Mail 3.0</a>.</p> <p>In the guide below I will refer to changing your 'Mailbox behaviours' settings, you can find these by</p> <ol> <li>Open Preferences in Mail</li> <li>Select the 'Accounts' section</li> <li>Select your Gmail account</li> <li>Select 'Mailbox behaviours'</li> </ol> <p>I will also refer to configuring Mail to treat some of your IMAP mailboxes as 'special'. You can do this by</p> <ol> <li>Select the mailbox in your IMAP account you want to make 'special'.</li> <li>Select the 'Mailbox' menu</li> <li>Move the mouse over the 'Use This Mailbox For'</li> <li>Select what you want to use the mailbox for, i.e. 'Drafts', 'Sent', 'Trash', 'Junk'</li> </ol> <h2>Drafts</h2> <ul> <li>In 'Mailbox behaviours' tick 'Store draft messages on the server'</li> <li>Select the drafts mailbox in your IMAP account (probably [Googlemail]/Drafts) and set to be used as 'Drafts'.</li> </ul> <p>These settings ensure that drafts will be stored in your IMAP account and will appear in the standard 'Drafts' mailbox in Mail.</p> <h2>Sent Mail</h2> <ul> <li>In 'Mailbox behaviours' tick 'Store sent message on the server'</li> <li>Select the sent mail mailbox in your IMAP account (probably [Googlemail]/Sent Mail) and set to be used as 'Sent'.</li> </ul> <p>These settings ensure that sent mail will be stored in your IMAP account and will appear in the standard 'Sent' mailbox in Mail.</p> <h2>Junk</h2> <ul> <li>In 'Mailbox behaviours' <ul> <li>Tick 'Store junk messages on the server'</li> <li>For 'Delete junk mail when' select 'Never'</li> </ul> </li> <li>Select the junk mailbox in your IMAP account (probably [Googlemail]/Spam) and set to be used as 'Junk'.</li> <li>In Mail Preferences > Junk Mail <ul> <li>Tick 'Enable junk mail filtering'</li> <li>For 'When junk mail arrives', select move it to the Junk mailbox</li> </ul> </li> </ul> <p>These settings mean that you are using both Mail and Gmail's spam filters and that you will train them in parallel, i.e. when you mark mail as Junk / Not Junk the information will be passed back to Gmail and will improve their spam filtering too.</p> <p>I set the Junk mail to never be deleted because Gmail already does this after 30 days and set junk mail to be moved straight to the Junk mailbox so that it doesn't clutter my inbox (this matches the behaviour on Gmail too).</p> <p>Note: if you 'Erase Junk Mail' in Mail.app it will remove the mails currently in your junk mailbox from Mail's view of your junk mail box but not actually delete them on the server.</p> <h2>Trash</h2> <ul> <li>In 'Mailbox behaviours' <ul> <li>Tick 'Move deleted messages to the Trash mailbox'</li> <li>Tick 'Store deleted messages on the server'</li> <li>For 'Delete trash when' select 'Never'</li> </ul> </li> <li>Select the trash mailbox in your IMAP account (probably [Googlemail]/Bin) and set to be used as 'Trash'.</li> </ul> <p>These settings will ensure that mail you delete locally is marked as deleted in the IMAP server, and will leave the actual removal of deleted messages from your IMAP account up to GMail (30 days)</p> <h2>Notes</h2> <p>I don't use notes so I leave 'Store notes in Inbox' unticked in 'Mailbox behaviours'</p> <h2>Updated - 28 Sep 2009</h2> <p>I double checked storing sent mail on the server at Shad's suggestion (see comments below), and I have found that it no longer results in multiple copies of sent mail. I am not sure when this was fixed but I have updated the recommendations to suggest you store sent mail on the server as a result.</p> <p>I've also corrected the label on the Notes checkbox to 'Store notes in Inbox'.</p> Joel Chippindale http://blog.monkeysthumb.org/ruby-docs-on-os-x-with-fluid 2010-05-05T22:26:50Z 2009-06-22T12:56:33Z Ruby docs on OS X with Fluid <p>Wouldn't it be nice to have a neat little an application on your desktop which allows you to search and view ruby docs.</p> <p>Well it's just 4 easy steps away.</p> <p>Wouldn't it be nice to have a neat little an application on your desktop which allows you to search and view ruby docs.</p> <p>Well it's just 4 easy steps away.</p> <p><!--more--></p> <h2>Step 1: Install Fluid</h2> <p>Download and install <a href="http://fluidapp.com/">Fluid</a> a site specific browser for OS X, that enables you to turn a website into an application.</p> <h2>Step 2: Download the Rails Searchable API Doc</h2> <ul> <li>Visit <a href="http://railsapi.com/">Rails Searchable API Doc</a></li> <li>Press 'select gems' and decide which versions of Ruby, Rails and other common gems you want to include in your ruby docs application</li> <li>Click download</li> <li>Unpack the zip file you download and save it to '/Users/you/Library/Application Support/RubyDocs' say.</li> </ul> <p>I chose the 'Rails Searchable API Doc' because it includes a number of other ruby gems, has a good search function and supports keyboard shortcuts.</p> <p>Of course if you prefer a different rendering of the docs, e.g. <a href="http://noobkit.com/">Noobkit</a> and <a href="http://www.railsbrain.com/">RailsBrain</a> then you could download one of those instead.</p> <h2>Step 3: Download a nice icon</h2> <p>Download <a href="http://www.flickr.com/photos/conekt/">conekt's</a> excellent <a href="http://farm4.static.flickr.com/3392/3315357128_af7c165408_o_d.png">RubyDoc icon</a>.</p> <h2>Step 4: Make your application</h2> <p>Open Fluid</p> <ul> <li>Put the local URL of your docs, 'file:///Users/you/Library/Application%20Support/RubyDocs/index.html', say, in the URL field</li> <li>Put 'RubyDocs' in the name field</li> <li>Select 'Other' in the icon field and find your spiffy icon (downloaded in step 3)</li> <li>Press the create button.</li> </ul> <p>You're done. Enjoy.</p> Joel Chippindale http://blog.monkeysthumb.org/install-old-version-of-screen-using-mac-ports 2010-05-05T22:26:50Z 2009-06-11T05:14:43Z Install old version of screen using Mac Ports <p>The latest version of <a href="http://en.wikipedia.org/wiki/GNU_Screen">Screen</a> (version 4.0.3 port revision 3) that comes with MacPorts has a <a href="https://trac.macports.org/ticket/18235">number of issues</a>.</p> <p>Most annoying for me were that 'mate' and 'gitx' stopped working from the command line (with the errors 'mate: failed to establish connection with TextMate' and 'gitx: failed to establish connection with GitX' respectively).</p> <p>The screen port @4.0.3_1 (version 4.0.3 revision 1) is free of these problems and, with a little bit of work, you can install this version via MacPorts. The instructions below are based on Joe Horns' post, <a href="http://journal.bitshaker.com/articles/2007/10/20/install-old-versions-of-ports-using-macports/">install old versions of ports using MacPorts</a>.</p> <p>The latest version of <a href="http://en.wikipedia.org/wiki/GNU_Screen">Screen</a> (version 4.0.3 port revision 3) that comes with MacPorts has a <a href="https://trac.macports.org/ticket/18235">number of issues</a>.</p> <p>Most annoying for me were that 'mate' and 'gitx' stopped working from the command line (with the errors 'mate: failed to establish connection with TextMate' and 'gitx: failed to establish connection with GitX' respectively).</p> <p>The screen port @4.0.3_1 (version 4.0.3 revision 1) is free of these problems and, with a little bit of work, you can install this version via MacPorts. The instructions below are based on Joe Horns' post, <a href="http://journal.bitshaker.com/articles/2007/10/20/install-old-versions-of-ports-using-macports/">install old versions of ports using MacPorts</a>.</p> <p><!--more--></p> <h2>Instructions</h2> <ol> <li><p>Set up a local port repository. In the file /opt/local/etc/macports/sources.conf, add this line before the rsync line:</p> <p> <pre><code class="bash">file:///Users/Shared/dports</code></pre></p> <p> and create that directory.</p></li> <li><p>Install the old revision of the port into your local repository, <a href="http://trac.macports.org/browser/trunk/dports/sysutils/screen/Portfile?rev=45522">revision 45522</a> specifies screen port @4.0.3_1.</p> <p> <pre><code class="bash">cd /Users/Shared/dports &amp;&amp; svn co --revision 45522 \ http://svn.macports.org/repository/macports/trunk/dports/sysutils/screen/ \ sysutils/screen/</code></pre></p></li> <li><p>Run portindex so that ports now finds your new (old) version of Screen.</p> <p> <pre><code class="bash">portindex /Users/Shared/dports</code></pre></p></li> <li><p>Now you should be able to see two versions of the screen port by running</p> <p> <pre><code class="bash">port list screen</code></pre></p> <p> However, rather unhelpfully, they will both be listed as version @4.0.3.</p></li> <li><p>Install Screen</p> <p> <pre><code class="bash">sudo port install screen @4.0.3_1</code></pre></p> <p> and you should be up and running.</p></li> </ol> Joel Chippindale http://blog.monkeysthumb.org/refresh-data-from-production 2010-05-05T23:14:35Z 2008-11-30T08:15:36Z Refresh data from production <p>When working on web apps, it can really useful to be able to load production data into your development environment.</p> <p>When working on web apps, it can really useful to be able to load production data into your development environment.</p> <p><!--more--></p> <p>I am a sucker for anything that reduces typing so I put together a <a href="http://github.com/mocoso/mysql_tasks/tree/master">mysql_tasks</a> rails plugin for my MySQL backed applications which makes it as easy as</p> <pre><code class="bash">rake mysql:refresh_from_production</code></pre> <p>Which makes a tar gzipped snapshot of the production database, downloads it into my development box and loads it into my development environment.</p> <p>If you want to give it a go yourself then read these <a href="http://github.com/mocoso/mysql_tasks/tree/master/README.markdown">installation instructions for the mysql_tasks plugin</a>.</p> <p>This was inspired by <a href="http://www.nateclark.com/articles/2007/02/23/rails-rake-tasks-to-sync-your-remote-database-to-your-local-development-environment">the real Nate Clark</a>.</p> Joel Chippindale http://blog.monkeysthumb.org/code-beautifier-textmate-bundle 2010-05-05T22:26:50Z 2008-09-25T12:33:14Z Code Beautifier Textmate Bundle <p>Textmate's indent functionality does a passable job of formatting your code BUT there is a great deal of room for improvement.</p> <p>Inspired by the Paul Lutus's <a href="http://www.arachnoid.com/ruby/rubyBeautifier.html">ruby beautifier script</a> and Tim Burks's <a href="http://blog.neontology.com/posts/2006/05/10/beautiful-ruby-in-textmate">post on making it into a Textmate bundle</a> I've put together a <a href="http://github.com/mocoso/code-beautifier.tmbundle/tree/master">Code Beautifier Textmate bundle</a></p> <p>It only supports Ruby at present but does improve upon Textmate's indent functionality, in particular it is better at indenting multiline statements and cleans up white space.</p> <p>It's all hosted on <a href="http://github.com/">Github</a> so if you want to make improvements then please fork away.</p> <p>Textmate's indent functionality does a passable job of formatting your code BUT there is a great deal of room for improvement.</p> <p>Inspired by the Paul Lutus's <a href="http://www.arachnoid.com/ruby/rubyBeautifier.html">ruby beautifier script</a> and Tim Burks's <a href="http://blog.neontology.com/posts/2006/05/10/beautiful-ruby-in-textmate">post on making it into a Textmate bundle</a> I've put together a <a href="http://github.com/mocoso/code-beautifier.tmbundle/tree/master">Code Beautifier Textmate bundle</a></p> <p>It only supports Ruby at present but does improve upon Textmate's indent functionality, in particular it is better at indenting multiline statements and cleans up white space.</p> <p>It's all hosted on <a href="http://github.com/">Github</a> so if you want to make improvements then please fork away.</p> <p><!--more--></p> <h2>Installation</h2> <p>Run this:</p> <pre><code class="bash">cd ~/Library/Application\ Support/TextMate/Bundles git clone git://github.com/mocoso/code-beautifier.tmbundle.git Code\ Beautifier.tmbundle</code></pre> <p>Then select 'Bundles > Bundle Editor > Reload Bundles' from Textmate's menus</p> <h2>Updated on 21 May 2009</h2> <p>Changed the URL of the repository on GitHub to http://github.com/mocoso/code-beautifier.tmbundle/tree/master to fix a typo in the name (oops).</p> Joel Chippindale http://blog.monkeysthumb.org/screen-textmate-bundle 2010-05-05T22:26:50Z 2008-09-09T05:52:19Z Screen Textmate Bundle <p>When working on a rails project I usually have script/server, script/console and autotest all running in <a href="http://en.wikipedia.org/wiki/GNU_Screen">GNU Screen</a>. Jamie Flournoy has already described why using <a href="http://www.pervasivecode.com/blog/2007/06/12/gnu-screen-and-my-screenrc/">GNU screen is better than plain old Terminal Tabs</a>.</p> <p>I've put together a <a href="http://github.com/mocoso/screen.tmbundle/tree/master">Screen Textmate Bundle</a> to make it easy to configure and open per project screen sessions.</p> <p>When working on a rails project I usually have script/server, script/console and autotest all running in <a href="http://en.wikipedia.org/wiki/GNU_Screen">GNU Screen</a>. Jamie Flournoy has already described why using <a href="http://www.pervasivecode.com/blog/2007/06/12/gnu-screen-and-my-screenrc/">GNU screen is better than plain old Terminal Tabs</a>.</p> <p>I've put together a <a href="http://github.com/mocoso/screen.tmbundle/tree/master">Screen Textmate Bundle</a> to make it easy to configure and open per project screen sessions.</p> <p><!--more--></p> <h2>Installation</h2> <p>Run this:</p> <pre><code class="bash">cd ~/Library/Application\ Support/TextMate/Bundles git clone git://github.com/mocoso/screen.tmbundle.git Screen.tmbundle</code></pre> <h2>Set up your screen configuration for a project</h2> <p>Create a .screenrc file <em>in your project directory</em> if you want to specify a particular configuration for your project.</p> <p>For example for a Ruby on Rails project you might create a .screenrc file in your project directory like this</p> <pre><code class="bash"># Have the server running in screen 1 # # Stuff is used so that when you exit the stuff-ed program, you drop back # to the bash shell for that screen instead of immediately exiting that # screen. This is useful for "^c, up-arrow, enter" restarting of programs. screen -t server 1 stuff "script/server\012" # Have autotest running in screen 2 screen -t autotest 2 stuff "autotest\012" # Have the console running in screen 3 screen -t console 3 stuff "script/console\012" # Finally have a command line prompt at the project root in screen 4 screen -t project_root 4</code></pre> <h2>Usage</h2> <p>Use this bundle's 'Start Session' command (ctrl-shift-s) to start (or reconnect to) your project's screen session.</p> <p>If you have created a .screenrc file in your project directory then this will be used to initialize the new session.</p> <h2>Update (14th Sep 2008)</h2> <p>On <a href="http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/" title="Like Slime, For Vim">Jonathon Palardy's suggestion</a> I've added a 'Send to Screen' command (ctrl-alt-c) that copies selected text (or current line if no selection made) to your project's screen session. If you have multiple windows open in the session then it will paste to the currently selected window.</p> <h2>Update (22nd Jan 2009)</h2> <p>If you want similar functionality without learning screen then check out Nick Rutherford's <a href="http://blog.ardes.com/2009/1/22/rails-multi-terminal-launcher">Rails Workbench</a></p> Joel Chippindale http://blog.monkeysthumb.org/using-git-with-subversion-part-ii-practice 2010-05-05T22:26:50Z 2008-06-27T04:38:37Z Using Git with subversion: Part II (Practice) <p>More tips on how to use <a href="http://git.or.cz/" title="Git version control">Git</a> with a Subversion repository to get some of the Git goodness, local branches, <a href="http://ariejan.net/2008/04/23/git-using-the-stash/" title="Using Git stashes">stashes</a> and much more, without having to persuade everyone else on your project to migrate to Git</p> <p>If you don't already have git installed then see <a href="/2008/5/26/using-git-with-subversion-part-i-installation">part I (Installation)</a>.</p> <p>More tips on how to use <a href="http://git.or.cz/" title="Git version control">Git</a> with a Subversion repository to get some of the Git goodness, local branches, <a href="http://ariejan.net/2008/04/23/git-using-the-stash/" title="Using Git stashes">stashes</a> and much more, without having to persuade everyone else on your project to migrate to Git</p> <p>If you don't already have git installed then see <a href="/2008/5/26/using-git-with-subversion-part-i-installation">part I (Installation)</a>.</p> <p><!--more--></p> <h2>Clone you Subversion repository</h2> <p>Make a local clone of your subversion repository to work with.</p> <p><strong>Warning:</strong> Git does not support svn:externals but luckily you <a href="http://errtheblog.com/posts/50-vendor-everything">vendor everything</a> with <a href="http://www.rubyinside.com/advent2006/12-piston.html">piston</a>, don't you? If not then various people have written up <a href="http://blog.alieniloquent.com/2008/03/08/git-svn-with-svnexternals/">hacks for managing svn:externals</a> none of which are ideal but they will get you started.</p> <p>Assuming you use a standard Subversion repository layout (with /trunk, /branches etc.) then this is as easy as</p> <pre><code class="bash">git-svn clone http://svn.foo.org/project/trunk</code></pre> <h2>Tweak your local Git repository</h2> <p>There are a couple more things that you should do to the repository before beginning work</p> <p>Firstly, tell Git about the files that Subversion ignores, using:</p> <pre><code class="bash">git svn show-ignore >> .git/info/exclude</code></pre> <p>This appears to work for some projects/Subversion installations and not others. If it doesn't work you'll need to create .git/info/exclude file in the project and add file patterns to exclude by hand.</p> <p>Secondly, recreate any empty folders which are required by the project e.g. /log. You need to do this because Git does not track empty directories.</p> <p>Now you are ready to go.</p> <h2>Get to work</h2> <ol> <li><p>Make your changes</p> <p>Make changes to the code base in just the same way as you would with Subversion</p></li> <li><p>Commit your changes to your local master branch</p> <p>Unless you have been working with <a href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html">local branches</a> this is easy as.</p> <p><pre><code class="bash">git commit -a</code></pre></p> <p>Which will commit all your changes to your local Git repository.</p> <p>If you have added or removed files you will also need to use <a href="http://www.kernel.org/pub/software/scm/git/docs/git-add.html">git add</a> or <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rm.html">git rm</a> to ensure all your changes are committed.</p></li> <li><p>Update your local repository from Subversion</p> <p><pre><code class="bash">git svn rebase</code>></pre></p> <p>This brings your local Git repository up to date with the central Subversion repository</p> <p>It works just like <a href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html">git rebase</a> in that it rewinds your local commits, applies the latest changes from subversion, and then replays your local commits over the top. If there are merge issues you will be warned about them here.</p></li> <li><p>Push your local commits back into subversion</p> <p><pre><code class="bash">git svn dcommit</code></pre></p> <p>This applies each of your local commits in turn to the subversion repository.</p></li> <li><p>Repeat (go back to step 1.)</p></li> </ol> <h2>Further reading</h2> <p>Now you've got started here are a couple of good resources for when you get stuck</p> <ul> <li><a href="http://www.kernel.org/pub/software/scm/git/docs/user-manual.html">Git manual</a></li> <li><a href="http://www.sourcemage.org/Git_Guide">Quick Git guide</a></li> <li><a href="http://git.or.cz/course/svn.html">Git - SVN Crash Course</a></li> <li><a href="http://zrusin.blogspot.com/2007/09/git-cheat-sheet.html">Git cheat sheet</a></li> </ul> <p>Best of luck.</p> Joel Chippindale http://blog.monkeysthumb.org/csv-templating-made-easy-in-rails 2010-05-05T23:20:58Z 2008-06-27T04:40:39Z CSV templating made easy in Rails <p><a href="http://github.com/econsultancy/csv_builder/tree/master">CSV Builder</a> is a simple little Rails (v2.1) plugin that makes it easy to write templates to generate CSV formatted output from your Rails application.</p> <p><a href="http://github.com/econsultancy/csv_builder/tree/master">CSV Builder</a> is a simple little Rails (v2.1) plugin that makes it easy to write templates to generate CSV formatted output from your Rails application.</p> <p><!--more--></p> <p>It does this by providing a little bit of plumbing gubbins to make a custom template handler from the <a href="http://fastercsv.rubyforge.org">FasterCSV gem</a>.</p> <p>So if you want to export data in CSV format from your rails app then install it like this</p> <pre><code class="bash">sudo gem install fastercsv ./script/plugin install git://github.com/econsultancy/csv_builder.git</code></pre> <p>This plugin was developed as part of project that I have been working on with <a href="http://www.e-consultancy.com">Econsultancy.com</a>.</p> Joel Chippindale http://blog.monkeysthumb.org/using-git-with-subversion-part-i-installation 2010-05-05T22:26:50Z 2008-05-26T04:56:01Z Using Git with Subversion: Part I (Installation) <p>You can use <a href="http://git.or.cz/" title="Git version control">Git</a> with a Subversion repository to get some of the Git goodness, local branches, <a href="http://ariejan.net/2008/04/23/git-using-the-stash/" title="Using Git stashes">stashes</a> and much more, without having to persuade everyone else on your project to migrate to Git</p> <p>You can use <a href="http://git.or.cz/" title="Git version control">Git</a> with a Subversion repository to get some of the Git goodness, local branches, <a href="http://ariejan.net/2008/04/23/git-using-the-stash/" title="Using Git stashes">stashes</a> and much more, without having to persuade everyone else on your project to migrate to Git</p> <p><!--more--></p> <h2>Install Git</h2> <p>You need to install git-svn first, with <a href="http://www.macports.org/">MacPorts</a> this is as easy as</p> <pre><code class="bash">sudo port install git-core +svn +bash_completion</code></pre> <p>And then to enable bash completion (thanks to <a href="http://effectif.com/2008/4/24/easy-git-svn-for-rails">Graham Ashton</a> for this tip)</p> <pre><code class="bash">cp /opt/local/etc/bash_completion.d/git ~/.git-bash-completion.sh echo '[ -f ~/.git-bash-completion.sh ] &amp;&amp; . ~/.git-bash-completion.sh' &gt;&gt; ~/.profile . ~/.profile</code></pre> <p>And for those without macports here are some <a href="http://git.or.cz/gitwiki/Installation">installation instructions</a></p> <h2>TextMate integration</h2> <p>If you use <a href="http://macromates.com/">TextMate</a> then install the <a href="http://blog.macromates.com/2008/git-bundle/">Git Bundle</a></p> <p>And you can set TextMate as the editor for git commit messages by adding the following to ~/.profile</p> <pre><code class="bash">export GIT_EDITOR="mate -w"</code></pre> <h2>Basic git configuration</h2> <p>You should tell git who you are.</p> <pre><code class="bash">git config --global user.name 'your name*' git config --global user.email 'your.email.address@foo.bar'</code></pre> <p>If you are on OS X, then tell git to ignore .DSStore files in all your projects.</p> <pre><code class="bash">git config --global core.excludesfile .gitexcludes</code></pre> <p>And create a file ~/.gitexcludes with '.DSStore' in it.</p> <p>This all you need to configure but there's much more you can do with git config e.g. <a href="http://jbowes.dangerouslyinc.com/2006/12/19/my-gitconfig/">aliases for git commands</a> if you want to save those typing fingers.</p> <h2>Coming soon</h2> <p><a href="/2008/6/27/using-git-with-subversion-part-ii-practice">Using Git with Subversion - Part II (Practice)</a></p> Joel Chippindale http://blog.monkeysthumb.org/select-in-in-rails 2010-05-05T22:26:50Z 2008-03-13T06:44:38Z 'SELECT IN' in rails <p><code>#find</code> supports select in conditions in just the way you would expect, so</p> <pre><code class="ruby">Model.find(:all, :conditions => ["attribute IN (?)", [1,2,3]])</code></pre> <p>generates</p> <pre><code class="sql">SELECT * FROM models WHERE (attribute IN (1,2,3))</code></pre> <p>for MySQL.</p> Joel Chippindale http://blog.monkeysthumb.org/web-apps-on-your-desktop 2010-05-07T05:17:31Z 2008-03-11T06:42:47Z Web apps on your desktop <p><a href="http://fluidapp.com/">Fluid</a> is a site specific browser for OS X, that lets you can take the web apps that you use all the time out of your browser and on to the desktop.</p> <p>I've been using it with Gmail to give it's own application window, dock icon etc. on my desktop rather than it just being lost amongst the 101 other tabs I have open.</p> <p><a href="http://fluidapp.com/">Fluid</a> is a site specific browser for OS X, that lets you can take the web apps that you use all the time out of your browser and on to the desktop.</p> <p>I've been using it with Gmail to give it's own application window, dock icon etc. on my desktop rather than it just being lost amongst the 101 other tabs I have open.</p> <p><!--more--></p> <p>If you use it with Gmail I recommend you install Todd Ditchendorf's <a href="http://www.ditchnet.org/wp/2008/03/05/fluid-gmail-userscript/">user script</a> to stop a gmail popping up a blank window when you click on an external link.</p> Joel Chippindale http://blog.monkeysthumb.org/moremoney-gem 2010-05-07T05:17:31Z 2008-02-29T06:28:44Z MoreMoney gem <p>The <a href="http://dist.leetsoft.com/api/money/">Money gem</a> is a great little utility for representing money in ruby.</p> <p>However it's formatting rules assume that the currency symbol will be a dollar ($) which is makes it far less useful for those of us who need to display other currencies, euros, pounds sterling (£) and yen (¥) to name a few.</p> <p>The <a href="http://dist.leetsoft.com/api/money/">Money gem</a> is a great little utility for representing money in ruby.</p> <p>However it's formatting rules assume that the currency symbol will be a dollar ($) which is makes it far less useful for those of us who need to display other currencies, euros, pounds sterling (£) and yen (¥) to name a few.</p> <p><!--more--></p> <p>Luckily Paolo Negri has come to the rescue with his <a href="http://moremoney.rubyforge.org/">More Money gem</a> which has all the goodness of the original money gem (configurable currencies and exchange rates) with added support for international currencies.</p> <p>Installing it is as easy as</p> <pre><code class="bash">gem install more_money</code></pre> Joel Chippindale http://blog.monkeysthumb.org/select-helper-methods 2010-05-05T22:26:50Z 2008-02-22T06:32:30Z Select helper methods <p><em>Shining through</em> has written an invaluable guide to the <a href="http://shiningthrough.co.uk/blog/show/6">ruby on rails select helper methods</a>.</p> <p>Now if only someone would turn these into a documentation patch for rails.</p> Joel Chippindale http://blog.monkeysthumb.org/comix-influx 2010-05-07T05:17:31Z 2008-02-19T06:36:07Z Comix influx <p>I am very pleased to see that there's a bit of a buzz building around Stephen Bett's most excellent project <a href="http://comixinflux.com/">Comix Influx</a>.</p> <p>I am very pleased to see that there's a bit of a buzz building around Stephen Bett's most excellent project <a href="http://comixinflux.com/">Comix Influx</a>.</p> <p><!--more--></p> <p><a href="http://paulgravett.com/articles/119_influx/119_influx.htm">Stephen's interview with Paul Gravett</a> explains more about this collaborative comics translation site.</p> <p><strong>Disclosure:</strong> I am a friend of Stephen's and a contributor to the Comix Influx code base.</p> Joel Chippindale http://blog.monkeysthumb.org/exception-notifier 2010-05-07T05:29:36Z 2008-02-02T06:38:08Z Exception notifier <p>Once installed the <a href="http://agilewebdevelopment.com/plugins/exception_notifier">exception notifier plugin</a> will send emails to your whenever your application raises an exception.</p> <p>It's a sinch to install making it no brainer for low/medium traffic rails apps.</p> <p>Once installed the <a href="http://agilewebdevelopment.com/plugins/exception_notifier">exception notifier plugin</a> will send emails to your whenever your application raises an exception.</p> <p>It's a sinch to install making it no brainer for low/medium traffic rails apps.</p> <p><!--more--></p> <ol> <li><p>Install exception notifier</p> <p> <pre><code class="bash">script/plugin install \ http://dev.rubyonrails.org/svn/rails/plugins/exception_notification/</code></pre></p></li> <li><p>Configure by adding to the list of email address you want to receive notifications your production environment</p> <p> <pre><code class="ruby">ExceptionNotifier.exception_recipients = %w(foo@bar.com) ExceptionNotifier.sender_address = %w(exception.notifier@bar.com)</code></pre></p></li> </ol> <p>Deploy and that's it, you're done.</p> <h2>Update - 11 Feb 08</h2> <p>Edge rails changeset <a href="http://dev.rubyonrails.org/changeset/8669">8669</a> breaks the plugin but Lourens has posted a <a href="http://blog.methodmissing.com/2008/2/4/exception-notification-and-edge">neat fix</a>.</p> Joel Chippindale http://blog.monkeysthumb.org/taking-rails-to-the-masses 2010-05-05T22:26:50Z 2008-02-01T06:40:05Z Taking rails to the masses <p>Tom Stuart, has been doing his bit to make Rails a household name with <a href="http://www.guardian.co.uk/technology/2007/dec/13/opensource.software">this piece on the release of 2.0</a> in the Guardian today.</p> Joel Chippindale http://blog.monkeysthumb.org/php-is-dead-long-live-ruby 2010-05-07T05:29:36Z 2007-12-13T06:41:01Z PHP is dead, long live ruby <p>I finally got around to deploying the rails port of my site <a href="http://www.prepfortests.com/">PrepForTests.com</a> this week.</p> <p>Moving it from PHP/Drupal to Ruby on Rails was surprisingly painless and now I can enjoy working on it rather than putting off new features.</p> <p>And I don't think I'll ever write another line of PHP again. Never go back.</p> <p>I finally got around to deploying the rails port of my site <a href="http://www.prepfortests.com/">PrepForTests.com</a> this week.</p> <p>Moving it from PHP/Drupal to Ruby on Rails was surprisingly painless and now I can enjoy working on it rather than putting off new features.</p> <p>And I don't think I'll ever write another line of PHP again. Never go back.</p> <p><!--more--></p> <h2>Update - a while later</h2> <p>Of course it wasn't long before I found myself ditching <a href="http://mephistoblog.com/">Mephisto</a> (Ruby) as a platform for this blog and switching to <a href="http://wordpress.org/">WordPress</a> (PHP), I'll leave you to draw your own conclusions.</p> Joel Chippindale