<?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>casperfabricius.com &#187; tutorial</title>
	<atom:link href="http://casperfabricius.com/site/category/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://casperfabricius.com/site</link>
	<description>expert ruby on rails development</description>
	<lastBuildDate>Sun, 06 Jun 2010 08:43:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Getting started with JRuby on Rails on OS X</title>
		<link>http://casperfabricius.com/site/2008/11/05/getting-started-with-jruby-on-rails-on-os-x/</link>
		<comments>http://casperfabricius.com/site/2008/11/05/getting-started-with-jruby-on-rails-on-os-x/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 19:14:44 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
		<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/home/cfp/casperfabricius.com/site/wp-content/plugins/autometa/autometa.php</b> on line <b>324</b><br />
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=142</guid>
		<description><![CDATA[I&#8217;ve been an independent web developer for over a month now, and I am enjoying every moment of it! If the first step in the liberation of programmers is getting Java- or .NET-free, the second step must be to get employer-free. Of course, being an employee has many benefits and doesn&#8217;t hold much risk (especially [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been an independent web developer for over a month now, and I am enjoying every moment of it! If the first step in the liberation of programmers is getting Java- or .NET-free, the second step must be to get employer-free. Of course, being an employee has many benefits and doesn&#8217;t hold much risk (especially not if you live in one of these countries where it is practically impossible to fire people, such as Sweden or France), and being independent doesn&#8217;t mean &#8211; at least not yet for me &#8211; that you don&#8217;t have to do boring or tedious work.</p>
<p>But it does mean that any time during work hours where I am not doing work for a customer is my own time, and on my own time I get to decide what to work on. I am building a product during these free hours, and while I&#8217;d like to hold the details a bit longer (&#8220;don&#8217;t tell &#8211; show!&#8221; someone smart has said), I can say that it is a Ruby on Rails application allowing manipulation of PDF documents. Ruby has some decent PDF libraries, and <a href="http://github.com/sandal/prawn/tree/master">Prawn</a> holds a great potential, but none of these allow me to manipulate existing PDF documents.</p>
<p>The Java library <a href="http://www.lowagie.com/iText/">iText</a> is capable of doing so, and so is the .NET port <a href="http://itextsharp.sourceforge.net/">iTextSharp</a>, but would I really have to build some kind of web service in one of these forsaken frameworks? I was complaining about it to a friend, and promptly asked me: Why don&#8217;t you build it in JRuby? The more I thought about it, the more this seemed to be the perfect excuse for trying out JRuby, and so I set out to build my first ever JRuby on Rails application. It also helped that I got a free OpenSolaris/Glassfish VPS from <a href="http://www.sun.com/third-party/global/glassfish/index.jsp">Sun</a> and <a href="http://www.layeredtech.com/sun">Layered Technologies</a>.</p>
<p><span id="more-142"></span></p>
<p>Now, this long introduction was meant to disguise the fact that it is really very easy to get started on some JRuby on Rails development on Mac OS X. All I did was to follow <a href="http://rorblog.techcfl.com/2007/06/01/get-jruby-onto-the-rails-on-mac-os-x/">this great installation guide</a>. I do however have a few corrections and recommendations of my own, which I recommend you read before you go on to Robert Dempseys blog. </p>
<p>First, the guide doesn&#8217;t tell you where to install JRuby, and that&#8217;s because you can install anywhere you want. I chose to put it in <code>/Library/Java/</code>, because it makes sense to me to place it with the other Java stuff. Also, make sure you download the newest JRuby version from their <a href="http://dist.codehaus.org/jruby/">download page</a> &#8211; that&#8217;s <i>not</i> the first in the list. Second, the guide assumes that you have Ant &#8211; a tool for building Java apps &#8211; installed, but I bet you haven&#8217;t. To do this, you can either follow <a href="http://www.asceticmonk.com/blog/?p=388">this guide</a>, or you can simply <a href="http://ant.apache.org/bindownload.cgi">download Ant</a> and put it in <code>/Library/Java/</code>. Remember to put <code>JAVA_HOME</code> and <code>ANT_HOME</code> in your <code>.bash_profile</code> as Robert&#8217;s guide says.</p>
<p>If you need to work with ordinary Ruby applications alongside your JRuby apps, I wouldn&#8217;t recommend putting the JRuby lib in your default path. While it is easy to distinguish between the <code>ruby</code> and <code>jruby</code> commands, JRuby also have its own version of other well-known  tools such as <code>gem</code> and <code>rake</code>, and since JRuby for instance keeps its own gem repository, you can end up being quite confused as to what gems you are seeing. My solution is not the most elegant, but it works for me. I have created a file with the contents below in my home directory, and when I want to work with JRuby, I simply have to write <code>source ./~.jruby</code> in my console:</p>
<pre>
  export PATH="/Library/Java/jruby-1.1.4/bin/:$PATH"
</pre>
<p>There is one part of Robert&#8217;s guide that is slightly outdated. The name and structure of the ActiveRecord gems that allow using MySQL through JDBC has changed. Instead of installing the now non-existing <code>activerecord-jdbc</code> gem, you should install <code>activerecord-jdbc-adapter</code> and <code>activerecord-jdbcmysql-adapter</code>:</p>
<pre>
  sudo gem install activerecord-jdbc-adapter activerecord-jdbcmysql-adapter
</pre>
<p><a href="http://rubylearning.com/blog/2008/07/28/using-activerecord-and-jdbc-with-jruby/">This article</a> explains the various JDBC adapters available in depth.</p>
<p>Also, I didn&#8217;t need to add the lines in <code>environment.rb</code> starting with <code>if RUBY_PLATFORM =~ /java/</code>. With the gems installed and the MySQL jar in place, it worked out of the box for me.</p>
<p>By now you should hopefully be able to build and run your JRuby application. But what you want to debug? I like to use <a href="http://bashdb.sourceforge.net/ruby-debug.html">ruby-debug</a> in my Rails applications, because it allows me to break anywhere in the code by adding a <code>debugger</code> statement. For JRuby, the official ruby-debug gem won&#8217;t work because it relies on compiled C code, but luckily a JRuby compatible verison has been released as described in <a href="http://wiki.jruby.org/wiki/Using_the_JRuby_Debugger">the JRuby wiki</a>. With this installed, you simply add the <code>-d</code> when you call <code>jruby</code>, and the code will break at any <code>debugger</code> like we are used to.</p>
<p>Next up is interacting with Java libraries and deploying JRuby on Rails applications, but that&#8217;ll have to be in separate articles &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2008/11/05/getting-started-with-jruby-on-rails-on-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keeping git repositories on Dreamhost using SSH</title>
		<link>http://casperfabricius.com/site/2008/09/21/keeping-git-repositories-on-dreamhost-using-ssh/</link>
		<comments>http://casperfabricius.com/site/2008/09/21/keeping-git-repositories-on-dreamhost-using-ssh/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 19:00:46 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
		<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/home/cfp/casperfabricius.com/site/wp-content/plugins/autometa/autometa.php</b> on line <b>324</b><br />
		<category><![CDATA[other]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=130</guid>
		<description><![CDATA[&#8220;is bemused/awed by how fast svn became a legacy technology in ruby community/developers&#8221; Dr. Nic recently said on Twitter. It is true. Greatly aided by Geoffrey Grosenbach&#8217;s screencast on git, I myself is starting to feel comfortable enough with git to start abandoning subversion altogether.
Github is great, but there is really no reason to pay [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/drnic/statuses/924483088">&#8220;is bemused/awed by how fast svn became a legacy technology in ruby community/developers&#8221;</a> <a href="http://drnicwilliams.com/">Dr. Nic</a> recently said on <a href="http://twitter.com">Twitter</a>. It is true. Greatly aided by <a href="http://nubyonrails.com/">Geoffrey Grosenbach&#8217;s</a> screencast on <a href="http://peepcode.com/products/git">git</a>, I myself is starting to feel comfortable enough with git to start abandoning subversion altogether.</p>
<p><a href="http://github.com">Github</a> is great, but there is really no reason to pay for private git repositories unless you need the added functionality. I have a <a href="http://dreamhost.com">Dreamhost</a> account that I am happy with, so why not use that for my private git repos? It is easy to do through SSH, now that git is installed on all Dreamhost servers, but it is not <i>that</i> easy, so I thought I&#8217;d better document it here for my own future reference.</p>
<p>(This stuff is tested on Mac OSX, and should work fine for *nix users. Windows users will have to do some workarounds, but can use this as a reference point.)</p>
<p><span id="more-130"></span></p>
<p><b>Create and add your public key (optional)</b><br />
If you are used to use SSH access with Dreamhost, you probably already have this step setup, but if you don&#8217;t, this will help you avoid having to type your password everyone you connect through SSH, which will be every time you pull and push to and from the git repo on Dreamhost.</p>
<p>If haven&#8217;t done any SSH at all, you will probably need to generate a public/private set of RSA keys:</p>
<pre class="cfcode"><code>
ssh-keygen -t rsa
</code></pre>
<p>Then you&#8217;ll need to to add your public key to your server (thanks to <a href="http://www.davethewave.it/rails-capistrano-dreamhost/">Dave the Wave</a> for this trick):</p>
<pre class="cfcode"><code>
cat .ssh/id_rsa.pub | ssh user@domain.tld 'cat >> .ssh/authorized_keys'
</code></pre>
<p>And with that, you can SSH to the server without typing your password, which is almost a must when doing git over SSH.</p>
<p><b>Create the <code>dreamgit</code> shell script</b><br />
<a href="http://toolmantim.com/article/2007/12/5/setting_up_a_new_remote_git_repository">Toolman Tim</a> explains very well how to setup a remote git repository over SSH, but it is easy to mess things up, and I&#8217;m planning on doing all my stuff in git from now on &#8211; so an automated script to suit my needs is essential.</p>
<p>I am not an expert in either git or shell scripting, so this script can probably be optimized quite a bit &#8211; in fact I am more than willing to update it if I get any comments from the real experts out there. But this script works for me:</p>
<pre class="cfcode"><code>
DREAMGIT_DOMAIN=user@domain.tld
ssh $DREAMGIT_DOMAIN 'mkdir -p ~/git/'$1'.git &#038;&#038; cd ~/git/'$1'.git &#038;&#038; git --bare init'
mkdir $1
cd $1
git init
git remote add origin ssh://$DREAMGIT_DOMAIN/~/git/$1.git
touch .gitignore
git add .
git commit -m 'Created new repo'
git push origin master
echo "
[branch \"master\"]
  remote = origin
  merge = refs/heads/master" >>.git/config
echo "Your new git repo '$1' is ready and initialized at $DREAMGIT_DOMAIN/~/git/$1.git"
</code></pre>
<p>Put the above code into a file you place in a directory in your <code>PATH</code>. Remember to change <code>user@domain.tld</code> to your real Dreamhost SSH user and domain. I&#8217;ve selected to name the command <code>dreamgit</code> and put it in <code>/usr/local/bin</code> like this:</p>
<pre class="cfcode"><code>
sudo mate /usr/local/bin/dreamgit
</code></pre>
<p>Paste the code in and save the file. Make your new command executable:</p>
<pre class="cfcode"><code>
sudo chmod a+x /usr/local/bin/dreamgit
</code></pre>
<p>You now have a new command &#8211; <code>dreamgit</code> &#8211; that you can invoke in any directory on your local machine. You call it with a single argument &#8211; the name of your project &#8211; like this:</p>
<pre class="cfcode"><code>
dreamgit test05

Initialized empty Git repository in /home/.char/cfp/git/test05.git/
Initialized empty Git repository in .git/
Created initial commit f4fbb71: Created new repo
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore
Counting objects: 3, done.
Writing objects: 100% (3/3), 220 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://cfp@casperfabricius.com/~/git/test05.git
 * [new branch]      master -> master
Your new git repo 'test05' is ready and initialized at cfp@casperfabricius.com/~/git/test05.git
</code></pre>
<p>As it says &#8211; you now have a fresh repository ready for action, pulling and pushing to your remote repo at Dreamhost.</p>
<p><b>How it works</b><br />
On the server, it creates a folder named <code>git</code> in your home directory &#8211; if it doesn&#8217;t already exists &#8211; and creates a directory named <code><i>project_name</i>.git</code> in it. It then initializes a <i>bare</i> git repo in that directory, meaning that the repo will hold the git database only, and is not used for doing actual work in.</p>
<p>On your local machine it creates a directory with the project name, initializes a git repo in it, adds an commit an empty <code>.gitignore</code> file to it, and pushes that to the remote repo on your server. Finally it sets up the remote repo to be the default push and pull location for the master branch the local repository. This way, we only have to type <code>git push</code> and <code>git pull</code> without specifying which remote repo and branch we want to interact with.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2008/09/21/keeping-git-repositories-on-dreamhost-using-ssh/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>IE on Mac without Parallels/VMWare</title>
		<link>http://casperfabricius.com/site/2007/10/28/ie-on-mac/</link>
		<comments>http://casperfabricius.com/site/2007/10/28/ie-on-mac/#comments</comments>
		<pubDate>Sun, 28 Oct 2007 15:18:24 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>copenhagenrb</category>
	<category>ies4linux</category>
	<category>x11</category>
	<category>ie6</category>
	<category>macports</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2007/10/28/ie-on-mac/</guid>
		<description><![CDATA[
Benjamin Quorning gave a great tip at the Copenhagen Ruby Brigade mailing list the other day: How to run (Windows) Internet Explorer on your (Intel-based) Mac without having to boot up Parallels, VMWare, or any other kind of time-consuming PC-emulation software. This is made possible by the IEs 4 Linux project (no, that&#8217;s no IE [...]]]></description>
			<content:encoded><![CDATA[<div class="photo right"><img src="/blog/wp-content/uploads/2007/10/ie6screen.png" alt="IE6 on Mac" /></div>
<p><a href="http://www.linkedin.com/in/benjaminquorning">Benjamin Quorning</a> gave a great tip at the <a href="http://copenhagenrb.dk/">Copenhagen Ruby Brigade</a> mailing list the other day: How to run (Windows) Internet Explorer on your (Intel-based) Mac without having to boot up Parallels, VMWare, or any other kind of time-consuming PC-emulation software. This is made possible by the <a href="http://www.tatanka.com.br/ies4linux/">IEs 4 Linux</a> project (no, that&#8217;s no IE 4 on Linux, it&#8217;s IEs <i>for</i> Linux, and IE 4 is not supported, just 6, 5.5 and 5) which provides a simple way to run IE on Linux and, as it turns out, <a href="http://www.tatanka.com.br/ies4linux/page/Does_IEs_4_Linux_Work_with_Mac_OSX">OS X on Intel-based Macs</a>.</p>
<p>While the <a href="http://www.tatanka.com.br/ies4linux/page/Does_IEs_4_Linux_Work_with_Mac_OSX">article</a> on the IEs 4 Linux provides one method for getting this up and running, I tend to like Benjamin&#8217;s more as it uses <a href="http://www.macports.org/">MacPorts</a>, so I&#8217;m going to repeat it here for reference. A prerequisite for the tutorial is to have <a href="http://www.apple.com/macosx/features/x11">X11</a> installed, which is part of the optional developer tools that comes with OS X, and you also need <a href="http://www.macports.org/">MacPorts</a>, which seems to be the best package system for Darwin at the moment.</p>
<p>To install IEs4Linux and its dependencies, execute these commands in your terminal of choice:</p>
<pre>
sudo port install cabextract wget wine
wget http://www.tatanka.com.br/ies4linux/downloads/ies4linux-latest.tar.gz
tar zxvf ies4linux-latest.tar.gz
cd ies4linux-*
./ies4linux
</pre>
<p>The first line installs several components required to run IEs4Linux, most importantly <a href="http://www.winehq.org/">Wine</a>, a framework allowing <a href="http://appdb.winehq.org/">many Windows applications</a> to run on Unix-based systems, including OS X. The other lines download and start the impressively user-friendly installation of IEs4Linux. After completing the installation, Benjamin explains that to run Internet Explorer, you must startup the X11 console (<code>/Applications/Utilities/X11.app</code>) and execute these commands:</p>
<pre>
export PATH="/opt/local/bin:/opt/local/sbin:$PATH"
~/bin/ie6
</pre>
<p>That&#8217;s a bit too inconvenient for my taste, since want to be able to place a link to IE directly in my Dock, or run it by executing a simple command in <a href="http://quicksilver.blacktree.com/">Quicksilver</a>. So I have created a shell script in my home directory (you could also place it in the <code>Applications</code> directory if you like that better) called <code>ie6</code> with the following contents:</p>
<pre>
#!/bin/sh
open-x11 .ies4linux/bin/ie6
</pre>
<p>I also need to make it executable by running <code>chmod +x ie6</code> in the terminal. Now this gives me the ability to execute the shell script from terminal, to call it from Quicksilver (by writing <code>ie6</code>), and to drag it to the right/lower part of the Dock (the part with the trash can in it) with an ugly generic document icon. I want it in my Dock with a nice high quality Internet Explorer icon so I can start just like any other application, and for that purpose I wrapped the shell script as an application:</p>
<p><a href="/blog/wp-content/uploads/2007/10/IE6.zip">Download IE6 application</a></p>
<ul>
<li>Requires IEs4Win to be installed in the default location (~/.ies4win)</li>
<li>Must be dragged to the <code>Applications</code> directory <i>in your home directory</i> (create one if you don&#8217;t have one), not to the general <code>Applications</code> directory (this is due to my limited shell scripting / X11 abilities, <code>~</code> didn&#8217;t seem to work as a reference to the home directory in X11).</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2007/10/28/ie-on-mac/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Inside Rails Engines</title>
		<link>http://casperfabricius.com/site/2006/08/06/inside-rails-engines/</link>
		<comments>http://casperfabricius.com/site/2006/08/06/inside-rails-engines/#comments</comments>
		<pubDate>Sun, 06 Aug 2006 20:36:29 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[engines]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>article</category>
	<category>engines</category>
	<category>title</category>
	<category>aimed</category>
	<category>pure</category>
	<category>parts</category>
	<category>curiosity</category>
	<category>diving</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2006/08/06/inside-rails-engines/</guid>
		<description><![CDATA[Rails Engines are small subsets of an application that can be dropped into any of your Rails applications and handle common parts of the application from scratch. The title might be a bit misleading, since the technical side of this article is really a beginner’s introduction to Rails Engines spiced up with a few tips [...]]]></description>
			<content:encoded><![CDATA[<p>Rails Engines are small subsets of an application that can be dropped into any of your Rails applications and handle common parts of the application from scratch. The title might be a bit misleading, since the technical side of this article is really a beginner’s introduction to Rails Engines spiced up with a few tips and tricks. I&#8217;m not diving into the inner workings of engines &#8211; the &#8220;inside&#8221; part of the title is more aimed against the fact that I&#8217;ve &#8211; out of pure curiosity and as a preparation for this article &#8211; asked the author of the engine plugin and the first and still most popular engines; James Adam, a few questions about his thoughts behind the engines and which direction he wants them to go in.</p>
<p><b>What is an engine?</b><br />
There are two aspects of Rails Engines: There&#8217;s <i>the</i> engine plugin, a standard Rails plugin that you need to install as any other plugin. This plugin enables you install the individual actual engines that you want to use &#8211; the engines are also seen as standard plugins from Rails&#8217; point of view, but they won&#8217;t work without the engine plugin.</p>
<p>An engine works by allowing a large part of the standard Rails application structure (that is; the <code>/app</code> directory in your projects) to exist as a part of the engine. Where a normal plugin only compromises Ruby code (often core extensions and helper classes), an engine are capable of having controllers, views and models that behaves like they are situated in the &#8220;real&#8221; <code>/app</code> directory.</p>
<p>This allows you to reuse a lot of traditional support functionality such as authentication, authorization and user management, a wiki, a shopping basket, a blog, a CMS and so on. Several engine implementations of some of this functionality already exist, most of which can be found through <a href="http://rails-engines.org/">Rails-Engines.org</a>, and while the wonders of CSS can get you a long way in getting these engines to fit into the design of the rest of your app, you will almost certainly want to change some things. Enter Rails Engine&#8217;s biggest advantage: The ability to override individual views and controller actions on a pr. need basis.</p>
<p>Let&#8217;s say you want to add some text and images to the login view of the Login engine, because this action effectively will function as your frontpage. All have to do is to copy the view from the <code>/app/views</code> directory of the engine into the corresponding directory in your own <code>views</code> directory &#8211; and through the magic of the engine plugin, this view now <em>overrides</em> the view that came with the engine. Often you&#8217;ll also need to modify the behavior of various actions supplied by the engine &#8211; you do this simply by creating a controller with the same name as the controller in the engine with action you want to override in your own <code>/app/controllers</code> directory, and define the actions in the controller. The engine plugin is able to combine the controllers of the engine with the ones in your app, so you can both override actions already defined by the engine, and you can add actions to a controller defined by the engine.</p>
<p><b>When should you use an engine?</b><br />
While it is indeed very convenient to be able to drop all this functionality into your app without writing any code your self, you should be aware that this ability is not the primary goal with the original engine plugin, and that many people sees a lot of potential problems in constructing an application from one or more engines. James Adam explained it like this to me in an email:</p>
<blockquote><p>Rails and Ruby make developing applications very easy, so there&#8217;s very little reason why a competent developer couldn&#8217;t write every part of the application that they need, and not rely on any  code from outside. Working in this way has significant benefits, because it puts you in a position where you intimately understand exactly how your application works. There are no mysterious black boxes.</p></blockquote>
<p>So when should you use an engine? James&#8217; original intention with Rails Engines, and the way he continues to use them himself, is by abstracting commonly used application &#8220;chunks&#8221; so they can be reused in his company&#8217;s applications:</p>
<blockquote><p>Where I work, we are working on a varying collection of fundamentally similar applications, all at the same time. They don&#8217;t have widely different requirements in terms of their basic architecture (authentication, importing Excel data, reporting back, loading and storing data and so on&#8230;), so it makes sense that we only maintain a single version of each of these shared aspects. &#8220;Enterprise DRY&#8221;, if you like. This is why engines exists; we wrote the engines plugin to make it possible for use to reuse as much of this shared code as made sense in our situation, in a manner that was easy to maintain where generators aren&#8217;t, but easy to override when the situation required it.</p></blockquote>
<p>As for myself, I gladly use the Login, User, Riki and Substruct engines in several applications, and while I cannot claim that it haven&#8217;t taken an effort to integrate the engines into the application, I&#8217;d still say that it has saved me a considerable amount of time &#8211; especially when I&#8217;m reusing an engine that I already know well. I guess the ultimate DRY-proof solution would be to abstract my own versions of these engines &#8211; probably not to share with others, but use in my own projects working just the way I want them.</p>
<p><b>Implementing the Login and User engines in your application</b><br />
Now to the more tutorial-ish aspects of this article. In this section, I&#8217;ll explain how to implement two of the most commonly used engines in your application. I expect you to have a running Rails application with a functional database connection. I also suggest that you setup a Subversion repository so you can add the plugins as externals, but it is not strictly necessary, just DRY&#8217;er.</p>
<ol>
<li>
		Install the Engine plugin</p>
<ol>
<li>Setup an SVN external attribute to point <code>vendor/plugins/engines</code> to <a href="http://svn.rails-engines.org/engines/tags/rel_1.1.3/">http://svn.rails-engines.org/engines/tags/rel_1.1.3/</a> (or just download the files to that directory).</li>
<li>The engine plugin is automatically loaded by Rails, and nothing visible happens until you install some engines. However, if you are running engines on Edge Rails, you should add this to the very top of <code>config/environment.rb</code>:
<pre style="width:300px;">
# environment.rb
module Engines
  CONFIG = {:edge => true}
end
</pre>
</li>
</ol>
</li>
<li>Install the Login and User engines
<ol>
<li>Setup SVN external attributes to point <code>vendor/plugins/login_engine</code> to <a href="http://svn.rails-engines.org/login_engine/tags/rel_1.0.2/">http://svn.rails-engines.org/login_engine/tags/rel_1.0.2/</a> and <code>vendor/plugins/user_engine</code> to <a href="http://svn.rails-engines.org/user_engine/tags/rel_1.0.1/">http://svn.rails-engines.org/user_engine/tags/rel_1.0.1/</a>.</li>
<li>Create two new migrations; <code>login_engine_schema</code> and <code>user_engine_schema</code>, and copy the contents of the migration(s) in the <code>db/migrations</code> of each engine into each of the new migrations. This way, you can still create the entire database structure with the <code>rails migrate</code>, without the need for running specialized engine tasks.</li>
<li>Add the required configuration and startup code to <code>config/environment.rb</code>. The configuration is well documented in the read me files, so I won&#8217;t dive into that here, but instead provide a sample of my setup:
<pre style="width:400px">
# environment.rb

#####################################################
# Engine setup
#####################################################

module LoginEngine
  config :salt, "not_my_real_salt"
  #...
end

module UserEngine
  config :admin_login, "admin"
  #...
end

Engines.start :login, :user

UserEngine.check_system_roles
Permission.sync rescue false # Ignore any errors here
</pre>
</li>
<li>Add code to <code>application.rb</code> in order to add user authorization to all actions, and to make the user-logic available to helpers and models:
<pre style="width:400px">
# application.rb

require 'login_engine'
require 'user_engine'

class ApplicationController < ActionController::Base

  # Login and User Engines setup
  include LoginEngine
  include UserEngine
  helper :user
  model :user
  before_filter :authorize_action # unless RAILS_ENV == 'test'

end
</pre>
<p>(Be sure to also include Login- and UserEngine in <code>application_helper.rb</code> to make support available to the views.)
</li>
</ol>
</li>
<li>Override views, actions and models as needed</li>
<ul>
<li>A view is overridden by creating a view with the same name in your own app-structure - <i>not</i> by modifying the view directly in the engine. For example; if you want to override the template for the <code>list</code> action of the <code>user</code> controller, simply create the file <code>list.rhtml</code> in <code>/app/views/user/</code>, and this file will be used.</li>
<li>An action is overridden by creating the controller the action belongs to, and defining a function with the same name. For example; if you want to override the <code>list</code> action of the <code>UserController</code> to provide additional data to your list view, you should create the <code>user_controller.rb</code> file in <code>/app/controllers/<code> and define the action:
<pre style="width:400px;">
# user_controller.rb

def list
  # ...
end
</pre>
</li>
<li>Overriding a model is a bit more complicated, since the engine plugin has no clever way of supporting this due to <a href="http://rails-engines.org/wiki/pages/Why+Models+Don%27t+Act+Like+Controllers">various reasons</a>. However, in the Login- and User engines, it is possible to extend the User-model because it is implemented as a namespaced module, which can be included in your own model-file. So if you want to associate a user with, say, a log entry, you can create the file <code>/app/models/user.rb</code> with this code:
<pre style="width:400px;">
# user.rb

class User < ActiveRecord::Base
  include LoginEngine::AuthenticatedUser
  include UserEngine::AuthorizedUser

  has_many :log_entries

end
</pre>
</li>
</ul>
</ol>
<p><b>Tips and tricks</b><br />
Many people complain that it is hard to test your application with authentication and authorization enabled. The easy solution is to add <code>unless RAILS_ENV == 'test'</code> to the <code>before_filter :authorize_action</code> line in <code>application.rb</code>. The better solution is to actually have a loaded user during the tests, since this is what the application generally expects. One way to solve this is to put this in your test case:</p>
<pre>
# /test/fixtures/companies_controller.rb

  def setup
    @controller = CompaniesController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
    @request.session[:user] = User.find(1)
  end
</pre>
<p>Another issue the synchronization of the permissions data for the User engines authorization logic. I'm not entirely happy with the way this work, since the <code>Permission.sync</code> done on system startup tends to fail, which is why I've had to add <code>rescue false</code> to ignore any errors.</p>
<p><b>Some final thoughts</b><br />
Should the standard Rails plugins go in the direction of engines? I asked James Adam this very question, and here is what he answered:</p>
<blockquote><p>
Yes and no. Some things that I feel should be easier in plugins:</p>
<ul>
<li>Managing stylesheets/javscripts/etc in plugins. The engines plugin makes this trivial, and I'll be working on adapting the implementation of this feature so it seems natural in any plugin.</li>
<li>Sharing views in plugins. While you can do that with a plugin (overriding a controller's template_root), that seems like a bit of a kludge. I'd like to see a 'load_path' for views.</li>
</li>
<li>Controlling whether plugins are loaded or not. This is handy for development, and as a side effect, you get control over the plugin load order.</li>
</ul>
<p>What shouldn't be a part of the default plugin system:</p>
<ul>
<li>Overriding aspects of controllers, helpers and views automagically. This behavior is significantly different  from that way that Rails works in a normal situation. Because of this, users should explicitly 'ask' (by installing/creating engines-based plugins) for this behavior, so they know what to expect. This is really the significant addition that engines add beyond what might seem natural for a plugin anyway.</li>
</ul>
</blockquote>
<p>Thank you for Rails Engines, James, and keep up the good work!</p>
<p><b>Additional resources</b></p>
<ul>
<li><a href="http://rails-engines.org/">Home of Rails Engines</a></li>
<li><a href="http://alterlabs.com/ruby/how-to-build-a-ruby-on-rails-engine-in-depth-start-to-finish-tutorial">How to write your own Rails Engine</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2006/08/06/inside-rails-engines/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Deploying Rails with Edge and Engines to Dreamhost using Capistrano</title>
		<link>http://casperfabricius.com/site/2006/05/21/rails-on-dreamhost/</link>
		<comments>http://casperfabricius.com/site/2006/05/21/rails-on-dreamhost/#comments</comments>
		<pubDate>Sun, 21 May 2006 19:59:51 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>combination</category>
	<category>deploying</category>
	<category>circumstances</category>
	<category>strange</category>
	<category>specifically</category>
	<category>microsoft</category>
	<category>documented</category>
	<category>developers</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2006/05/21/rails-on-dreamhost/</guid>
		<description><![CDATA[It&#8217;s not that I&#8217;m the first to describe the process of deploying a Rails application, in fact; it&#8217;s rather well-documented, also when it comes specifically to Dreamhost. It&#8217;s just that I have a strange combination of circumstances that none of these articles cover, and also; I know almost nothing about Unix-based systems &#8211; I don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not that I&#8217;m the first to describe the process of deploying a Rails application, in fact; it&#8217;s rather <a href="#ressources">well-documented</a>, also when it comes specifically to Dreamhost. It&#8217;s just that I have a strange combination of circumstances that none of these articles cover, and also; I know almost nothing about Unix-based systems &#8211; I don&#8217;t even have a Mac. I am one the of many Microsoft-developers who are starting to see the light, and because 	of that, I need to start entirely from scratch when it comes to understanding the whole Linux/Apache/open-source universe.</p>
<p>(<a href="#solution">Take me straight to the solution, please</a>)</p>
<p><strong>My strange combination of circumstances</strong><br />
The Rails application I&#8217;ve had to learn to deploy the hard way has this configuration:</p>
<ul>
<li>Dependent on Rails 1.1.2</li>
<li>Uses <a href="http://www.rails-engines.org/login_engine">Login</a> and <a href="http://www.rails-engines.org/user_engine">User Engine</a>.</li>
<li>Build for MySQL (so no problem there)</li>
<li>Must run with FastCGI, or it&#8217;s too slow</li>
<li>Developed with RadRails on Windows XP (yes, this makes a difference)</li>
<li>Resides in a Subversion repository</li>
</ul>
<p>If you can live with Rails 1.0.0, if you don&#8217;t use Rails Engines, if you don&#8217;t need FastCGI and if you know about Linux, you are probably better off using <a href="#ressources">shorter and simpler tutorials</a>, because these where my specific problems, and what I am going to dvelve into here.</p>
<p><strong>Linux basics</strong><br />
Although it is possible to <a href="http://airhead.typepad.com/airhead/2006/05/windows_on_rail.html">deploy Rails to a Windows server</a> (and presumably not <em>much</em> harder if you can use Apache instead of IIS), Dreamhost, and all other commercial hosts supporting Ruby on Rails, are using Linux servers. You can develop your entire Rails application completely unknowningly about Linux, but when it gets to deployment you have to learn the basics about this strange operating system:</p>
<ul>
<li>You don&#8217;t use Remote Desktop, you use SSH. Remember DOS? When you connect with SSH, you get a text prompt simular to that, and you need to know some basic commands. I recommend using <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">PuTTY</a> for SSH.</li>
<li>Use <code>pwd</code> to print you current directory.</li>
<li>Use <code>ls</code> to print the contents of the current directory.</li>
<li>Use <code>cd</code> (e.g. <code>cd /home/user/</code>) to move into a directory.</li>
<li>Use <code>vim</code> (e.g. <code>vim environment.rb</code>) to quickly view and edit files directly on the server. Press your INSERT button to enable editing, and press ESCAPE, then write <code>:wq</code> to save and exit the file.</li>
</ul>
<p>Now, in a <em>perfect world</em> (see below) you actually shouldn&#8217;t have to know this, because Capistrano would do all the dirty work for you, but let&#8217;s get real: It&#8217;s just not that easy.</p>
<p><strong>In a perfect world</strong><br />
Here is a quick recap of what you would be all needed to do, if the world was perfect or you are extremely lucky and everything works as expected</p>
<ol class="fluffy">
<li>Now, I expect you have already created MySQL database on Dreamhost and entered the connection details into <code>config/database.yml</code> &#8211; otherwise; start out with that.</li>
<li>Create a new fully hosted domain in the Dreamhost panel, and make sure it is configured like this:
<div><img src="http://casperfabricius.com/site/wp-content/uploads/2006/05/dreamhost_rails.png" alt="Dreamhost Rails setup" /></div>
<ul>
<li>FastCGI Support enabled</li>
<li>The user has shell access of the type <code>/bin/bash/</code> (configurable from the Manage Users page)</li>
<li>The web directory points to <code>[yourdomain.com]/current/public</code> (not just <code>[yourdomain.com]/public</code>, since we want to use Capistrano)</li>
<li>(The www option is up to you)</li>
</ul>
<li>SSH to [yourdomain.com] and remove the current directory (containing the public directory) Dreamhost has automatically created. (Capistrano needs to create this as a <a href="http://en.wikipedia.org/wiki/Symbolic_Link">symbolic link</a> later.):
<pre># On your Dreamhost server
[nimitz]$ pwd
/home/cape
[nimitz]$ cd myrailsapp.com/
[nimitz]$ ls
current
[nimitz]$ rm -r current/
[nimitz]$ ls
[nimitz]$</pre>
<ul>
<li>Start PuTTY, enter [yourdomain.com] as Host Name and click Open.</li>
<li>Login with the user you specified when creating the domain</li>
<li>Change to the directory of your Rails application (<code>cd  [yourdomain.com]</code>)</li>
<li>Remove the directories (<code>rm -r current</code>)</li>
</ul>
<li>Download <a href="http://topfunky.com/">Geoffrey Grosenbach&#8217;s</a> <a href="http://topfunky.net/svn/shovel/dreamhost/deploy.rb">Capistrano script</a>, add it to the /config/ directory of your Rails application, and edit it to reflect your setup:
<pre># In config/deploy.rb
set :user, 'cape'
set :application, 'myrailsapp.com'
set :repository, 'http://svn1.cvsdude.com/...'
set :svn_username, "casper"
set(:svn_password) { Capistrano::CLI.password_prompt }</pre>
<ul>
<li><code>:user</code> must match the user you specified when creating the domain</li>
<li><code>:application</code> must be the domain you created</li>
<li><code>:repository</code> must be the url of your Subversion repository for the application, from where Capistrano will grab the code to deploy.</li>
<li><code>:svn_username</code> only have to be present, if your subversion username is different from your Dreamhost shell username.</li>
<li><code>set(:svn_password) { Capistrano::CLI.password_prompt }</code> tells Capistrano to prompt you for your subversion password. This might not be nescessary, if your Dreamhost user is already in a trust relationship with the Subversion server.</li>
</ul>
<li>Edit <code>public/.htaccess</code> and change the line <code>RewriteRule ^(.*)$ dispatch.cgi [QSA,L]</code> to <code>RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]</code>. This tells Apache which file it should execute when a request comes in.</li>
<li><a name="shebang"></a>Edit <code>public/dispatch.fcgi</code> and change the first line from <code>#!c:/ruby/bin/ruby</code> (or something simularly Windowish) to <code>#!/usr/bin/env ruby</code>. This line is called a <em>shebang location</em> and tells Linux where to find the program that are able to execute this file, in our case; this is ruby.</li>
<li>Edit <code>config/enviroment.rb</code> and incomment the line: <code>ENV['RAILS_ENV'] ||= 'production'</code>. Dreamhost says they set this enviroment variable automatically the nice way when using FastCGI &#8211; in my experience, they don&#8217;t. This means you have to incomment the line every time you release, and outcomment it again the develop in the development environment &#8211; in my final <code>deploy.rb</code> I have a much cleaner solution to this problem, so stay tuned.</li>
<li>Open up a Command Window, move into the directory of your Rails Application and run the command <code>rake remote:exec ACTION=setup</code>. (You will need to type your password for the user you specified when creating the domain)</li>
<li>Run <code>rake deploy</code>. If you are really, really lucky, this will actually do the job for you, and you can browse to your application. If you are not, go on &#8230;</li>
</ol>
<p><strong>Finding out what&#8217;s wrong</strong><br />
I&#8217;m going to assume that the steps above sort of worked for you, such that Capistrano was actually able to setup the server and copy the files to the correct directory, but it probably failed by the end of the <code>rake deploy</code> command, because it didn&#8217;t have the permissions to restart the web server. So now when you go to [yourdomain.com] in your browser, you don&#8217;t get a &#8220;Page not found&#8221;, you get a &#8220;Rails application failed to start properly&#8221; after a looong wait.</p>
<p>Since the &#8220;Rails application failed to start&#8221; message is not very information, I am going to start out by giving you a few tips about how to diagnose your failing Rails application. You should be able to distinguish between to scenarios:</p>
<ol>
<li>Your Rails application is not able to run, probably because it can&#8217;t connect to the database or can&#8217;t locate some files</li>
<li>The application can run, but the FastCGI link doesn&#8217;t work, so pages cannot be served</li>
</ol>
<p>It&#8217;s easy to test for the first scenario; just SSH to the server, cd to the directory of your app (<code>cd /home/user/[yourdomain.com]/current/</code>), and run the command <code>ruby script/console production</code>. This attempts to start your Rails app in production mode, and any error messages will be right there on the screen for you.</p>
<p>The second scenario is in fact also pretty easy to test, at least under the assumption that Apache is able to redirect to &#8220;dispatch.fgi&#8221; (but it wasn&#8217;t, you probably wouldn&#8217;t get the  &#8220;Rails application failed to start properly&#8221; error). By running <code>ruby public/dispatch.fgi</code> you actually invoke the same file as the web server, which will often give you handy information.</p>
<p>Once you application is running, you can also get useful debugging information from the log files in the <code>logs</code> directory, but if your Rails app is actually writing to these, you probably have something that are pretty close to work.</p>
<p><strong>Fixing deploy.rb</strong><br />
As I have hinted, I had to make a couple of changes to Geoff&#8217;s &#8220;shovel&#8221; <code>deploy.rb</code> in order to make it run smoothly:</p>
<ol>
<li>To be able to restart the FastCGI-processes in the <code>:restart</code> task, I had to add <code>ruby</code> to the line that restarts, because the reaper-script that restarts is not executable on Dreamhost. So my <code>:restart</code> task now looks like this:
<pre># In config/deploy.rb
task :restart, :roles => :app do
  run "ruby #{current_path}/script/process/reaper --dispatcher=dispatch.fcgi"
end</pre>
</li>
<li>To make Apache able to actually execute <code>dispatch.fcgi</code> our <code>deploy.rb</code> also needs to run a command makes <code>dispatch.fcgi</code> executable. On Unix-based systems, any file can be marked as executable, and the OS will then read the <a href="#shebang">shebang location</a> when the file is invoked. By inserting the task below, <code>dispatch.fcgi</code> will be made executable each time you make a deployment. By naming the task <code>after_symlink</code>, it will be executed after the symbolic link has been moved to point to your new files &#8211; first by then, the <code>current_path</code> variable is available.
<pre># In config/deploy.rb
task :after_symlink, :roles => [:web, :app] do
  # Make dispatcher executable
  run "chmod a+x #{current_path}/public/dispatch.fcgi"
end</pre>
</li>
</ol>
<p><strong>Rails in the /vendor directory</strong><br />
It&#8217;s supposed to be <a href="http://weblog.rubyonrails.org/articles/2005/12/22/freezing-your-rails-when-you-deploy-shared">so easy</a> to use a different version of Rails than the one installed on your host. Just run <code>rake rails:freeze:gems</code> &#8211; or even better: Set <code>/vendor/rails</code> to point to <code>http://dev.rubyonrails.org/svn/rails/tags/rel_X-X-X/</code> (depending on your prefered version) using the <a href="http://svnbook.red-bean.com/en/1.0/ch07s03.html">svn:externals</a> feature of Subversion. However, strange things can happen to your application, once all the core files of Rails are suddenly supposed to be read from the <code>/vendor/rails</code> directory. I had to make three crucial changes to avoid various &#8220;required file not found&#8221; or &#8220;NoMethodError&#8221; messages after I &#8220;froze&#8221; Rails:</p>
<ol class="fluffy">
<li>Move the inclusion of files in <code>config/environenment.rb</code> down to the <em>bottom</em> of this file. For instance; I have <code>require 'taggable'</code> in my <code>environment.rb</code>, and before I &#8220;froze&#8221; Rails it I just had this line at the top without any problems, but after, it suddenly couldn&#8217;t find the taggable stuff, and it only worked when I moved that line down after the whole <code>Rails::Initializer.run do |config|</code> chunk.</li>
<li>Force <code>public/dispatch.fcgi</code> (the file that runs the show) to use the &#8220;frozen&#8221; version of Rails, by replacing the line <code>require 'fcgi_handler'</code> in <code>dispatch.fcgi</code> with this line:
<pre>require File.dirname(__FILE__) + "/../vendor/rails/railties/lib/fcgi_handler"</pre>
</li>
<li>Unfortunately, we also need to edit a file inside the Rails framework itself, putting in the absolute location of a required file instead of just the name of the file, as described in <a href="http://forum.textdrive.com/viewtopic.php?pid=87987#p87606">this post</a>. However, if you use svn:externals like I do, you can&#8217;t just alter a file in <code>vendor/rails</code>, since you don&#8217;t have any commit rights. Furthermore, the location of the line we need to add is specific to our setup on the host, so it would be baaad to hardcode it. That&#8217;s why I came up with a solution letting the deployment script <em>replace</em> this line on the server using the <code>current_path</code> variable available. You could do this with ruby, but I asked one of my hardcore Linux geek friends to write a one-liner that I could just run, and he chose to let Perl make the replace directly in the file for us. This also happens in the <code>after_symlink</code> task:
<pre># In config/deploy.rb
task :after_symlink, :roles => [:web, :app] do
  # Ensure Rails in the vendor dir is used by replacing a line in fcgi_handler.rb
  run "perl -i -pe \"s/require 'dispatcher'/require '#{current_path.gsub(/\//, '\\/')}\\/vendor\\/rails\\/railties\\/lib\\/dispatcher'/\" #{current_path}/vendor/rails/railties/lib/fcgi_handler.rb"
  ...
end</pre>
</ol>
<p><strong>Rails Engines</strong><br />
<a href="http://www.rails-engines.org/">Rails Engines</a> is a brilliant way of creating &#8220;super-plugins&#8221; that acts like small sub-applications inside your application, but where everything can be extended or overriden &#8211; even views! If you don&#8217;t use engines, this small section is irrelevant for you, but I&#8217;d recommend you taking a look a them &#8211; I love them.</p>
<p>There is really only one thing you need to be aware of when you deploy a Rails application to Dreamhost that uses engines and has Rails in the vendor directory, and that is to put this code at the very top of your <code>environment.rb</code>:</p>
<pre># In config/environment.rb
module Engines
  CONFIG = {:edge => true}
end</pre>
<p>One other thing, not really related to deployment: As I am writing this, the LoginEngine has a problem loading two files in its <code>init_engine.rb</code>, so if you get errors in this file, try replacing the two original require statements with this:</p>
<pre># In vendor/plugins/login_engine/init_engine.rb
require 'login_engine/authenticated_user'
require 'login_engine/authenticated_system'</pre>
<p><a name="solution"></a><br />
<strong>Wrapping it up: The complete solution</strong><br />
Today, I am able to run <code>rake deploy</code> and it actually works. My deployment script for Capistrano, based on <a href="http://topfunky.net/svn/shovel/dreamhost/deploy.rb">Geoff&#8217;s shovel</a>, can be downloaded <a href="/blog/files/deployment/deploy.rb">here</a>. Notice that this script, besides the tasks described above, also automatically replaces <code>#ENV['RAILS_ENV'] ||= 'production'</code> with <code>ENV['RAILS_ENV'] ||= 'production'</code> (incomments it) in <code>config/environment.rb</code> to force production environment on the Dreamhost server.</p>
<p>Here is a complete list of files I&#8217;ve uploaded for your reference:</p>
<ul>
<li><a href="/blog/files/deployment/contentsof.htaccess">.htaccess</a> (public/)</li>
<li><a href="/blog/files/deployment/deploy.rb">deploy.rb</a> (config/)</li>
<li><a href="/blog/files/deployment/dispatch.txt">dispatch.fcgi</a> (public/)</li>
<li><a href="/blog/files/deployment/environment.rb">environment.rb</a> (config/)</li>
</ul>
<p>I had to rename some of the files in order to let them be downloadable, but the link listed above has the correct name and the directory the file belongs to.</p>
<p>Please note: You can&#8217;t just dump these four files into your own Rails application and expect things to work. You have to carefully extract the pieces from each file you think you need in order to get your application up and running.</p>
<p>Good luck!</p>
<p><a name="ressources"></a><br />
<strong>Recommended ressources</strong></p>
<ul>
<li><a href="http://nubyonrails.com/pages/shovel_dreamhost">Capistrano Deployment on Dreamhost</a></li>
<li><a href="http://woss.name/2006/01/22/using-switchtower-with-ruby-on-rails-and-dreamhost/">Howto: Using Switchtower with Ruby on Rails and DreamHost</a></li>
<li><a href="http://wiki.dreamhost.com/index.php/Rails">Dreamhost Wiki: Ruby on Rails</a></li>
<li><a href="http://manuals.rubyonrails.com/read/chapter/97">Capistrano manual</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2006/05/21/rails-on-dreamhost/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Getting started using Subversion on Windows</title>
		<link>http://casperfabricius.com/site/2006/04/19/subversion-tutorial/</link>
		<comments>http://casperfabricius.com/site/2006/04/19/subversion-tutorial/#comments</comments>
		<pubDate>Wed, 19 Apr 2006 19:50:16 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[subversion]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>subversion</category>
	<category>tutorial</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2006/04/19/subversion-tutorial/</guid>
		<description><![CDATA[Subversion is a brilliant piece of open-source software for version control. It is the heir of the renowned CVS and suprior to the infamous SourceSafe in every way. This tutorial is not about running a Subversion server &#8211; although it is easy and free &#8211; but about using Subversion for easy collaboration and version control [...]]]></description>
			<content:encoded><![CDATA[<p>Subversion is a brilliant piece of open-source software for version control. It is the heir of the renowned CVS and suprior to the infamous SourceSafe in every way. This tutorial is not about running a Subversion server &#8211; although it is easy and free &#8211; but about using Subversion for easy collaboration and version control in Windows.</p>
<p><strong>What is version control?</strong></p>
<p>Version control is basically about storing different versions of the same files, which enables you to go back previous versions in case you mess something up. Since the files are usually stored on a central server &#8211; often, but not necessarily, accessible from the internet &#8211; a nice side effect of version control is that it enables several people to work with the same set of files simultaneously, by letting everyone syncronize their files with the server.</p>
<p><strong>What is a repository?</strong></p>
<p>Remember the central server running Subversion? This is where the repositories is located. Each repository is a unique and seperate collection of files with a forthrunning version number. You usually create a new repository for each new project you choose to version control, but in case you can&#8217;t just create new repositories, there is no problem in grouping several projects in the same repository.</p>
<p>I assume that you already know two things: The url of the Subversion repository you want to work with, and the username and password to use with it. If not, feel free to expirement with (but not abuse) a test repository I have setup for this tutorial:</p>
<ul>
<li>Url: <a title="Test repository" href="http://svn.casperfabricius.com/sandbox/">http://svn.casperfabricius.com/sandbox/</a></li>
<li>Login: test</li>
<li>Password: test</li>
</ul>
<p><strong>TortoiseSVN &#8211; making Subversion easy</strong></p>
<p><img align="right" alt="Downloading TortoiseSVN" title="Downloading TortoiseSVN" src="http://casperfabricius.com/blog/gfx/download-tortoisesvn.png" /></p>
<p>Your first step is to install TortoiseSVN; a free open-source client for working with Subversion in Windows, which integrates seamlessly with Windows Explorer. Go on; <a title="Download TortoiseSVN" href="http://sourceforge.net/project/showfiles.php?group_id=138498&#038;package_id=151948">download and install</a> the latest version right now! (Select the TortoiseSVN-X.X.X.XXXX-svn- X.X.X.msi file.)</p>
<p>Once installed; start Windows Explorer or open My Computer from your desktop and create a folder a place where you would like to place your first repository &#8211; I usually keep mine in &#8220;C:\Projects&#8221;. Right-click on the folder (or in the &#8220;white space&#8221; inside it) to discover two new items in your context menu: &#8220;SVN Checkout&#8221; and &#8220;TortoiseSVN&#8221;. Select to &#8220;SVN Checkout&#8221; to make the folder your local working folder for the files in the repository. Enter the url of the repository you want to use, or use &#8220;http://svn.casperfabricius.com/sandbox/&#8221;. Enter your username and password (both are case-sensitive) or use test as both if you are checking out my test repository. I recommend that you check the &#8220;Save authentication&#8221; box, unless you are not using your own computer. I might encounter the message saying &#8220;Error validating server certificate &#8230;&#8221; during the process, if the repository is using SSL. It&#8217;s not a problem at all, just select &#8220;Accept Permantly&#8221; and go on with the tutorial. TortoiseSVN will now download any files in the repository to the folder, and add several new items to the context-menu, enabling you to syncronize with the Subversion repository. Your are ready to start using the repository!</p>
<div class="c_clear"></div>
<div class="c_centerlist_left">1.</div>
<div class="c_centerlist_right"><img title="Checkout step 1" alt="Checkout step 1" src="http://casperfabricius.com/blog/gfx/svnscheckout-1.png" /></div>
<div class="c_clear"></div>
<div class="c_centerlist_left">2.</div>
<div class="c_centerlist_right"><img title="Checkout step 2" alt="Checkout step 2" src="http://casperfabricius.com/blog/gfx/svnscheckout-2.png" /></div>
<div class="c_clear"></div>
<div class="c_centerlist_left">3.</div>
<div class="c_centerlist_right"><img title="Checkout step 3" alt="Checkout step 3" src="http://casperfabricius.com/blog/gfx/svnscheckout-3.png" /></div>
<div class="c_clear" /></div>
<p><strong>Commit and update &#8211; your two basic commands</strong></p>
<p>Basically, the point with Subversion is all about sharing your changes with others, and in turn getting their changes reflected in your local working copy of the repository. When you upload you files to the repository on the central server, you are in fact &#8211; in Subversion slang &#8211; <i>commiting</i> your changes. Every time some one commits a change, the Subversion server creates a new version of the repository. Not that it copies every single file in the repository each time a change is commited, but it creates <i>change sets</i> which enables the server to produce an exact copy of the repository in any given version. Even deleted files still exists in previous versions, so once you have commited something, you can always get it back later, no matter what changes other people make.</p>
<p>So how do you actually commit files? You right on the folder or inside the folder with the files you want to commit, and select &#8220;SVN Commit&#8221; from the context menu. This brings up an overview of all the files you have changed <i>and</i> new files that has not yet been <i>added</i> to the repository. You must actively check the box for new (non-versioned) files to get added and committed to the repository. You don&#8217;t have to add all files in the folder to the repository, actually; you should make sure that generated files &#8211; such as dll-files genereated from code files &#8211; are <i>not</i> added to the repository.</p>
<div class="c_clear"></div>
<div class="c_centerlist_left">1.</div>
<div class="c_centerlist_right"><img title="Commit step 1" alt="Commit step 1" src="http://casperfabricius.com/blog/gfx/commit-update.png" /></div>
<div class="c_clear"></div>
<div class="c_centerlist_left">2.</div>
<div class="c_centerlist_right"><img title="Commit step 2" alt="Commit step 2" src="http://casperfabricius.com/blog/gfx/commit-box.png" /></div>
<div class="c_clear"></div>
<div class="c_centerlist_left">3.</div>
<div class="c_centerlist_right"><img title="Commit step 3" alt="Commit step 3" src="http://casperfabricius.com/blog/gfx/commit-status.png" /></div>
<div class="c_clear" /></div>
<p>Updating &#8211; as you have probably guessed by now &#8211; is simply a matter of selecting &#8220;SVN Update&#8221; in the context menu and letting magic happen.</p>
<p><strong>Merging and conflicts &#8211; two people; one file</strong></p>
<p>But what happens if two people make changes to the same file? The scenario goes like this:</p>
<ol>
<li>Bob and Alice both change helloworld.txt</li>
<li>Alice commits her version of the file, unknowingly that Bob has also made changes</li>
<li>Now Bob commits his version of file, but get&#8217;s an error message; his file is out of date</li>
<li>Bob fixes this by updating his local working copy, and most likely; Subversion is able to merge his changes automatically with Alice&#8217;s changes.</li>
<li>If Subversion cannot merge the changes; a conflict occurs.</li>
<li>Bob now needs to navigate to the conflicted file, select &#8220;TortoiseSVN > Edit conflicts&#8221; and the context menu for the file, manually merge the two files using the build-in program, and mark the conflict as resolved.</li>
<li>Bob are now able to commit his version of the file, which contains both his and Alice&#8217;s changes.</li>
<li>The next time Alice update, she gets Bob&#8217;s merged file and everyone is happy</li>
</ol>
<div class="c_clear"></div>
<div class="c_centerlist_left">1.</div>
<div class="c_centerlist_right"><img title="Conflict step 1" alt="Conflict step 1" src="http://casperfabricius.com/blog/gfx/conflict-box.png" /></div>
<div class="c_clear"></div>
<div class="c_centerlist_left">2.</div>
<div class="c_centerlist_right"><img title="Conflict step 2" alt="Conflict step 2" src="http://casperfabricius.com/blog/gfx/conflict-menu.png" /></div>
<div class="c_clear"></div>
<div class="c_centerlist_left">3.</div>
<div class="c_centerlist_right"><img title="Conflict step 3" alt="Conflict step 3" src="http://casperfabricius.com/blog/gfx/mark-as-resolved.png" /></div>
<div class="c_clear" /></div>
<p>Why does it work like this? Why aren&#8217;t the files &#8220;locked&#8221; so only one person can edit a file at the time? Well, for one thing; this way everyone in a team can work unbothered and even offline on the same set of files, and Subversion will (mostly) be able to merge the changes. If you are used to SourceSafe, it will probably take you a bit of time to get used to the idea, but it is &#8211; in my opinion &#8211; by the best way to work. Embrace merging and even conflicts &#8211; they are always easily resolved. If you can&#8217;t; Subversion also supports locking, but that&#8217;s another story.</p>
<p>One last thing: Subversion can&#8217;t (by default) merge binary files. It&#8217;s not a problem storing Word-documents, Visio-diagrams, Photoshop-images etc. in a Subversion repository, but once a conflict occurs; you are on your own.</p>
<p><strong>Rearranging &#8211; renaming, moving and deleting files.</strong></p>
<p>In time; your repositories grow big and ugly, and you&#8217;ll want to rearrange or clean up the mess. When doing this; it&#8217;s important to be aware that you can&#8217;t just rename, move and delete as you usually do it in &#8220;My Computer&#8221; or Windows Explorer. Well, you can, but Subversion won&#8217;t know it, and will consider a renamed or moved a new file, while restoring the file with the old name in it&#8217;s old location on your next update.</p>
<p>For this reason, you should always use the &#8220;Rename&#8221; and &#8220;Delete&#8221; commands in the &#8220;TortoiseSVN&#8221; sub menu in the context menu. This also applies to folders. Also, if you want to move a file to another folder in the repository, you should <i>drag it with right mouse-button</i> and drop it on the folder you want to move it to. This will open a context menu, and when you select &#8220;SVN Move versioned files here&#8221;, TortoiseSVN will make all the dirty work for you, moving the file to it&#8217;s new location.</p>
<p><img title="Rename and delete" alt="Rename and delete" src="http://casperfabricius.com/blog/gfx/rename-delete.png" align="left" /><br />
<img title="Moving a file" alt="Moving a file" src="http://casperfabricius.com/blog/gfx/move.png" align="right" /></p>
<div class="c_clear" /></div>
<p>The result of sticking to using the rename, delete and move command is that the files will automatically renamed, deleted and moved in other peoples local working copies once they update.</p>
<p><strong>How do I get my own Subversion repository?</strong></p>
<p>If you know me personally, I can probably be persuaded to create a repository for you. If you have our own server, or access to one, you can install Subversion following the instructions on <a href="http://subversion.tigris.org/">http://subversion.tigris.org/</a>.</p>
<p>Otherwise, there are plenty of companies that offers to fullfill all your Subversion needs. I can recommend these two, since I use them my selve:</p>
<ul>
<li><a href="http://www.dreamhost.com">Dreamhost</a></li>
<li><a href="http://www.cvsdude.org">CVS Dude</a></li>
</ul>
<p><strong>Conclusion</strong></p>
<p>I could go on for long about other features of Subversion and TortoiseSVN, but with this; the most basic and important commands and functionality are covered. Happy versioning!</p>
<p>Read more:</p>
<ul>
<li><a href="http://subversion.tigris.org/">http://subversion.tigris.org/</a></li>
<li><a href="http://tortoisesvn.tigris.org/">http://tortoisesvn.tigris.org/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2006/04/19/subversion-tutorial/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
