<?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:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>theAdmin.org - Ruby on Rails and Redmine</title>
 
 <updated>2009-11-04T10:24:31-08:00</updated>
 <id>http://theadmin.org</id>
 <author>
   <name>Eric Davis</name>
   <email>edavis@littlestreamsoftware.com</email>
 </author>

 
 <geo:lat>45.49106</geo:lat><geo:long>-122.803594</geo:long><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.0/" /><logo>http://www.feedburner.com/fb/images/pub/fb_pwrd.gif</logo><link rel="self" href="http://feeds.feedburner.com/theAdmin" type="application/atom+xml" /><feedburner:emailServiceId>theAdmin</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FtheAdmin" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FtheAdmin" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FtheAdmin" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/theAdmin" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FtheAdmin" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FtheAdmin" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FtheAdmin" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
   <title>Launching the Little Stream Software Blog</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/D5tKo0ivxtk/launching-the-little-stream-software-blog" />
   <updated>2009-11-04T00:00:00-08:00</updated>
   <id>http://theadmin.org/articles/2009/11/04/launching-the-little-stream-software-blog</id>
   <content type="html">&lt;p&gt;I've been writing about my business, Little Stream Software, here for two years now.  This has been good but I've been losing focus on the technical content here, which has caused me to doubt many of my new post ideas.  So to keep things simple, I've created a new blog for my business topics, &lt;a href="http://blog.littlestreamsoftware.com"&gt;the Little Stream Software Blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm going to be covering my experiences that I've had from running a one person Ruby on Rails consultancy.  Some topic ideas I'm thinking about are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managing customers&lt;/li&gt;
&lt;li&gt;How to price your products and services&lt;/li&gt;
&lt;li&gt;Working with other contractors&lt;/li&gt;
&lt;li&gt;Finding time to do business development while you still code&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I have two posts up right now; &lt;a href="http://blog.littlestreamsoftware.com/articles/new-contractor-questions"&gt;New Contractor Questions&lt;/a&gt; and &lt;a href="http://blog.littlestreamsoftware.com/articles/how-to-bring-in-new-sales-in-slow-times"&gt;How to bring in new sales in slow times&lt;/a&gt; and am planning to write to it regularly.  If you enjoy the content, please &lt;a href="http://feeds.feedburner.com/LittleStreamSoftwareBlog"&gt;subscribe&lt;/a&gt; to the RSS feed.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://theadmin.org"&gt;theAdmin.org&lt;/a&gt; will still be where to get my technical content about &lt;a href="http://www.rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt; and &lt;a href="http://www.redmine.org"&gt;Redmine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Eric Davis&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=D5tKo0ivxtk:DhttQkTDCHw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=D5tKo0ivxtk:DhttQkTDCHw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=D5tKo0ivxtk:DhttQkTDCHw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=D5tKo0ivxtk:DhttQkTDCHw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=D5tKo0ivxtk:DhttQkTDCHw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=D5tKo0ivxtk:DhttQkTDCHw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=D5tKo0ivxtk:DhttQkTDCHw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/D5tKo0ivxtk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/11/04/launching-the-little-stream-software-blog</feedburner:origLink></entry>
 
 <entry>
   <title>Converting a Redmine plugin to a Gem</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/3XdrrIphnCg/converting-a-redmine-plugin-to-a-gem" />
   <updated>2009-10-15T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/10/15/converting-a-redmine-plugin-to-a-gem</id>
   <content type="html">&lt;p&gt;A lot of Rails plugins are starting to be released as RubyGems.  I've found using RubyGems to manage plugins has been easy and have several advantages over a standard Rails plugin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;built in versioning&lt;/li&gt;
&lt;li&gt;easy installation - no more installing plugins to the wrong directory&lt;/li&gt;
&lt;li&gt;pick a specific version to use&lt;/li&gt;
&lt;li&gt;not having to add a bunch of code to the application tree&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Since I've created several dozen plugins for Redmine, I decided to start releasing them as RubyGems.  I hoping this will make it easier for the user to install and upgrade them.  After spending a night converting four plugins, I found I was running the same commands again and again.  That meant, I could script it for the remaining 29 plugins.&lt;/p&gt;

&lt;h3&gt;The process&lt;/h3&gt;

&lt;p&gt;After a few tweaks, I ended up with a simple procedural script that would:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checkout the master branch&lt;/li&gt;
&lt;li&gt;Update the master branch from origin&lt;/li&gt;
&lt;li&gt;Create a new branch called 'gem' to work in&lt;/li&gt;
&lt;li&gt;Add a configuration for jeweler to the Rakefile&lt;/li&gt;
&lt;li&gt;Add a VERSION file based on the version used in &lt;code&gt;init.rb&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Move the existing &lt;code&gt;init.rb&lt;/code&gt; to &lt;code&gt;rails/init.rb&lt;/code&gt; so Rails will load it from the gem&lt;/li&gt;
&lt;li&gt;Generate a valid gemspec for the plugin&lt;/li&gt;
&lt;li&gt;Install the new gem&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Finally, I would review the 'gem' branch and test out the newly minted gem in Redmine.  If something went wrong, the entire 'gem' branch could be destroyed with &lt;code&gt;git branch -D gem&lt;/code&gt;.  This let me finish converting the rest of the plugins in just a couple of hours.&lt;/p&gt;

&lt;h3&gt;The script&lt;/h3&gt;

&lt;p&gt;This script is still Redmine specific (how it parses the version and description) but it could easily be adapted to work with any Rails plugin.  I've also shared this as a &lt;a href="http://gist.github.com/211054"&gt;Gist&lt;/a&gt;, so feel free to fork and modify it there.  Let me know if you used it and how it worked for you.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# Usage:&lt;/span&gt;
&lt;span class="c1"&gt;#  ruby plugin_to_gem.rb my_plugin_directory&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;fileutils&amp;#39;&lt;/span&gt;

&lt;span class="vi"&gt;@plugin_dir&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="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="vi"&gt;@plugin_name&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="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rakefile_content&lt;/span&gt;
  &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;TODO&amp;#39;&lt;/span&gt;
  &lt;span class="n"&gt;redmine_init_content&lt;/span&gt; &lt;span class="o"&gt;=&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;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;init.rb&amp;#39;&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;redmine_init_content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/description (.*$)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&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="s2"&gt;&amp;quot;&amp;#39;&amp;quot;&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="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;quot;&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="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;EORAKE&lt;/span&gt;
