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

<channel>
	<title>How they Discovered Something Worth Knowing</title>
	<atom:link href="http://www.silverchairsolutions.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.silverchairsolutions.com/blog</link>
	<description>reflections on life, technology and brownies</description>
	<lastBuildDate>Mon, 31 Oct 2011 15:06:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Using Bundler To Create Gems With Rspec</title>
		<link>http://www.silverchairsolutions.com/blog/2011/10/using-bundler-to-create-gems-with-rspec/</link>
		<comments>http://www.silverchairsolutions.com/blog/2011/10/using-bundler-to-create-gems-with-rspec/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 12:24:23 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=60</guid>
		<description><![CDATA[Suppose you want to start gem development, and you want to use bundler to generate your skeleton gem.  Great!   Now what about the tests?  I wanted to know how to add Rspec to my basic gem and get going. Here are the steps I used: bundler gem fooster Then edit the generated Gemfile (fooster/Gemfile) [...]]]></description>
			<content:encoded><![CDATA[<p>Suppose you want to start gem development, and you want to use bundler to generate your skeleton gem.  Great!   Now what about the tests?  I wanted to know how to add Rspec to my basic gem and get going.</p>

<p>Here are the steps I used:</p>

<p><code>bundler gem fooster</code></p>

<p>Then edit the generated Gemfile (fooster/Gemfile) to add rspec as a dependency</p>

<p><code>
    s.add<em>development</em>dependency "rspec"
</code></p>

<p>Then create the spec directory to hold your specs</p>

<p><code>mkdir fooster/rspec</code></p>

<p>Then create the fooster/spec/spec_helper.rb file</p>

<p><code>
    require 'rubygems'</p>

<pre><code>require 'bundler/setup'

require 'fooster' # and any other gems you need

RSpec.configure do |config|
  # some (optional) config here
end
</code></pre>

<p></code></p>

<p>I use guard to autorun my specs, so make sure that is installed (optional)</p>

<p><code>
    gem install guard</p>

<pre><code>gem install rspec-guard

cd fooster

guard init rspec
</code></pre>

<p></code></p>

<p>Then create your first spec</p>

<p><code>
    #fooster/spec/fooster_spec.rb</p>

<pre><code>require 'spec_helper'

describe Fooster do
  pending 'write it'
end
</code></pre>

<p></code></p>

<p>Then execute guard</p>

<p><code>    guard</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2011/10/using-bundler-to-create-gems-with-rspec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using git-svn with remote branches</title>
		<link>http://www.silverchairsolutions.com/blog/2011/04/using-git-svn-with-remote-branches/</link>
		<comments>http://www.silverchairsolutions.com/blog/2011/04/using-git-svn-with-remote-branches/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 11:19:45 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=53</guid>
		<description><![CDATA[I am writing this as a note to myself, because I always forget how to set this up.   I have found it surprisingly hard and tricky to get  local git branches to map to remote svn branches.   Not sure why this is really, but have put together these notes as to how to [...]]]></description>
			<content:encoded><![CDATA[<p>I am writing this as a note to myself, because I always forget how to set this up.   I have found it surprisingly hard and tricky to get  local git branches to map to remote svn branches.   Not sure why this is really, but have put together these notes as to how to get it to work &#8220;normally&#8221; from the git side and magically map to the appropriate remote branch on the remote svn side.</p>

<p>Assume your upstream svn repo is stored at https://svn2.code.com/svn/myproject</p>

<p>First clone the repo:<strong> git svn clone https://svn2.code.com/svn/myproject &#8211;stdlayout</strong></p>

<p>(stdlayout tells the git svn client to assume the existence of trunk, branches and tags in the upstream repo, most people do this)</p>

<p>after it finishes you will have a directory myproject with trunk checked out in it</p>

<p><strong>git branch -r</strong> will show you the upstream (svn) branches</p>

<p>working on a remote branch is as easy as <strong>git checkout  -b new<em>local</em>branch name<em>of</em>remote<em>upstream</em>branch</strong></p>

<p>you can see which upstream branch is connected to the local git branch by doing a <strong>git log</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2011/04/using-git-svn-with-remote-branches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Talk on Rails3 for Rails2 Programmers</title>
		<link>http://www.silverchairsolutions.com/blog/2010/05/my-talk-on-rails3-for-rails2-programmers/</link>
		<comments>http://www.silverchairsolutions.com/blog/2010/05/my-talk-on-rails3-for-rails2-programmers/#comments</comments>
		<pubDate>Wed, 12 May 2010 14:39:21 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=48</guid>
		<description><![CDATA[Last nite I gave a presentation at houston.rb about Rails3 for the person doing Rails2 currently.   Lots of folks showed up and the good folks from Squegee bought pizza.   A good time was had by all.  Lots of people wanted a link to the slides so I have included them here]]></description>
			<content:encoded><![CDATA[<p>Last nite I gave a presentation at <a title="houston.rb" href="http://houstonrb.com">houston.rb</a> about Rails3 for the person doing Rails2 currently.   Lots of folks showed up and the good folks from Squegee bought pizza.   A good time was had by all.  Lots of people wanted a link to the slides so I have included them <a href="http://www.silverchairsolutions.com/presentations/Rails3OV.pdf">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2010/05/my-talk-on-rails3-for-rails2-programmers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Running HTTPS in your Rails Development Environment</title>
		<link>http://www.silverchairsolutions.com/blog/2009/09/runnning-https-in-your-rails-development-environment/</link>
		<comments>http://www.silverchairsolutions.com/blog/2009/09/runnning-https-in-your-rails-development-environment/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 15:53:33 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=27</guid>
		<description><![CDATA[If you are building a rails application that requires SSL for parts of your site, you are probably going to use the SSL requirement plugin. But that alone isn&#8217;t going to allow you to run your code in development. You can easily see this after you enable the SSL Requirement plugin (suddenly nothing will work). [...]]]></description>
			<content:encoded><![CDATA[<p>If you are building a rails application that requires SSL for parts of your site, you are probably going to use the <a href="http://dev.rubyonrails.org/svn/rails/plugins/ssl_requirement/">SSL requirement plugin</a>.   But that alone isn&#8217;t going to allow you to run your code in development.  You can easily see this after you enable the SSL Requirement plugin (suddenly nothing will work).   Your single mongrel instance is going to need some help in order to be able process https requests!   I wanted a simple way to allow my rails development process to continue normally and still have https protected code.</p>

<p><span id="more-27"></span>
Its not hard to set this up (ok its a bit tedious), but as <a href="http://www.subelsky.com/2007/11/testing-rails-ssl-requirements-on-your.html">Mike Subelsky</a> noted in his blog post, its not really written up elsewhere in one compact recipe.  I wanted to take a slightly different approach than what Mike took, in that I wanted to disturb the default OSX install as little as possible.  Since OSX includes an apache webserver, the idea is that you have that webserver proxy all the SSL details and then pass off control to your development instance running on localhost:3000.   The built-in instance of apache can be turned on and off in OSX by going to the Sharing control panel in your System Preferences.   If you mark the checkbox named &#8220;Web Sharing&#8221; apache is on and running, and off if the checkbox is off.   You can verify this by turning it on then browsing to http://localhost, you should see an apache screen.</p>

<h1>Step 1 &#8211; Configuring SSL Encryption</h1>

<p>Note that this recipe is a condensed version of what is found <a href="http://developer.apple.com/internet/serverside/modssl.html">here</a>, but I have cut out all the commentary. You will be using terminal for all the rest of this.  Also I am using OSX Leopard
* Shut down your local apache server
either turn off web sharing or </p>

<pre><code>sudo apachectl stop
</code></pre>

<ul>
<li><p>Create a Working Directory</p>

<p>mkdir ~/Desktop/KeyGen; cd ~/Desktop/Keygen</p></li>
<li><p>Create the RSA private key</p>

<p>openssl genrsa -des3 -out server.key 1024</p></li>
</ul>

<p>use a passphrase here as directed (and remember it <img src='http://www.silverchairsolutions.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>

<ul>
<li><p>Create the CSR (Certificate Signing Request)</p>

<p>openssl req -new -key server.key -out server.csr </p></li>
</ul>

<p>This signing request you will sign yourself (for development only of course).  For this CSR enter &#8217;127.0.0.1&#8242; for the prompted &#8220;Common Name &#8211; i.e. for the appropriate server&#8221;</p>

<ul>
<li><p>Create a Certificate Authority (CA) to sign the key</p>

<pre><code>openssl genrsa -des3 -out ca.key 1024
</code></pre></li>
</ul>

<p>use a passphrase here again</p>

<ul>
<li><p>Create a self-signed CA certificate using the key you just made</p>

<p>openssl req -new -x509 -days 365 -key ca.key -out ca.crt</p></li>
</ul>

<p>in the &#8220;Common Name&#8221; field enter your name, because you are the dummy certificate authority and you are the one signing it.</p>

<ul>
<li><p>Download the latest mod_ssl distribution
It can be found <a href="http://www.modssl.org/">here</a>.  Look in the pkg.contrib subdirectory and copy the file sign.sh to your working directory. Then you have to make the file executable, and sign the csr.</p>

<p>chmod +x sign.sh ;./sign.sh server.csr</p></li>
</ul>

<p>Enter &#8216;yes&#8217; for all the prompts, and you will have a directory full of files, representing the signed csr.</p>

<ul>
<li><p>Put the signed files where apache can use them</p>

<p>sudo mkdir /etc/apache2/ssl.key</p></li>
</ul>

<p>Move all of the contents of your working directory to the ssl.key directory you just made.</p>

<pre><code>sudo cp -r * /etc/apache2/ssl.key/
</code></pre>

<ul>
<li><p>Remove the passphrase from the server key (DONT DO THIS FOR A PRODUCTION SYSTEM)</p>

<pre><code>cd /etc/httpd/ssl.key
sudo cp server.key server.key.original
sudo openssl rsa -in server.key.original -out server.key
</code></pre></li>
</ul>

<h1>Step 2 &#8211; Modify the Apache config files</h1>

<ul>
<li><p>First, back up the existing apache config file for safety</p>

<p>cd /etc/apache2
sudo cp httpd.conf httpd.conf.backup</p></li>
<li><p>Then use your favorite editor to enable the appropriate LoadModule statements.   (you are going to have to use sudo (&#8216;sudo vi&#8217;) to open this file in order to save it).  Search for a line that looks like this:</p>

<p>LoadModule ssl<em>module libexec/apache2/mod</em>ssl.so</p></li>
</ul>

<p>and make sure that the # at the beginning of the line is not there (i.e. the comment indication), if it is there remove it.  Likewise remove # from this line a bit farther down</p>

<pre><code>Include /private/etc/apache2/extra/httpd-vhosts.conf
</code></pre>

<p>and this&#8230;</p>

<pre><code>Include /private/etc/apache2/extra/httpd-ssl.conf
</code></pre>

<ul>
<li><p>Back up your extra/httpd-ssl.conf</p>

<p>sudo cp httpd-ssl.conf httpd-ssl.conf.original</p></li>
<li><p>Comment out the following line by putting a # at the beginning of it (we are putting this setting in the httpd-vhosts.conf file)</p>

<p>Listen 443</p></li>
<li><p>Remove the Virtual Host</p></li>
</ul>

<p>Then remove all the lines starting at</p>

<pre><code>    &lt;VirtualHost _default_:443&gt;
</code></pre>

<p>and ending at</p>

<pre><code>    &lt;/VirtualHost&gt; 
</code></pre>

<p>We are going to define all our virtual host stuff in the httpd-vhosts.conf file, so its not needed here.</p>

<ul>
<li><p>Back up your extra/httpd-vhosts.conf and edit it</p>

<p>sudo cp httpd-vhosts.conf httpd-vhosts.conf.original</p></li>
</ul>

<p>I pretty much deleted everything in my vhosts file and replaced it with the following content</p>

<pre><code>Listen 443

SSLCertificateFile /etc/apache2/ssl.key/server.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server.key

CustomLog logs/ssl_request_log  "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

&lt;VirtualHost *:80&gt;
 ServerName localhost
 ServerAlias 127.0.0.1

 ProxyPass / http://localhost:3000/
 ProxyPassReverse / http://localhost:3000
 ProxyPreserveHost on
&lt;/VirtualHost&gt;

&lt;VirtualHost *:443&gt;
 SSLEngine On
 ServerName localhost
 ServerAlias 127.0.0.1

 ProxyPass / http://localhost:3000/
 ProxyPassReverse / http://localhost:3000
 ProxyPreserveHost on
 RequestHeader set X_FORWARDED_PROTO 'https'
&lt;/VirtualHost&gt;
</code></pre>

<p>And thats it.  Go to your Sharing control panel and turn on Web Sharing.  You should see https requests being forwarded correctly to your rails application (assuming that its listening on the default mongrel port of 3000).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2009/09/runnning-https-in-your-rails-development-environment/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Announcing the migrate_war Rails plugin</title>
		<link>http://www.silverchairsolutions.com/blog/2008/04/announcing-the-migrate_war-rails-plugin/</link>
		<comments>http://www.silverchairsolutions.com/blog/2008/04/announcing-the-migrate_war-rails-plugin/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 16:32:00 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=26</guid>
		<description><![CDATA[The MigrateWar Rails plugin makes it easy to create database schema on deployment machines when you deploy via JRuby/War Files. This is especially helpful on Windows machines, where you cannot use Capistrano easily. Capistrano is a powerful deployment tool that is considered &#8216;state of the practice&#8217; by anyone deploying Rails applications to Unixy type systems. [...]]]></description>
			<content:encoded><![CDATA[<p>The MigrateWar Rails plugin makes it easy to create database schema on deployment machines when you deploy via JRuby/War Files.  This is especially helpful on Windows machines, where you cannot use Capistrano easily. </p>

<p>Capistrano is a powerful deployment tool that is considered &#8216;state of the practice&#8217; by anyone deploying Rails applications to Unixy type systems.  But what about if you need some of that same Capistrano fu on a windows server.   Can it be done?   In my case I really needed a way to build my
database schema on the deployment target as soon as the application was deployed (cap deploy with migrations basically).   This isnt such an 
easy thing to do as I found.    I was going to deploy via JRuby/Goldspike in a War file format (the standard java deployment package), so I dusted off my arcane Java knowledge and came up with a solution to load the schema.rb file as soon as the war file loads.  Read on for details.</p>

<p><span id="more-26"></span></p>

<p>The trick here, was that I needed the &#8220;migrate to current&#8221; process to run only once, when the Rails application loads.  When you deploy the web application via the Goldspike Plugin, you end up with a pretty standard Java Web Application  WAR file (i.e. Web ARchive).   WAR files have a very well defined set of hooks for startup and teardown, which of course would directly correspond to the startup of the Rails application that we are deploying inside of that WAR file.  So the basic trick, is to leverage the startup hook of the WAR file (In Javaland this is called a Context) and run the appropriate logic for creating database schema on the deployment box.    You could of course do arbitrary other things as well, but thats a talk for another time.</p>

<p>We want to do this in such a way that we are writing a minimum of Java code, and pushing most of the work of doing this off to Ruby.  The first thing we have to do is create the Java class which runs when the Context loads (i.e. the Rails application).   This is done by creating a ServletContextListener, an interface in Java.   Here is an excerpt of the class I wrote (showing only the important bits)</p>

<p>`  </p>

<pre><code>    public void contextInitialized(ServletContextEvent event) {
  try {
      final ServletContext context = event.getServletContext();
      // create the pool
      initiallizeJrubyEnvironment(context);

      //this is defined in the web.xml
      commandFile = context.getInitParameter("command-file");


      System.out.println("Entering: MigratorContentListener.contextIntialized \n");

      thread = new Thread(new Runnable() {

          public void run() {
              try {
                  // wait for a little while before starting the task
                  // this allow the app server to start serving requests before initializing all tasks
                  Thread.sleep(100);


                  runOnce(context);
                  System.out.println("Exiting: MigratorContentListener.contextIntialized \n");
              } catch (InterruptedException e) {
                  // break out of loop
              } catch (Exception e) {
                  context.log("Could not start " + commandFile, e);
              }
          }
      });
      thread.start();
  } catch (ServletException ex) {
      Logger.getLogger(MigratorContextListener.class.getName()).log(Level.SEVERE, null, ex);
  }}'
</code></pre>

<p>&#8216;<br />
    private void runOnce(ServletContext context) throws Exception {</p>

<pre><code>    try {
        String rootDir = context.getRealPath("");

        Ruby runtime = null;
        try {

            String script = readFileAsString(rootDir + "/" + commandFile);
            context.log("executing "+script);
            runtime = (Ruby) getRuntimePool().borrowObject();
            runtimeApi.eval(runtime,"ENV['RAILS_ROOT'] = '" + rootDir + "'");
            runtimeApi.eval(runtime, script);
            getRuntimePool().returnObject(runtime);
        } catch (Exception e) {
           context.log("Could not execute: " + commandFile, e);
            getRuntimePool().invalidateObject(runtime);
          context.log(commandFile + " returning JRuby runtime to pool and will restart in 15 minutes.");
            try {
                Thread.sleep(FIFTEEN_MINUTES_IN_MILLIS);
            } catch (InterruptedException ex) {
            // can't do much here ...
            }
        }


    } catch (Exception e) {
        e.printStackTrace();
        context.log("Could not execute: " + commandFile, e);
    }
}`
</code></pre>

<p>The J2EE application server will call the contextInitiallized method shown above when the WAR file loads.  In the 4th line of that method, notice that I get the name of the ruby file to run, its passed in via a parameter defined in the web.xml file.   More on that later.    Basically this class executes the &#8220;runOnce&#8221; method one time, in a separate thread, as soon as the context loads.   Really all the runOnce method does is pass the name of the method to run to the Ruby runtime that has been set up  via the magic of JRuby.   </p>

<p>In order to get this file to get loaded by the Application Server, you need to make two entries in the web.xml file.   The first one, which tells it to attach a listener to the Context, looks like this  </p>

<p><code>&lt;listener&gt;
   &lt;listener-class&gt;org.jruby.webapp.MigratorContextListener&lt;/listener-class&gt;
 &lt;/listener&gt;</code></p>

<p>where the MigratorContextListener is the Java class that contains the logic listed above.  The second entry that you need to put into the web.xml file is what the ruby file is named that you want executed.   Here is that entry  </p>

<p><code>&lt;context-param&gt;
    &lt;param-name&gt;command-file&lt;/param-name&gt;
    &lt;param-value&gt;migrator.rb&lt;/param-value&gt;
    &lt;description&gt;Run this file to execute an initial migration (for deployment to new platforms)&lt;/description&gt;
&lt;/context-param&gt;</code></p>

<p>The migrator.rb file, the one that gets executed on startup (and found in the root of the application), looks like this  </p>

<p><code>load('db/schema.rb')</code></p>

<p>Once this executes, the production database indicated in the database.yml will get the schema.rb file applied to it.  It would have been much cooler to actually run a migration, but by the time you deploy to production, your schema has probably settled down anyway, so applying the schema.rb file is probably sufficient.  I guess the bigger point is, you can do arbitrary things at install time with this.</p>

<p>I bundled all of this up into a plugin called &#8220;migrate_war&#8221;, one of the things this plugin includes is a jar file which contains the ContextListener, you have to tell the GoldSpike plugin about this jar file so that it includes it in the WAR file it generates.   To do this edit the config/war.rb file and add this to the end:  </p>

<p><code>include_library 'migrator-rails' , '0.9'</code></p>

<p>When you install the plugin, it will copy that jar to lib/java and the include_library command will find it there and pull it into the generate WAR file.</p>

<p>Once you have installed the plugin and made the include_library addition shown above, go ahead and generate your WAR file using Goldspike.</p>

<p>After that finishes you can edit the web.xml file found in WEB-INF/web.xml (Goldspike generates the WEB-INF and everything below it) with the xml edits shown above (for the listener, and the command-file).  Then you need to run it again to generate the WAR file with the modified web.xml included (if the WEB-INF directory already exists the Goldspike plugin won&#8217;t clobber this directory unless you tell it to, so its cool to edit these files before generating again, Goldspike will use whats in WEB-INF).</p>

<p>You can install the plugin by entering  </p>

<p><code>script/plugin install http://svn.silverchairsolutions.com/migrate_war/</code>. </p>

<p>Hope this helps someone!</p>

<p>Update:  Its important to note that this will apply the schema.rb file directly to your database.  This will blow away the schema contained within (and any data found there).  So if you need to save the data, you should export it then reimport it after the schema gets built.  It would be much cooler if migrations were run on this.  Anyone care to try?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2008/04/announcing-the-migrate_war-rails-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails Contractor:   I am Available! (One of the Advanced Rails Recipes Book contributors )</title>
		<link>http://www.silverchairsolutions.com/blog/2008/04/ruby-on-rails-contractor-i-am-available-one-of-the-advanced-rails-recipes-book-contributors/</link>
		<comments>http://www.silverchairsolutions.com/blog/2008/04/ruby-on-rails-contractor-i-am-available-one-of-the-advanced-rails-recipes-book-contributors/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 01:51:28 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=25</guid>
		<description><![CDATA[I just posted this to craigslist: I am web developer who specializes in Ruby on Rails contracts and works remotely from my home office. Currently looking for new projects, I&#8217;m open to conversations about new contract possibilities. My company is Silverchair Solutions, an agile web development consultancy. I have over 13 years of web development [...]]]></description>
			<content:encoded><![CDATA[<p>I just posted this to craigslist:</p>

<p>I am web developer who specializes in Ruby on Rails contracts and works remotely from my home office. Currently looking for new projects, I&#8217;m open to conversations about new contract possibilities. My company is Silverchair Solutions, an agile web development consultancy.  I have over 13 years of web development experience 
and two and a half years of Rails experience.  Recently some of my work was published in the Advanced Rails Recipes book (Pragmatic Programmers &#8211; see the wizard chapter!).  I am a former Oracle DBA and am very comfortable designing databases as well as configuring linux/mac os servers in support of my web applications.</p>

<p>To learn more about me, view my Linkedin profile <a href="http://www.linkedin.com/pub/0/51/b39">here:</a></p>

<p><a href="http://www.workingwithrails.com/person/8989-mike-hagedorn">Working with Rails Profile</a></p>

<p>If you have a project that you think I may be able to help you with, please send me an email with a short description of what it is you need done and we will chat!</p>

<p>Thanks,
Mike</p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2008/04/ruby-on-rails-contractor-i-am-available-one-of-the-advanced-rails-recipes-book-contributors/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I&#8217;m an Author!</title>
		<link>http://www.silverchairsolutions.com/blog/2008/04/im-an-author/</link>
		<comments>http://www.silverchairsolutions.com/blog/2008/04/im-an-author/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 14:35:05 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=24</guid>
		<description><![CDATA[Ok its been awhile since this occurred, but I would be remiss if I didn&#8217;t mention that I have been included as one of the authors of the Pragmatic Studio&#8217;s Advanced Rails Recipes Book. I contributed a chapter on creating Wizards. You can check it out here. Basically I leveraged actsasstate_machine to pull this off. [...]]]></description>
			<content:encoded><![CDATA[<p>Ok its been awhile since this occurred, but I would be remiss if I didn&#8217;t mention that I have been included as one of the authors of the Pragmatic Studio&#8217;s Advanced Rails Recipes Book.   I contributed a chapter on creating Wizards.   You can check it out <a href="http://www.pragprog.com/titles/fr_arr" title="Advanced Rails Recipes">here</a>.  Basically I leveraged acts<em>as</em>state_machine to pull this off.  Check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2008/04/im-an-author/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using your website url as your OpenID</title>
		<link>http://www.silverchairsolutions.com/blog/2008/03/using-your-website-url-as-your-openid/</link>
		<comments>http://www.silverchairsolutions.com/blog/2008/03/using-your-website-url-as-your-openid/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 14:22:28 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[OpenId]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=23</guid>
		<description><![CDATA[I have an OpenId, I have found it useful. But frankly its just another thing that I have to remember. Somthing that I can&#8217;t forget is my website url. What if you could set up some kind of cool forwarding that allows me to use my website url as my OpenID? Well&#8230; you can. Actually [...]]]></description>
			<content:encoded><![CDATA[<p>I have an OpenId, I have found it useful.   But frankly its just another thing that I have to remember.  Somthing that I can&#8217;t forget is my website url.  What if you could set up some kind of cool forwarding that allows me to use my website url as my OpenID?   Well&#8230; you can.  Actually if you just have a blog and not a full blown website, this will work too.   </p>

<p>Add some entries to the head section of the index page of your website </p>

<hr />

<pre><code>`&lt;link rel="openid.server" href="http://www.myopenid.com/server" /&gt;
&lt;link rel="openid.delegate" href="http://your.real.openid.com/" /&gt;'
</code></pre>

<p>Where, the openid.server is the url of your provider, and the openid.delegate is your real openid identity.</p>

<p>This trick will work with any resource you have access to on the internet, i.e. anything where you could add information to the head portion of your index page.   Many thanks to <a href="www.duncandavidson.com">Duncan Davidson</a> for this tip</p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2008/03/using-your-website-url-as-your-openid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating Cocoa Deployments with Sparkle and Xcode</title>
		<link>http://www.silverchairsolutions.com/blog/2008/03/automating-cocoa-deployments-with-sparkle-and-xcode/</link>
		<comments>http://www.silverchairsolutions.com/blog/2008/03/automating-cocoa-deployments-with-sparkle-and-xcode/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 16:40:12 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Cocoa]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=22</guid>
		<description><![CDATA[For those of us who live in the rails world, fantastic tools like Capistrano have made deployment drop-dead simple. And since I do some Cocoa work I found myself wanting some of that same capistrano-esqe love in my Cocoa deployments. The Sparkle framework handles most of this for you, but in its vanilla implementation requires [...]]]></description>
			<content:encoded><![CDATA[<p>For those of us who live in the rails world, fantastic tools like <a href=""www.capify.org"">Capistrano</a> have made deployment drop-dead simple.   And since I do some Cocoa work I found myself wanting some of that same  capistrano-esqe love in my Cocoa deployments.   The <a href=""http://sparkle.andymatuschak.org/"">Sparkle</a> framework handles most of this for you, but in its vanilla implementation requires you to hand code some descriptor files and this seemed problematic to me.   So I have cooked up an Xcode based recipe which allows me to do push button deploys and let Sparkle handle the updating part.</p>

<p><span id="more-22"></span></p>

<p>I got the germ of the idea for this one from <a href=""http://duncandavidson.com/"">Duncan Davidson&#8217;s</a> blog post (which sadly is no longer available due to a server crash) of last fall where he too was longing for something like capistrano to automatically handle pushing up code updates.   I will condense what I remember from his post.   </p>

<p>At its heart, this approach starts by recognizing that Xcode allows you to keep project specific settings (kind of like environment variables) in a separate file called an .xcconfig file.   For us this file will contain the version number of the code that we are going to deploy.   In this technique this value will be manually editing.   Everytime we want to do a deploy, edit the xcconfig file, then do a deployment.   The deployed code will show up on the client with the version number you specified in the .xcconfig file.</p>

<h1>Create the Xcode Config File</h1>

<p>In your cocoa project, add a new file to the project (File -> New File) and select  Xcode/Configuration Settings File.   Call it whatever works for you.   Open the file up in Xcode and add this single line to it (or more if you are using xcconfig for other things too <img src='http://www.silverchairsolutions.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>

<p><code>WIDGET_VERSION = 0.99</code></p>

<p>(Replace WIDGET with whatever the name is of your application, its up to you, you are merely defining a variable here that you will use in your Plist ).</p>

<p>The next step is to make sure XCode uses the xcconfig file that we just created.  To do this, select the project icon in the outline view of Xcode and hit command-I.  This will bring up the project information for your project.   Navigate to the build tab on this window, and at the bottom of this tab you should see &#8220;Based on:&#8221;, with a drop down to pick an xcconfig file to base this build on.   Since we are going to control the version number through the xcconfig, we want to select the xcconfig file that holds our version number here.</p>

<h1>Modify the PList file to utilize the setting from the .xcconfig file</h1>

<p>Lets now edit Info.plist file to make use of the version number.  Edit the plist so that it looks like this (I have only listed the appropriate lines, leave the lines alone)</p>

<p><code>&lt;key&gt;CFBundleVersion&lt;/key&gt;
 &lt;string&gt;${WIDGET_VERSION}&lt;/string&gt;</code></p>

<p>Save this and lets move on&#8230;</p>

<h1>Create a new build target which does the deploy</h1>

<p>Add a new target to your XCode project, and call it Deploy.  Drag your build product under this target as well.  This step will make sure that building the application will happen before deploying it (it makes it a dependency).   Add a new build phase to your Deploy target, add a build phase that is of type Run Script.  &#8221; Add -> New Run Script Build Phase&#8221;.  Edit this run script build phase to look like this:</p>

<pre><code>if [ "Release" != "$CONFIGURATION" ]; then
    echo 'error: Package creation only works for Release builds'
    exit -1
fi

./ruby_deploy.rb $WIDGET_VERSION $CONFIGURATION_BUILD_DIR`
</code></pre>

<h1>Create the Ruby File Which Does the Packaging</h1>

<p>In our run script phase we just wrote, we turn around and execute a ruby script called <code>ruby_deploy</code>.  This is a custom script that we are going to create right now.  Go ahead and add a new empty file to your project, and save it as ruby_deploy.rb.   Here is a suggested starting place that I use.  Feel free to modify it as needed for what you are doing</p>

<pre><code>#!/usr/bin/env ruby
#
#  ruby_deploy.rb
#  widget
#
#  Created by Mike Hagedorn on 12/1/07.
#  Copyright (c) 2007 Silverchair Solutions. All rights reserved.
#


require 'rss/1.0'
require 'rss/2.0'
require 'open-uri'
require 'rss'

require 'net/http'


#put your application name here
APPLICATION_NAME="widget"
#put your user name here
USERNAME="user"
#specify the appropriate server and directories here
SCP_DESTINATION="yourserver.com:the_directory_where_you_want_it_on_your_webserver/apps/#{APPLICATION_NAME}"
SCP_SOURCE="/tmp"


version = ARGV[0]
build_dir = ARGV[1]
proper_name = APPLICATION_NAME.capitalize
package = "#{proper_name}_#{version}.zip"
notes = "#{APPLICATION_NAME}_#{version}.html"
puts build_dir
`zip -r /tmp/#{package} \"#{build_dir}/PhonoscopeDialer.app\"`
url_base = "http://yourserver.com/apps/#{APPLICATION_NAME}"
dist_dir = url_base

content = ""
# raw content of rss feed will be loaded here
open("#{url_base}/appcast.xml") do |s|
    content = s.read
end
rss = RSS::Parser.parse(content, false)

package_url = "#{url_base}/#{package}"
zip_ctime = File.ctime("#{SCP_SOURCE}/#{package}")
zip_size = File.size("#{SCP_SOURCE}/#{package}")
pub_date = zip_ctime.localtime.strftime("%a, %d %b %Y %T %z")

last_item = rss.items.last

latest_version = last_item.title.split.last
if version.to_f &lt;= latest_version.to_f
    puts "version not updated, returning"
    exit -1
end


source = "#{SCP_SOURCE}/#{package}"
dest = "#{USERNAME}@#{SCP_DESTINATION}/#{package}"
`scp \"#{source}\" \"#{dest}\"`

content_new = RSS::Maker.make("2.0") do |m|
    m.channel.title = "Your Application Log"
    m.channel.link = "#{url_base}/appcast.xml"
    m.channel.description = "Most recent changes with links to updates."
    m.channel.language = "en"
    rss.items.each do |item|
        m.items.new_item do |newitem|
            newitem.title = item.title
            newitem.link = item.link
            newitem.description = item.description  
            newitem.enclosure.url = item.enclosure.url  
            newitem.enclosure.type = item.enclosure.type
            newitem.enclosure.length = item.enclosure.length
            newitem.date = item.date
        end
    end
#add the new one
m.items.new_item do |appendedItem|
    appendedItem.title = "Your Application Version #{version}"
    appendedItem.description = "#{url_base}/#{APPLICATION_NAME}_#{version}.html"
    appendedItem.enclosure.url = "#{package_url}"
    appendedItem.enclosure.type = 'application/octet-stream'
    appendedItem.enclosure.length = "#{zip_size}"
    appendedItem.date = pub_date        
end


end

puts content_new
File.open("#{SCP_SOURCE}/appcast.xml","w") do |f|
    f.write(content_new.to_s)
end


source = "#{SCP_SOURCE}/appcast.xml"
dest = "#{USERNAME}@#{SCP_DESTINATION}/appcast.xml"
`scp \"#{source}\" \"#{dest}\"`

source = "#{build_dir}/#{notes}"

dest = "#{USERNAME}@#{SCP_DESTINATION}/#{notes}"
`scp \"#{source}\" \"#{dest}\"`
</code></pre>

<p>Lets step through this script.  The first thing to do (and this will be custom to your application) is to set up  values for a specific server on the internet where your application will be stored.   The variables set up here for the location of the appcast need to match the SUFeedURL entry in your Plist file.   You would have had to set that up when you integrated Sparkle.  Heres an example that would match the ruby file listed above.</p>

<p><code>&lt;key&gt;SUFeedURL&lt;/key&gt;
&lt;string&gt;http://www.yourserver.com/apps/widget/appcast.xml&lt;/string&gt;</code></p>

<p>The next thing that is done is to create the archive (zip file) of the built application.  That&#8217;s why building the application is a prerequisite for the deploy step, you want to make sure you have code there to actually zip up.   After you zip up the file, you store it in the <code>/tmp</code> directory. </p>

<p>Now we need to update the appcast.xml file, this is the RSS feed that your application will check to see if there is a more recent drop of the application available. The basic workflow is, go out to the internet, grab the appcast.xml feed (the xml), parse the file to find the last revision number, if the current revision is equal to the last revision, exit and do nothing.  If however the revision number is greater (this should usually be the case) then go ahead and copy the zipped up code out to the server using scp, secure copy.   Then you need to create an RSS item for the new current revision (the update) and append it to the collection of items in the RSS feed.   Then you simply copy back the new and improved appcast.xml file out to your server.  Here is a simple example of an appcast file, to get this process started you need to copy this file out to your server first (so that it can be fetched and parsed)</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; 
    &lt;rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle"&gt; 
    &lt;channel&gt; 
        &lt;title&gt;Your Application Log&lt;/title&gt; 
        &lt;link&gt;http://www.yourserver.com/apps/widget/appcast.xml&lt;/link&gt; 
        &lt;description&gt;Most recent changes with links to updates.&lt;/description&gt; 
        &lt;language&gt;en&lt;/language&gt; 
        &lt;item&gt; 
            &lt;title&gt;Version 0.9&lt;/title&gt; 
            &lt;description&gt;http://www.yourserver.com/apps/widget/widget_0.9.html&lt;/description&gt; 
            &lt;pubDate&gt;Fri, 30 Nov 2007 19:20:11 +0000&lt;/pubDate&gt; 
            &lt;enclosure url="http://www.yourserver.com/apps/widget/widget_0.9.zip" length="1600000" type="application/octet-stream"/&gt; 
        &lt;/item&gt; 
    &lt;/channel&gt; 
    &lt;/rss&gt; 
</code></pre>

<p>`</p>

<p>Another step here that is important to the workflow is to add a release note to each drop.  This is an html file that is displayed when the update is loading.  The naming convention is appname_version.html.   Here&#8217;s a simple example of that</p>

<pre><code>&lt;h2&gt;Notes on version 1.02&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;First Sparkle Release&lt;/li&gt;
&lt;/ul&gt;`
</code></pre>

<h1>Your Deployment Workflow</h1>

<p>Now that you have all this, how do you use it?   First do all your coding, testing, etc for your next release.  When you are ready to push out some changes, first create the html file listing your changes and add it to your project (so that the script can find it to copy it out to your deployment server). Use the naming convention listed above.  Then update your xcconfig file with the appropriate release number.  Then select the Deploy target and build.   That&#8217;s it.    Isn&#8217;t that cool?
`</p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2008/03/automating-cocoa-deployments-with-sparkle-and-xcode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>State Transition Diagrams for acts_as_state_machine</title>
		<link>http://www.silverchairsolutions.com/blog/2008/03/state-transition-diagrams-for-acts_as_state_machine/</link>
		<comments>http://www.silverchairsolutions.com/blog/2008/03/state-transition-diagrams-for-acts_as_state_machine/#comments</comments>
		<pubDate>Wed, 05 Mar 2008 22:31:49 +0000</pubDate>
		<dc:creator>mhagedorn</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.silverchairsolutions.com/blog/?p=21</guid>
		<description><![CDATA[Lately I have been using the wonderful acts_as_state_machine plugin for lots of cool stuff in my rails applications. The problem that I have run into though, is visualizing the state transitions that I have created. Typically, when I first learned about state machines back in Electrical Engineering days, we drew cool diagrams with bubbles to [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I have been using the wonderful <code>acts_as_state_machine</code> plugin for lots of cool stuff in my rails applications.   The problem that I have run into though, is visualizing the state transitions that I have created.  Typically, when I first learned about state machines back in Electrical Engineering days, we drew cool diagrams with bubbles to represent the states and arrows to show the state transitions (a.k.a state transition diagrams).  I have found these to be very helpful.   But I wanted to a way to automatically create these.</p>

<p><span id="more-21"></span></p>

<p>My first problem was, how do I dynamically create graphs?   This was solved when I found out about this:
<a href="http://www.graphviz.org" title="graphviz">Graphviz</a>, an open source graph visualization language that many software packages understand.   There are stand-alone graph readers available as well as tools like OmniGraffle for the mac which can read this format.  We will create our diagrams in this format (.dot).  </p>

<p>My solution was inspired by Dave Thomas and his <em>annotate_models</em> plugin.   I created a plugin that is triggered as a rake task, i.e. <code>rake annotate_states</code>   I used Dave&#8217;s code to guide me on how to step through all the model classes, then I added additional logic to filter out all model classes that didnt use acts<em>as</em>state_machine.   I then introspected on the remaining list and got a list of states and transitions so that I could build the diagram.</p>

<p>You can install the plugin in the usual way, navigate to the root of your application and type <code>script/plugin install http://svn.silverchairsolutions.com/annotate_states</code>.   </p>

<p>After installing the plugin (and checking that it lists as a rake task by typing rake -T) you can create the .dot files for your application by typing <code>rake annotate_states</code>.   Each model file in your application that uses <code>acts_as_state_machine</code> should produce a state transition diagram in the root of your application.</p>

<p>Hope you enjoy it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.silverchairsolutions.com/blog/2008/03/state-transition-diagrams-for-acts_as_state_machine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