&lt;span class="sh"&gt;begin&lt;/span&gt;
&lt;span class="sh"&gt;  require &amp;#39;jeweler&amp;#39;&lt;/span&gt;
&lt;span class="sh"&gt;  Jeweler::Tasks.new do |s|&lt;/span&gt;
&lt;span class="sh"&gt;    s.name = &amp;quot;#{@plugin_name}&amp;quot;&lt;/span&gt;
&lt;span class="sh"&gt;    s.summary = &amp;quot;#{description}&amp;quot;&lt;/span&gt;
&lt;span class="sh"&gt;    s.email = &amp;quot;edavis@littlestreamsoftware.com&amp;quot;&lt;/span&gt;
&lt;span class="sh"&gt;    s.homepage = &amp;quot;https://projects.littlestreamsoftware.com/projects/TODO&amp;quot;&lt;/span&gt;
&lt;span class="sh"&gt;    s.description = &amp;quot;#{description}&amp;quot;&lt;/span&gt;
&lt;span class="sh"&gt;    s.authors = [&amp;quot;Eric Davis&amp;quot;]&lt;/span&gt;
&lt;span class="sh"&gt;    s.rubyforge_project = &amp;quot;#{@plugin_name}&amp;quot; # TODO&lt;/span&gt;
&lt;span class="sh"&gt;    s.files =  FileList[&lt;/span&gt;
&lt;span class="sh"&gt;                        &amp;quot;[A-Z]*&amp;quot;,&lt;/span&gt;
&lt;span class="sh"&gt;                        &amp;quot;init.rb&amp;quot;,&lt;/span&gt;
&lt;span class="sh"&gt;                        &amp;quot;rails/init.rb&amp;quot;,&lt;/span&gt;
&lt;span class="sh"&gt;                        &amp;quot;{bin,generators,lib,test,app,assets,config,lang}/**/*&amp;quot;,&lt;/span&gt;
&lt;span class="sh"&gt;                        &amp;#39;lib/jeweler/templates/.gitignore&amp;#39;&lt;/span&gt;
&lt;span class="sh"&gt;                       ]&lt;/span&gt;
&lt;span class="sh"&gt;  end&lt;/span&gt;
&lt;span class="sh"&gt;  Jeweler::GemcutterTasks.new&lt;/span&gt;
&lt;span class="sh"&gt;  Jeweler::RubyforgeTasks.new do |rubyforge|&lt;/span&gt;
&lt;span class="sh"&gt;    rubyforge.doc_task = &amp;quot;rdoc&amp;quot;&lt;/span&gt;
&lt;span class="sh"&gt;  end&lt;/span&gt;
&lt;span class="sh"&gt;rescue LoadError&lt;/span&gt;
&lt;span class="sh"&gt;  puts &amp;quot;Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com&amp;quot;&lt;/span&gt;
&lt;span class="sh"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;EORAKE&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;FileUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@plugin_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:verbose&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="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;dir&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rake clean&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git status&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git checkout master&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git merge origin/master&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git checkout -b gem&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# Rakefile&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="s1"&gt;&amp;#39;Rakefile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;a&amp;#39;&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rakefile_content&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;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git commit -am &amp;quot;Updated rakefile for jeweler&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# VERSION&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="s1"&gt;&amp;#39;VERSION&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;w&amp;#39;&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;version_file&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;redmine_init_content&lt;/span&gt; &lt;span class="o"&gt;=&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;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;init.rb&amp;#39;&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;redmine_init_content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/version (.*$)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$1&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="s2"&gt;&amp;quot;&amp;#39;&amp;quot;&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="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;quot;&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="n"&gt;version_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git add VERSION&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git commit -am &amp;quot;Added Version file&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# Rails GemPlugin init.rb&lt;/span&gt;
  &lt;span class="no"&gt;FileUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mkdir_p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rails&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git mv init.rb rails/init.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&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="s1"&gt;&amp;#39;init.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;w&amp;#39;&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;init_file&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;init_file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;require File.dirname(__FILE__) + &amp;quot;/rails/init&amp;quot;&amp;#39;&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;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git add init.rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git commit -am &amp;quot;Added init file for Rails GemPlugin&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



  &lt;span class="c1"&gt;# Gemspec&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rake gemspec&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;git add &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@plugin_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.gemspec&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git commit -am &amp;quot;Added generated gemspec&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# Install to test&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rake install&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# Back to master to allow merging&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git checkout master&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Eric Davis&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=3XdrrIphnCg:WkQ9F8WAFZs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=3XdrrIphnCg:WkQ9F8WAFZs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=3XdrrIphnCg:WkQ9F8WAFZs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=3XdrrIphnCg:WkQ9F8WAFZs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=3XdrrIphnCg:WkQ9F8WAFZs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=3XdrrIphnCg:WkQ9F8WAFZs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=3XdrrIphnCg:WkQ9F8WAFZs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/3XdrrIphnCg" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/10/15/converting-a-redmine-plugin-to-a-gem</feedburner:origLink></entry>
 
 <entry>
   <title>Now Jekyll Powered</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/QNgHSkc5UyY/now-jekyll-powered" />
   <updated>2009-09-30T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/09/30/now-jekyll-powered</id>
   <content type="html">&lt;p&gt;I've just migrated &lt;a href="http://theadmin.org"&gt;theAdmin.org&lt;/a&gt; to the &lt;a href="http://github.com/mojombo/jekyll/tree/master"&gt;Jekyll&lt;/a&gt; engine.  I was running on &lt;a href="http://mephistoblog.com/"&gt;Mephisto&lt;/a&gt; but switched because Mephisto's bugs were starting to get in the way of actual writing.  All of the comments have been converted to &lt;a href="http://disqus.com/"&gt;Disqus&lt;/a&gt; but I still have some features to add before the migration is complete.  If you notice anything wrong or find a 404 page, please file a &lt;a href="https://projects.littlestreamsoftware.com/projects/theadmin/issues"&gt;bug report&lt;/a&gt; for me or leave a comment here.  Thanks.&lt;/p&gt;

&lt;p&gt;Eric Davis&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QNgHSkc5UyY:CmxYwr9nsIw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QNgHSkc5UyY:CmxYwr9nsIw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=QNgHSkc5UyY:CmxYwr9nsIw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QNgHSkc5UyY:CmxYwr9nsIw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=QNgHSkc5UyY:CmxYwr9nsIw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QNgHSkc5UyY:CmxYwr9nsIw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=QNgHSkc5UyY:CmxYwr9nsIw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/QNgHSkc5UyY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/09/30/now-jekyll-powered</feedburner:origLink></entry>
 
 <entry>
   <title>MealEtte Tool Review - 2009 Rails Rumble</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/66C4JIzK92o/mealette-tool-review-2009-rails-rumble" />
   <updated>2009-08-26T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/08/26/mealette-tool-review-2009-rails-rumble</id>
   <content type="html">&lt;p&gt;&lt;a href="http://theadmin.org/assets/2009/8/26/mealette.png" class="float-right"&gt;
  &lt;img src="http://theadmin.org/assets/2009/8/26/mealette_thumb.png" alt="MealEtte" /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This past weekend I participated in the 2009 &lt;a href="http://r09.railsrumble.com"&gt;Rails Rumble&lt;/a&gt; where I built &lt;a href="http://mealette.com/"&gt;MealEtte&lt;/a&gt; (a combination of Meal and Roulette).  The purpose of MealEtte is:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Ever wasted more than 5 minutes figuring out what to eat for dinner tonight? MealEtte is for you. (If you haven’t wasted any time, please let me in on your secret.)&lt;/p&gt;

&lt;p&gt;MealEtte is designed to take the guesswork out of meal planning. By entering your Recipes you’ll have access to the MealEtte Roulette O’matic. Using sophisticated computer algorithms, artificial intelligence, and computer-geekery the Roulette O’matic is able to pick random meals for your consumption.&lt;/p&gt;

&lt;p&gt;So sit down, get hungry, and spin the wheel.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I entered the Rumble in order to learn about some new tools in the Rails community that I haven't had a chance to use yet.  And learn I did.  Here's a short list of my favorites, the full list is available on my &lt;a href="http://r09.railsrumble.com/teams/team-scope-creep"&gt;team&lt;/a&gt; page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://github.com/justinfrench/formtastic/tree/master"&gt;formtastic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/binarylogic/searchlogic/tree/master"&gt;searchlogic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/binarylogic/authlogic/tree/master"&gt;authlogic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/josevalim/inherited_resources/tree/master"&gt;inherited_resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/neerajdotname/admin_data/tree/master"&gt;admin_data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/rsl/stringex/tree/master"&gt;stringex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://raphaeljs.com/"&gt;Raphael&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://reductivelabs.com/products/puppet/"&gt;puppet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/37signals/fast_remote_cache/tree/master"&gt;fast_remote_cache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.thoughtbot.com/projects/shoulda/"&gt;shoulda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mocha.rubyforge.org/"&gt;mocha&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/flogic/object_daddy/tree/master"&gt;object_daddy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/grosser/parallel_specs/tree/master"&gt;parallel_specs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/ffmike/BigOldRailsTemplate/tree/master"&gt;BigOldRailsTemplate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If I had to pick my favorite three new tools, they would be:&lt;/p&gt;

&lt;h3&gt;Raphael&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://raphaeljs.com/"&gt;Raphael&lt;/a&gt; is a JavaScript library that makes working with SVG easy, which I used to animate the roulette wheel.  I ended up with about 50 lines of code to draw a SVG dynamically, animate the wheel spinning, and to get a random recipe from the Rails backend.  Here's a shortened version of function, if you want to see the full function it can be downloaded from &lt;a href="http://mealette.com/"&gt;MealEtte&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;    &lt;span class="nx"&gt;initialize_spinner&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;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ... options initialization removed ...&lt;/span&gt;

        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Raphael&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
              &lt;span class="c1"&gt;// ... connect to the Rails backend ...&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;rotation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2300&lt;/span&gt;&lt;span class="p"&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="c1"&gt;// ... popup a facebox lightbox with the results&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&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;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Here's a quick walk through of the main Raphael functions I used in the animation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;var R = Raphael()&lt;/code&gt; creates a SVG container at a specific DOM id that is 500x500 pixels.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;var img = R.image(src, -300, 000, 800, 800);&lt;/code&gt; takes the url of the roulette image and embeds it into the container as a 800x800 image.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$(opts.trigger).click()&lt;/code&gt; binds to the "Spin Wheel" link which connects to the Rails backend and also starts the Raphael animation.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;value += Math.floor(Math.random()*180) + 180;&lt;/code&gt; adds a random number of how many degrees to spin the wheel.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;img.animate({rotation: value}, 2300, function()&lt;/code&gt; controls the animation of the image, in this case to rotate it a specific number of degrees over 2.3 seconds (2300 milliseconds).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I was very happy with using Raphael.  I'm still working out how to get the animation smoother but Raphael was able to make it easy for me to simulate animation without having to use Flash.&lt;/p&gt;

&lt;h3&gt;inherited_resources&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;inherited_resources&lt;/code&gt; is a Rails plugin that creates resource controllers.  Instead of having to duplicate the standard &lt;code&gt;Object.new&lt;/code&gt;, &lt;code&gt;respond_to&lt;/code&gt;, &lt;code&gt;format.html&lt;/code&gt; that is common in Rails applications, you just have to inherit the InherietedResources class and it will setup the 7 standard Rails actions for you.  It includes a metric ton of hooks and ways to override it's behavior.  For example, I added a simple Content resource to MealEtte in order to post updates right to the site.  Additionally, I wanted to use &lt;code&gt;will_paginate&lt;/code&gt; to limit the amount of data on each page.  My entire controller with an override for &lt;code&gt;will_paginate&lt;/code&gt; looks like:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContentsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;InheritedResources&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;respond_to&lt;/span&gt; &lt;span class="ss"&gt;:html&lt;/span&gt;
      &lt;span class="n"&gt;respond_to&lt;/span&gt; &lt;span class="ss"&gt;:js&lt;/span&gt;
    
      &lt;span class="n"&gt;before_filter&lt;/span&gt; &lt;span class="ss"&gt;:admin_required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:only&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;:new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:edit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:destroy&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

      &lt;span class="kp"&gt;protected&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;
        &lt;span class="vi"&gt;@contents&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;end_of_association_chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:page&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;:page&lt;/span&gt;&lt;span class="o"&gt;]&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="ss"&gt;:order&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;id DESC&amp;#39;&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;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;collection&lt;/code&gt; method is my override and it tells &lt;code&gt;inherited_resources&lt;/code&gt; to add the &lt;code&gt;paginate&lt;/code&gt; method call when it's finding a collections of resources (e.g. the index action in Rails).  Other than that and my application specific authorization, all of the behavior is kept in &lt;code&gt;inherited_resources&lt;/code&gt; so there's a lot less code for me to maintain.  One side benefit of this is that means there is a lot less code I have to test also, since &lt;code&gt;inherited_resources&lt;/code&gt; itself tests it's generated methods.&lt;/p&gt;

&lt;h3&gt;fast_remote_cache&lt;/h3&gt;

&lt;p&gt;One common failure pattern in the past Rumbles has been teams putting off deployments until the very end and not being able to get their application running before time ran out.  My goal was to deploy as soon and as often as possible; preferably as soon as I finished a new feature.  In order to do that, I needed something faster than the standard 5-10 minute deployment process.  This is where &lt;code&gt;fast_remote_cache&lt;/code&gt; came in.  Using &lt;code&gt;fast_remote_cache&lt;/code&gt; I was able to deploy and have the server running the latest code in under a minute.  This means I could do a small deployment in the amount of time it takes a user to load a new page.  I'm going to be switching all my deployments to use &lt;code&gt;fast_remote_cache&lt;/code&gt; soon, there's no reason not too.&lt;/p&gt;

&lt;p&gt;I ended up  coming away from the 2009 &lt;a href="http://r09.railsrumble.com"&gt;Rails Rumble&lt;/a&gt; with a lot of experience about some newer tools and some great ideas on how to integrate them into older applications.  If you haven't ever done a code spike or any other rapid development on an application before, I'd highly recommend it just for the learning process.  I'm planning to continue development on &lt;a href="http://mealette.com/"&gt;MealEtte&lt;/a&gt; to see how these tools perform during application maintenance.&lt;/p&gt;

&lt;p&gt;Eric Davis&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=66C4JIzK92o:EfQerid7MuU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=66C4JIzK92o:EfQerid7MuU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=66C4JIzK92o:EfQerid7MuU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=66C4JIzK92o:EfQerid7MuU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=66C4JIzK92o:EfQerid7MuU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=66C4JIzK92o:EfQerid7MuU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=66C4JIzK92o:EfQerid7MuU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/66C4JIzK92o" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/08/26/mealette-tool-review-2009-rails-rumble</feedburner:origLink></entry>
 
 <entry>
   <title>What's the best computer science book you've ever read and why?</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/JszhhdNEoDo/what-s-the-best-computer-science-book-you-ve-ever-read-and-why" />
   <updated>2009-08-15T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/08/15/what-s-the-best-computer-science-book-you-ve-ever-read-and-why</id>
   <content type="html">&lt;p&gt;I'm an avid reader but I haven't gotten very deep into Computer Science yet, so I decided to ask on &lt;a href="http://twitter.com/edavis10/statuses/3310839647"&gt;Twitter&lt;/a&gt; to find what other people have read:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;What's the best computer science book you've ever read and why?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Some responses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://twitter.com/objo/statuses/3310887933"&gt;@objo&lt;/a&gt; said &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0023397632/"&gt;The Little Lisper&lt;/a&gt; (Called &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0262560992/"&gt;The Little Schemer&lt;/a&gt; now)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/julienXX/statuses/3310914000"&gt;@julienXX&lt;/a&gt; said &lt;a href="http://poignantguide.net/"&gt;Why's (Poignant) Guide to Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/Cerberus98/statuses/3310960843"&gt;@Cerberus98&lt;/a&gt; said &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0123744938/"&gt;Computer Organization and Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/rsturim/statuses/3311013851"&gt;@rsturim&lt;/a&gt; said &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0201485672/"&gt;Refactoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/MarkusQ/statuses/3318733762"&gt;@MarkusQ&lt;/a&gt; said &lt;a href="http://www.amazon.com/exec/obidos/ASIN/013215871X/"&gt;A Discipline of Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/MarkusQ/statuses/3311112197"&gt;@MarkusQ&lt;/a&gt; also said &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0262631113/"&gt;Perceptrons&lt;/a&gt;.  (I'll let him slide with two responses but only because of his Ruby challenges.)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/brentrowland/statuses/3311125646"&gt;@brentrowland&lt;/a&gt; said "There was a book on the Forth language with awesome cartoons. Don't remember the name, but it was my favorite."   (I think this is &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0138429308/"&gt;Starting FORTH&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/ajmurmann/statuses/3311578372"&gt;@ajmurmann&lt;/a&gt; said &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0072970545/"&gt;Introduction to Algorithms&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The best computer science book I've read is &lt;a href="http://www.amazon.com/exec/obidos/ASIN/020161622X/"&gt;The Pragmatic Programmer&lt;/a&gt;.  It was the book that got me interested in the craft of programming.  If you didn't catch my question on Twitter, tell me what the best computer science book you've read in the comments.&lt;/p&gt;

&lt;p&gt;Eric Davis&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=JszhhdNEoDo:3Mh9l7HEAp8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=JszhhdNEoDo:3Mh9l7HEAp8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=JszhhdNEoDo:3Mh9l7HEAp8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=JszhhdNEoDo:3Mh9l7HEAp8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=JszhhdNEoDo:3Mh9l7HEAp8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=JszhhdNEoDo:3Mh9l7HEAp8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=JszhhdNEoDo:3Mh9l7HEAp8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/JszhhdNEoDo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/08/15/what-s-the-best-computer-science-book-you-ve-ever-read-and-why</feedburner:origLink></entry>
 
 <entry>
   <title>RailsBridge BugMash - Contribute to the Rails core</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/QY10vJhUbt8/railsbridge-bugmash-contribute-to-the-rails-core" />
   <updated>2009-08-05T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/08/05/railsbridge-bugmash-contribute-to-the-rails-core</id>
   <content type="html">&lt;p&gt;&lt;a href="http://www.railsbridge.org"&gt;RailsBridge&lt;/a&gt; is hosting the first Rails &lt;a href="http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash"&gt;BugMash&lt;/a&gt; this coming weekend, on August 8th through August 10th.  The idea behind the BugMash is:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;RailsBridge has a lot of energy. The Rails Lighthouse has a lot of open tickets. With the help of some Rails Core team members, we're going to see what we can do to cut down the number of open tickets, encourage more people to get involved with the Rails source, and have some fun.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The BugMash will be held in the #railsbridge IRC channel with a few members of the Rails core and contributors to help.  If you'd prefer working in-person, several groups have organized venues in San Francisco, Boston, Chicago, and New York.&lt;/p&gt;

&lt;p&gt;The BugMash will also include a &lt;a href="http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash#Prizes"&gt;prize raffle&lt;/a&gt;.  Several businesses have offered prizes for the raffle; ranging from hosting to training to books.  Additionally, &lt;a href="http://getexceptional.com/"&gt;Exceptional&lt;/a&gt; is offering a 3 month plan for their service to &lt;strong&gt;all&lt;/strong&gt; participants.&lt;/p&gt;

&lt;p&gt;If you're interested in helping out the Ruby on Rails community, this weekend is a perfect time to get involved.  Just having access to the advise of other Rails experts alone is worth a few hours of hanging out.  I'll be there trying to get my first contribution into the Rails core.&lt;/p&gt;

&lt;p&gt;Eric Davis&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QY10vJhUbt8:K49uZMSWHCk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QY10vJhUbt8:K49uZMSWHCk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=QY10vJhUbt8:K49uZMSWHCk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QY10vJhUbt8:K49uZMSWHCk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=QY10vJhUbt8:K49uZMSWHCk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=QY10vJhUbt8:K49uZMSWHCk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=QY10vJhUbt8:K49uZMSWHCk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/QY10vJhUbt8" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/08/05/railsbridge-bugmash-contribute-to-the-rails-core</feedburner:origLink></entry>
 
 <entry>
   <title>Contracting or Freelancing ?</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/wWHrDx8uMFI/contracting-or-freelancing" />
   <updated>2009-07-29T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/07/29/contracting-or-freelancing</id>
   <content type="html">&lt;p&gt;A friend recently wrote me asking for some advise about contracting, which I think would be useful for a lot of freelancers.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Eric,&lt;/p&gt;

&lt;p&gt;It looks like I have a shot at a 3 month contract with Initech.  I have a vague idea of what the going hourly rates are; but I don't know anything about negotiating monthly or weekly rates.  Do you have any suggestions on how to work out what to ask for?&lt;/p&gt;

&lt;p&gt;Thanks,&lt;/p&gt;

&lt;p&gt;Peter Gibbons&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Welcome to the hardest part about business, pricing.  For this, the type of engagement will change the price.  There are at least two general types of engagements, Contracting and Freelancing.  The problem is, the terms are used interchangeably in the industry so you'll have to ask some questions to find out what they are looking for before rates even come up.  To add to this confusion, the IRS might call the contracting relationship an "employee/employer relationship" and the freelance relationship an "independent contractor relationship".&lt;/p&gt;

&lt;h2&gt;Contracting&lt;/h2&gt;

&lt;p&gt;I consider contracting as a way for a company to "hire" an expert to help for a specific chunk of time.  Aaron Erickson describes contracting as:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;One way to think of the difference is that in contracting, you are strictly exchanging time for money, whereas in consulting, you are exchanging ideas for money. The act of contracting is highly focused on rate per hour and set of skills brought to the table. No other factors matter in the context of contracting, such as the intellectual property the firm as a whole brings to the table or the broader capabilities to staff a team of professionals and provide leadership to a project.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321606396/theadmin-20"&gt;The Nomadic Developer: Surviving and Thriving in the World of Technology Consulting&lt;/a&gt;, page 40&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;When this is a contracting engagement you will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;be paid for a full week (40+ hours)&lt;/li&gt;
&lt;li&gt;be working on-site for the majority of the time&lt;/li&gt;
&lt;li&gt;use their systems to do the work (e.g. computers, network)&lt;/li&gt;
&lt;li&gt;be "contracted" based on a time frame (e.g. for 6 months)&lt;/li&gt;
&lt;li&gt;be working exclusively for Initech&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Freelancing&lt;/h2&gt;

&lt;p&gt;A freelance relationship is one where you are brought in to complete a specific goal.  For software companies, this is typically to develop a product or service for the company.  Compared to a contracting engagement, when you are freelancing you will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;only be paid for the time you work and bill.  20-30 hours a week is common.&lt;/li&gt;
&lt;li&gt;be brought on for the project and then move on afterwards&lt;/li&gt;
&lt;li&gt;be able to charge a lot more than the standard salary.  Amounts range wildly, but you can expect at least 35% more at the absolute bottom end (&lt;em&gt;see below&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;be able to work wherever you'd like&lt;/li&gt;
&lt;li&gt;use your own systems to do the work&lt;/li&gt;
&lt;li&gt;be able to work for other clients at the same time&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Since the different types of engagement vary widely, you will first need to talk with Initech to find out what they are looking for.  This means you might need to go into the meeting with two different numbers in mind, depending on what they want.  From the look of it, I'd guess they are looking for a contractor relationship.&lt;/p&gt;

&lt;p&gt;One thing to watch out for is, who is going to pay payroll taxes.  If it's you, then you need at least a 35% premium over your costs to pay self employment taxes.  You should also check how the IRS would treat the engagement to make sure you are not becoming an employee without getting any employee benefits.  The &lt;a href="http://www.irs.gov/businesses/small/article/0,,id=99921,00.html"&gt;IRS&lt;/a&gt; has created a bunch of information and tests for you to see.&lt;/p&gt;

&lt;p&gt;I hope this helps clear up some of the terminology and give you some tips on how to move forward.  Good luck.&lt;/p&gt;

&lt;p&gt;Eric Davis&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=wWHrDx8uMFI:HUIqNZZFlx4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=wWHrDx8uMFI:HUIqNZZFlx4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=wWHrDx8uMFI:HUIqNZZFlx4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=wWHrDx8uMFI:HUIqNZZFlx4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=wWHrDx8uMFI:HUIqNZZFlx4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=wWHrDx8uMFI:HUIqNZZFlx4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=wWHrDx8uMFI:HUIqNZZFlx4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/wWHrDx8uMFI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/07/29/contracting-or-freelancing</feedburner:origLink></entry>
 
 <entry>
   <title>Redmine Kanban plugin</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/6fG-hr-IrtA/redmine-kanban-plugin" />
   <updated>2009-07-22T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/07/22/redmine-kanban-plugin</id>
   <content type="html">&lt;p&gt;&lt;a href="http://theadmin.org/assets/2009/7/22/kanban.png"&gt;
   &lt;img src="http://theadmin.org/assets/2009/7/22/kanban_mid.png" alt="Kanban page" /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm happy to release the &lt;a href="https://projects.littlestreamsoftware.com/projects/redmine-kanban"&gt;Redmine Kanban&lt;/a&gt; plugin for &lt;a href="http://redmine.org"&gt;Redmine&lt;/a&gt;.  This plugin allows users to manage issues by following the &lt;a href="http://en.wikipedia.org/wiki/Kanban"&gt;Kanban&lt;/a&gt; style of project management, with bonus Javascript effects like drag and drop.&lt;/p&gt;

&lt;h2&gt;Getting the plugin&lt;/h2&gt;

&lt;p&gt;A copy of the plugin can be downloaded from &lt;a href="https://projects.littlestreamsoftware.com/projects/redmine-kanban/files"&gt;Little Stream Software&lt;/a&gt; or from &lt;a href="http://github.com/edavis10/redmine_kanban/tree/master"&gt;GitHub&lt;/a&gt;.  Make sure to download at least version 0.1.1, there was a critical bug that was fixed.&lt;/p&gt;

&lt;p&gt;The installation instructions are included in the archive's Readme.rdoc.&lt;/p&gt;

&lt;h3&gt;Features&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Global Kanban page showing the status of issues across projects&lt;/li&gt;
&lt;li&gt;Multiple "Panes" to show the lifecycle of an issue

&lt;ul&gt;
&lt;li&gt;Incoming Pane&lt;/li&gt;
&lt;li&gt;Unstaffed Backlog pane&lt;/li&gt;
&lt;li&gt;Quick Tasks pane - issues without a time estimate&lt;/li&gt;
&lt;li&gt;Selected Tasks - Manager prioritized list&lt;/li&gt;
&lt;li&gt;Active Staffed Requests - issues in progress&lt;/li&gt;
&lt;li&gt;Testing Staffed Requests - issues awaiting testing&lt;/li&gt;
&lt;li&gt;Finished Requests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Updates to Kanban view are saved to the issues

&lt;ul&gt;
&lt;li&gt;Issue status&lt;/li&gt;
&lt;li&gt;Issue assignment&lt;/li&gt;
&lt;li&gt;Issue start date&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Usage&lt;/h2&gt;

&lt;p&gt;This plugin requires some configuration so it knows your specific Redmine environment.  The Readme shows a recommended configuration that I used during development.  Future versions will allow more customizations like turning off some of the panes.&lt;/p&gt;

&lt;p&gt;Once configured, there will be a Kanban link on the top left menu.  This will bring up Kanban page, which has the entire logic of the plugin.  Make sure you have Javascript enabled and then start drag and dropping the issues.  As issues are dragged to the right panes, their statuses will be updated inside Redmine.&lt;/p&gt;

&lt;h2&gt;Project help&lt;/h2&gt;

&lt;p&gt;If you need help you can &lt;a href="http://www.littlestreamsoftware.com/contact/email"&gt;contact me&lt;/a&gt; or create an issue in the &lt;a href="https://projects.littlestreamsoftware.com/projects/redmine-kanban"&gt;Bug Tracker&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Thanks&lt;/h2&gt;

&lt;p&gt;I would like to thank &lt;a href="http://www.las.ch/"&gt;Bill Tihen from the Leysin American School in Switzerland&lt;/a&gt; for sponsoring this plugin.  If you find it useful, send your appreciation his way.&lt;/p&gt;

&lt;p&gt;If you are currently working on a Redmine plugin and need help or have an idea for a plugin you would like developed, please &lt;a href="http://www.littlestreamsoftware.com/contact/email"&gt;contact me&lt;/a&gt;.  My company, &lt;a href="http://www.littlestreamsoftware.com"&gt;Little Stream Software&lt;/a&gt;, specializes in the development of custom Redmine features and Redmine plugins.&lt;/p&gt;

&lt;p&gt;Eric&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=6fG-hr-IrtA:VxLu2jaIjiU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=6fG-hr-IrtA:VxLu2jaIjiU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=6fG-hr-IrtA:VxLu2jaIjiU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=6fG-hr-IrtA:VxLu2jaIjiU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=6fG-hr-IrtA:VxLu2jaIjiU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=6fG-hr-IrtA:VxLu2jaIjiU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=6fG-hr-IrtA:VxLu2jaIjiU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/6fG-hr-IrtA" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/07/22/redmine-kanban-plugin</feedburner:origLink></entry>
 
 <entry>
   <title>Redmine Issue Due Date plugin</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/zWU7nIqxYfE/redmine-issue-due-date-plugin" />
   <updated>2009-07-19T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/07/19/redmine-issue-due-date-plugin</id>
   <content type="html">&lt;p&gt;I've just released another small plugin for &lt;a href="http://redmine.org"&gt;Redmine&lt;/a&gt;, the Issue Due Date plugin.  This plugin will automatically set the due dates for issues based their Version or Deliverable's due dates.  I found this is useful to keep track of the latest date an issue needs to be completed by.&lt;/p&gt;

&lt;h2&gt;Getting the plugin&lt;/h2&gt;

&lt;p&gt;A copy of the plugin can be downloaded from &lt;a href="https://projects.littlestreamsoftware.com/projects/redmine-misc/files"&gt;Little Stream Software&lt;/a&gt; or from &lt;a href="http://github.com/edavis10/redmine_issue_due_date/tree/master"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Usage&lt;/h2&gt;

&lt;p&gt;The plugin entirely works in the background when Issues, Versions, or Deliverables are saved.  The plugin handles three separate states:&lt;/p&gt;

&lt;h3&gt;Issue edits&lt;/h3&gt;

&lt;p&gt;When an issue is edited, the plugin will check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the issue's due date has been set on the Issue or&lt;/li&gt;
&lt;li&gt;the deliverable has a due date or&lt;/li&gt;
&lt;li&gt;the version has a due date&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If any of those are true, the issue will have it's due date updated.  If multiple of them are true, the first one will be used.&lt;/p&gt;

&lt;h3&gt;Version or Deliverable edits&lt;/h3&gt;

&lt;p&gt;The plugin will also hook into Versions so when the version's due date is updated, all issues assigned to the Version will be updated if the issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not have a due date or&lt;/li&gt;
&lt;li&gt;Have a due date equal to the Version's old date&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Version X with a due of 2008-01-01 and issues of

&lt;ul&gt;
&lt;li&gt;Issues A (due on 2008-01-01)&lt;/li&gt;
&lt;li&gt;Issue B (due on 2008-02-01)&lt;/li&gt;
&lt;li&gt;Issue C (no due date)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Changing Version X's date to 2008-01-15 will update the due date of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Issue A to 2008-01-15. It has the same due date as the version, so it's "following" the version.&lt;/li&gt;
&lt;li&gt;Issue C to 2008-01-15. It did not have a due date so it was given the version's due date.&lt;/li&gt;
&lt;li&gt;Issue B's due date will stay 2008-02-01.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Deliverables follow the exact same behavior.&lt;/p&gt;

&lt;h3&gt;Version or Deliverable reassignments&lt;/h3&gt;

&lt;p&gt;When reassigning an issue to a different version, if the issue due date matched the old version date, the issue will change it's due date to match the new version.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I have an issue assigned to Version A with a date that matches Version A&lt;/li&gt;
&lt;li&gt;If I change the issue to be assigned to Version B, then the date should change to version B's due date.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Deliverables follow the exact same behavior.&lt;/p&gt;

&lt;h2&gt;Project help&lt;/h2&gt;

&lt;p&gt;If you need help you can &lt;a href="http://www.littlestreamsoftware.com/contact/email"&gt;contact me&lt;/a&gt; or create an issue in the &lt;a href="https://projects.littlestreamsoftware.com/projects/redmine-misc"&gt;Bug Tracker&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Thanks&lt;/h2&gt;

&lt;p&gt;I would like to thank &lt;a href="http://www.shaneandpeter.com"&gt;Shane and Peter from Shane and Peter Inc&lt;/a&gt; for sponsoring this plugin.  If you find it useful, send your appreciation their way.&lt;/p&gt;

&lt;p&gt;If you are currently working on a Redmine plugin and need help or have an idea for a plugin you would like developed, please &lt;a href="http://www.littlestreamsoftware.com/contact/email"&gt;contact me&lt;/a&gt;.  My company, &lt;a href="http://www.littlestreamsoftware.com"&gt;Little Stream Software&lt;/a&gt;, specializes in the development of custom Redmine features and Redmine plugins.&lt;/p&gt;

&lt;p&gt;Eric&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=zWU7nIqxYfE:q2V2sg0aEGI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=zWU7nIqxYfE:q2V2sg0aEGI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=zWU7nIqxYfE:q2V2sg0aEGI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=zWU7nIqxYfE:q2V2sg0aEGI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=zWU7nIqxYfE:q2V2sg0aEGI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=zWU7nIqxYfE:q2V2sg0aEGI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=zWU7nIqxYfE:q2V2sg0aEGI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/zWU7nIqxYfE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/07/19/redmine-issue-due-date-plugin</feedburner:origLink></entry>
 
 <entry>
   <title>Open Source Bridge 2009</title>
   <link href="http://feedproxy.google.com/~r/theAdmin/~3/eGEDWoM97eI/open-source-bridge-2009" />
   <updated>2009-06-25T00:00:00-07:00</updated>
   <id>http://theadmin.org/articles/2009/06/25/open-source-bridge-2009</id>
   <content type="html">&lt;p&gt;I attended &lt;a href="http://opensourcebridge.org"&gt;Open Source Bridge&lt;/a&gt; was last week, and have to say it was the best conference I've been to (I've only been to half a dozen).  The variety of content kept the conference interesting and it was nice for me to finally meet others in the Portland tech community.  I took a bunch of notes during the sessions and wanted to summarize them here.&lt;/p&gt;

&lt;h2&gt;Wednesday, June 17th&lt;/h2&gt;

&lt;h3&gt;Welcome Session&lt;/h3&gt;

&lt;p&gt;The welcome session started with some statistics that I thought were interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;About 400 people attending&lt;/li&gt;
&lt;li&gt;25% people are presenting&lt;/li&gt;
&lt;li&gt;33% speakers are female&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;How to earn an open source living without taking investors or selling your soul&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://opensourcery.com/"&gt;Brian Jamison&lt;/a&gt; from OpenSourcery talked about running a business that generates revenue from Open Source.  He had a lot of good ideas, some of which I'm going to try out in &lt;a href="http://www.littlestreamsoftware.com"&gt;Little Stream Software&lt;/a&gt;.  My favorite idea was something we should all do more often:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;"Say &lt;em&gt;No&lt;/em&gt;, a lot&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specific customer&lt;/li&gt;
&lt;li&gt;Sweat equity&lt;/li&gt;
&lt;li&gt;Microsoft projects&lt;/li&gt;
&lt;li&gt;Scope creep&lt;/li&gt;
&lt;li&gt;Lowering price - you've lost if the customer asks"&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Open Source tools for freelancers&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.christiekoehler.com/"&gt;Christie Koehler&lt;/a&gt;, a Portland freelance developer, went over several open source tools she used.  She mentioned a small Python utility called &lt;a href="http://bitbucket.org/trevor/timebook/wiki/Home"&gt;timebook&lt;/a&gt;.  It's a command line program that you can use to keep a running timer for tasks.  I'm going to try it out for a few days to see if it can replace my paper timelog I keep.&lt;/p&gt;

&lt;h3&gt;How to build a successful open source software consulting company&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://jazkarta.com/"&gt;Nate Aune&lt;/a&gt; from Jazkarta talked about starting an Open Source Consulting company.  I already consider &lt;a href="http://www.littlestreamsoftware.com"&gt;Little Stream Software&lt;/a&gt; an OS Consulting company, based on the work I do for Redmine but I did pick up few ideas on how to generate other streams of revenue (without selling my soul):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom development&lt;/li&gt;
&lt;li&gt;Training&lt;/li&gt;
&lt;li&gt;Support&lt;/li&gt;
&lt;li&gt;Hosting&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Information Security for the Open Source Business&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.k2dd.com/"&gt;Kevin Kenan&lt;/a&gt; gave a  session on Information Security.  Sadly, it was targeted at larger businesses than so many of the ideas weren't useful to me.  A good idea I did get was that products should give their customers a guide showing how to configure the product securely along with the tools needed to test those security precautions.&lt;/p&gt;

&lt;h3&gt;Cluster Analysis - how to have fun in n dimensions&lt;/h3&gt;

&lt;p&gt;In &lt;a href="http://sitr.us/"&gt;Jesse Hallett&lt;/a&gt;'s talk, showed how to do some Statistical analysis (Cluster analysis) to visually group data.  It was a very interesting talk, though above my current math knowledge.  He did have pretty animations though.&lt;/p&gt;

&lt;h3&gt;How to Work with the Government for fun and profit&lt;/h3&gt;

&lt;p&gt;I made a change at the last minute and decided to go to &lt;a href="http://www.bryantsblog.com/"&gt;Deborah Bryant&lt;/a&gt;'s session on how smaller businesses can win Government projects.  I haven't had a lot of chances to work with larger organizations so I wanted to know how feasible it is to work with the local government.&lt;/p&gt;

&lt;h2&gt;Thursday, June 18th&lt;/h2&gt;

&lt;h3&gt;Thursday Keynotes&lt;/h3&gt;

&lt;p&gt;The opening keynote for Thursday included a talk by the Portland Mayor, Sam Adams.  He mentioned that Portland has a lot of funds for digital improvements but there isn't enough people trying to help.  This might be a good opportunity for local tech businesses to pick up some work.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://aboutus.org/WardCunningham"&gt;Ward Cunningham&lt;/a&gt; gave the next keynote about Innovations in Teamwork.  One of his suggestion was that we try to work together more often, because that will lead to more insights and solutions than we have now.  Based on that advise, I'm going to try to attend more local user groups.&lt;/p&gt;

&lt;h3&gt;Unit test your database&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.justatheory.com/"&gt;David Wheeler&lt;/a&gt; from PostgreSQL Experts Inc gave a talk about unit testing the PostgreSQL database.  Even though Ruby on Rails doesn't use all of the features for each database, this talk had a few points that are great for writing unit tests against non-database code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test Driven Development is not for finding bugs, it for your own sanity and checking code consistently&lt;/li&gt;
&lt;li&gt;If testing an interface is hard, then the function might need to be refactored.  Hard to test means hard to use.&lt;/li&gt;
&lt;li&gt;Tests are about as fast as your code but even then... they are much faster than debugging.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;RubySpec: What does my Ruby do?&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://blog.brightredglow.com/"&gt;Brian Ford&lt;/a&gt; from Engine Yard gave a talk about RubySpec.  I'm really excited about this project because he talked about some very easy ways to get involved and contribute.  RubySpec is being used by many of the major Ruby implementations in order compare their implementation against the standard Ruby (MRI).&lt;/p&gt;

&lt;h3&gt;Configuration Management Panel&lt;/h3&gt;

&lt;p&gt;I went to this panel looking for a system that would help me automate server setup for myself and my customers.  I was looking for something that was easy to use and that would make doing system upgrades simple.  After hearing everyone speak, I'm going to take a look at puppet and automateit for my needs.  The &lt;a href="http://osbridge.blip.tv/file/2278426/"&gt;recording of this session&lt;/a&gt; just came online at blip.tv, I'd recommend watching it just to see the panel make offhand remarks at the other projects.&lt;/p&gt;

&lt;h3&gt;Bootstrapping Your Open Source Business&lt;/h3&gt;

&lt;p&gt;The GitHubbers never fail to entertain.  Some notable quotes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Taking VC money is like marring a girl"&lt;/li&gt;
&lt;li&gt;"I'm the CRO.  Chief Revenue Officer"&lt;/li&gt;
&lt;li&gt;"100,000 users on Twitter is the best integration test ever"&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Git vs bzr smackdown&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://www.chesnok.com/daily/"&gt;Selena Deckelmann&lt;/a&gt; and &lt;a href="http://emmajane.net/"&gt;EmmaJane Hogbin&lt;/a&gt; paired on a session comparing git to bzr.  bzr was my first exposure to a distributed version control system but git was the first one I really understood.  From what Emma and the audience were saying, bzr is easier to learn and is good if you work with Windows.  They also put up two sites to continue the battle: bzrvsgit.com gitvsbzr.com&lt;/p&gt;

&lt;h2&gt;Friday, June 19th&lt;/h2&gt;

&lt;p&gt;Friday was the unconference day.  I didn't take many notes but I think Friday was still my favorite day just from the networking and discussions that came up.  I'm going to have to attend more unconferences in Portland.&lt;/p&gt;

&lt;p&gt;That's my write up of &lt;a href="http://opensourcebridge.org"&gt;Open Source Bridge&lt;/a&gt;.  I really enjoyed myself and would highly recommend attending next years conference.  If anyone wants some more details about the notes I took, &lt;a href="http://www.littlestreamsoftware.com/contact.html"&gt;email me&lt;/a&gt; me and I'd be happy to send you a copy.&lt;/p&gt;

&lt;p&gt;Eric.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=eGEDWoM97eI:e72d1rqzxVQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=eGEDWoM97eI:e72d1rqzxVQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=eGEDWoM97eI:e72d1rqzxVQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=eGEDWoM97eI:e72d1rqzxVQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=eGEDWoM97eI:e72d1rqzxVQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/theAdmin?a=eGEDWoM97eI:e72d1rqzxVQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/theAdmin?i=eGEDWoM97eI:e72d1rqzxVQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/theAdmin/~4/eGEDWoM97eI" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://theadmin.org/articles/2009/06/25/open-source-bridge-2009</feedburner:origLink></entry>
 
 
</feed>
