<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>casperfabricius.com</title>
	
	<link>http://casperfabricius.com/site</link>
	<description>expert ruby on rails development</description>
	<lastBuildDate>Tue, 24 Jan 2012 20:05:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/FingerprintsOfCasperFabricius" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="fingerprintsofcasperfabricius" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>My first week with Sublime Text 2</title>
		<link>http://casperfabricius.com/site/2012/01/24/my-first-week-with-sublime-text-2/</link>
		<comments>http://casperfabricius.com/site/2012/01/24/my-first-week-with-sublime-text-2/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 20:05:57 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[podio]]></category>
		<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<category>sublime</category>
	<category>textmate</category>
	<category>textmate</category>
	<category>split</category>
	<category>settings</category>
	<category>tips</category>
	<category>meetup</category>
	<category>alpha</category>
	<category>sublime</category>
	<category>textmate</category>
	<category>textmate</category>
	<category>split</category>
	<category>settings</category>
	<category>tips</category>
	<category>meetup</category>
	<category>alpha</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=478</guid>
		<description><![CDATA[One dark evening in January around 30 geeks gathered at Podio for the monthly meetup in the Copenhagen Ruby Brigade. The only topic on the agenda was a grand showdown between code editors, but with such different editors as Emacs, Vim, Textmate 2, Chocolat, Sublime Text 2 and RubyMine in play, it was more than [...]]]></description>
			<content:encoded><![CDATA[<p>One dark evening in January around 30 geeks gathered at <a href="https://podio.com/">Podio</a> for the monthly meetup in the <a href="http://copenhagenrb.dk/">Copenhagen Ruby Brigade</a>. The only topic on the agenda was a grand showdown between code editors, but with such different editors as Emacs, Vim, Textmate 2, Chocolat, Sublime Text 2 and RubyMine in play, it was more than enough to cover an entire evening.</p>
<p><img src="http://casperfabricius.com/site/wp-content/uploads/2012/01/sublime-297x300.png" alt="" title="Sublime Text" width="297" height="300" class="alignleft size-medium wp-image-486" /></p>
<p>At the time I thought <a href="http://chocolatapp.com/">Chocolat</a> might be the next big thing, but after only two rather frustrating days I went back to Textmate. I still had to present Chocolat at the meetup, but wasn&#8217;t able to say many nice things about it. I also showed off a few features in the <a href="http://blog.macromates.com/2011/textmate-2-0-alpha/">Textmate 2 alpha </a> such as multiple carets (uuh), but as <a href="http://www.creativegenius.dk/">Jesper Christiansen</a> was quick to show us, <a href="http://www.sublimetext.com/">Sublime Text 2</a> could easily match these. During the meetup I started to realize that Sublime Text seemed to be everything many of us had hoped for in Textmate 2, but in software that was available today in a polished, fully functional version, not a just a rather buggy alpha preview.</p>
<p>So I decided to dedicate last week to Sublime Text 2. I installed it Monday and purchased it Friday without looking back. And I&#8217;m still using it today. As a heavy user of Textmate for the past 6-7 years I felt right at home. ⌘+T brings up a file switcher that is slightly more clever and drastically faster than <a href="http://peepcode.com/products/peepopen">PeepOpen</a>, and with that working I could start writing code straight away without feeling less productive than in Textmate. Speaking of the file switcher, I also really like that it instantly shows the file you highlight  as a preview without actually opening it in a tab. This makes it easy to quickly browse around for the right file without opening a horde (a circus?) of tabs.</p>
<p><span id="more-478"></span></p>
<p>Other things that has already increased my productivity is the split view and auto completion. Textmate must be the last decent editor on the planet not to have split view, and now that I&#8217;ve started using it view and stylesheet, model and test and so on, I can&#8217;t believe I&#8217;ve lived without this feature for so long. I&#8217;ve printed out some <a href="https://gist.github.com/1534274">useful shortcuts for Sublime Text</a> and taped them to the side of my monitor, and it pays off to learn the shortcuts for managing and switching split views and tabs. Auto completion may not be that much better than Textmate&#8217;s for a language such as Ruby, but the fact alone that it displays suggestions all the time helps me remember that I can save some typing by pressing tab.</p>
<p>Of course Sublime Text 2 is not perfect out of the box, especially not when you are an old programmer that don&#8217;t want things to change too much too quickly. As friendly people where quick to point out to me on Twitter, the <a href="http://wbond.net/sublime_packages/package_control">package manager</a> is the first package you want to install, and the only one you want to install manually. It is also true that the default icon for Sublime Text does look a lot like the one for the Terminal, so I was quick to follow suit and <a href="http://net.tutsplus.com/tutorials/tools-and-tips/sublime-text-2-tips-and-tricks/">replace it with a more distinctive one</a>.</p>
<p>Essential packages includes SublimeLinter, ZenCoding and the Soda Theme, but coming from Textmate I also liked Textmate ERb style blocks, even though it&#8217;s not exactly perfect. Notice how I don&#8217;t link to those packages, since you just have to enter the name in the package manager to install them. All settings are managed through text files, and while that did seemed a bit primitive to me when I just encountered it, I quickly realized that it makes perfect sense for developers to manage their settings like this &#8211; as long as it is not XML files! Some helpful settings include trim_trailing_white_space_on_save, ensure_newline_at_eof_on_save, file_exclude_patterns and folder_exclude_patterns. A nice site effect of having settings in plain text files is that it&#8217;s easy to synchronize the settings between multiple computers using Dropbox. <a href="http://andrew.hedges.name/blog/2012/01/19/sublime-text-2-more-sublime-with-a-drop-of-dropbox">This guide</a> explains how it&#8217;s done &#8211; it works beautifully.</p>
<p>If you haven&#8217;t tried out Sublime Text 2 yet I suggest you do so <a href="http://www.sublimetext.com/2">right now</a>. If you&#8217;re a power user I&#8217;m sure you wouldn&#8217;t mind sharing a few tips in a comment.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=V-s3X0sY2GA:bUKfQV3YawQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=V-s3X0sY2GA:bUKfQV3YawQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=V-s3X0sY2GA:bUKfQV3YawQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=V-s3X0sY2GA:bUKfQV3YawQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=V-s3X0sY2GA:bUKfQV3YawQ:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2012/01/24/my-first-week-with-sublime-text-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking at RuPy 2011</title>
		<link>http://casperfabricius.com/site/2011/10/01/speaking-at-rupy-2011/</link>
		<comments>http://casperfabricius.com/site/2011/10/01/speaking-at-rupy-2011/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 10:35:44 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[podio]]></category>

	<!-- AutoMeta Start -->
	<category>rupy</category>
	<category>poland</category>
	<category>api</category>
	<category>api</category>
	<category>2011</category>
	<category>python</category>
	<category>podio</category>
	<category>october</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=473</guid>
		<description><![CDATA[I&#8217;m glad to announce that I have been selected to speak at RuPy 2011 with a colleague of mine. RuPy is a conference in Poland about both Ruby and Python, and since we use both at Podio it seemed like a good conference to visit. Also we have yet to hire our first employee from [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m glad to announce that I have been selected to speak at <a href="http://rupy.eu/">RuPy 2011</a> with a colleague of mine. RuPy is a conference in Poland about both Ruby and Python, and since we use both at <a href="https://podio.com/">Podio</a> it seemed like a good conference to visit. Also we have yet to hire our first employee from Poland or any other East European country at Podio, so it could be a good chance for some networking.</p>
<p>The talk is titled &#8220;Dogfood your API&#8221; and is about the <a href="https://developers.podio.com/">Podio API</a> and how our entire web application is based on the API, never making a single direct database call. The API is written in Python and the web app in Ruby in Rails, so we will be able to touch upon both languages and frameworks in our talk.</p>
<p>I&#8217;ll be presenting with Christian Holm, the lead developer of Podio and main developer of the API. He will explain the evolvement of the API and some of the decisions made along the way, whereas I will talk mainly about the <a href="https://github.com/podio/podio-rb">Ruby API client</a> and something we call <i>ActivePodio</i>, which is an attempt to get interacting with a RESTful API to feel a bit like using ActiveRecord.</p>
<p>The talk is in Poznan, Poland on October 14th. If you can&#8217;t make it there, but are near Copenhagen, you can also see our rehearsal of the talk at the <a href="http://copenhagenrb.dk/">Copenhagen Ruby Brigade</a> meeting on October 10th.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=chOXA-Fb7nk:uBjdn1RzWnw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=chOXA-Fb7nk:uBjdn1RzWnw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=chOXA-Fb7nk:uBjdn1RzWnw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=chOXA-Fb7nk:uBjdn1RzWnw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=chOXA-Fb7nk:uBjdn1RzWnw:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2011/10/01/speaking-at-rupy-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running Capybara and RSpec without Rails</title>
		<link>http://casperfabricius.com/site/2011/04/23/running-capybara-and-rspec-without-rails/</link>
		<comments>http://casperfabricius.com/site/2011/04/23/running-capybara-and-rspec-without-rails/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 13:09:08 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[podio]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>capybara</category>
	<category>spec</category>
	<category>specs</category>
	<category>gemfile</category>
	<category>automate</category>
	<category>spec_helper</category>
	<category>automated</category>
	<category>gotcha</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=440</guid>
		<description><![CDATA[Inspired by a recent Railscast on Capybara, I decided to satisfy my holiday coding urges by looking into how Capybara might help us automate more testing at Podio. We are lucky enough to have a full time resource doing quality assurance, and we have often talked about how something like Selenium might help her automate [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by a <a href="http://railscasts.com/episodes/257-request-specs-and-capybara">recent Railscast</a> on <a href="https://github.com/jnicklas/capybara">Capybara</a>, I decided to satisfy my holiday coding urges by looking into how Capybara might help us automate more testing at <a href="https://podio.com">Podio</a>. We are lucky enough to have a full time resource doing quality assurance, and we have often talked about how something like <a href="http://seleniumhq.org/">Selenium</a> might help her automate a number of &#8220;sanity checks&#8221; that we could run before deployments. When I realized how well Capybara work with Selenium&#8217;s web driver, I had to investigate a bit more.</p>
<p>Podio is currently a mix of PHP and Rails (talking to a Python-driven API), and these automated tests of course had to work independently of whether a certain page was in PHP or Rails. Also it would be nice if our QA didn&#8217;t have to have the sites running locally to run the tests. These things ruled out running Capybara inside the Rails application, so I opted for making a seperate, Ruby-only test-suite for automated QA running against our staging server. There is a ton of challenges in this that I haven&#8217;t fully solved yet, most importantly how to manage test data on a separate server. This article only outlines how to get a simple Ruby application (without Rails) up and running that can test a remote site.</p>
<p>First step is to install the bundler gem, create a <code>Gemfile</code> in the root of the application and run the <code>bundle</code> command:<br />
<script src="https://gist.github.com/938578.js?file=Gemfile"></script></p>
<p>The gotcha here is that the &#8220;trunk&#8221; version of the Capybara gem on Github should referenced in the gemfile for compatibility with RSpec 2.</p>
<p><span id="more-440"></span></p>
<p>Second step is to setup a <code>spec_helper.rb</code> file. I created a <code>spec</code> folder in my application directory and put it there:<br />
<script src="https://gist.github.com/938578.js?file=spec_helper.rb"></script></p>
<p>I have some things in my spec helper you might not want: In line 6 I require all files in <code>spec/factories</code>. This is where I put method for generating test data. This has to be done &#8220;by hand&#8221; through Capybara as I am testing against a remote server. In line 10 I configure Capybara to save page snapshots in a directory called <code>snapsshots</code> so I can git ignore the files Capybara generates when using the <code>save_and_open_page</code> method. In lines 20-27 I configure RSpec to open a snapshot of the current page if an exception is raised during a test.</p>
<p>Lastly I place the actual specs within the <code>spec/requests</code> directory, following the RSpec naming conventions for this type of tests:<br />
<script src="https://gist.github.com/938578.js?file=sign_in_spec.rb"></script></p>
<p>One important gotcha here is that the describe block must be followed by the <code>:type => :request</code> option to trigger Capybara. It&#8217;s only within Rails that this type is automatically set for all specs in the <code>requests</code> directory.</p>
<p>What I have now is still very far from the holy grail of automated testing from a user perspective, but it feels like a step in the right direction. If we decide to pursue a setup like this on Podio I&#8217;ll most likely do another blog to follow this one up. If not &#8211; and there unfortunately many things making tests like these very brittle and hard to maintain &#8211; the quest for more and better automated tests continues :)</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=6C9ua48kyO0:k8zfIJ4pTG0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=6C9ua48kyO0:k8zfIJ4pTG0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=6C9ua48kyO0:k8zfIJ4pTG0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=6C9ua48kyO0:k8zfIJ4pTG0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=6C9ua48kyO0:k8zfIJ4pTG0:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2011/04/23/running-capybara-and-rspec-without-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Podio launch in San Francisco</title>
		<link>http://casperfabricius.com/site/2011/03/27/the-podio-launch-in-san-francisco/</link>
		<comments>http://casperfabricius.com/site/2011/03/27/the-podio-launch-in-san-francisco/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 17:17:19 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[podio]]></category>

	<!-- AutoMeta Start -->
	<category>francisco</category>
	<category>san</category>
	<category>podio</category>
	<category>launch</category>
	<category>mashable</category>
	<category>fastcompany</category>
	<category>techcrunch</category>
	<category>store</category>
	<category>francisco</category>
	<category>san</category>
	<category>podio</category>
	<category>launch</category>
	<category>mashable</category>
	<category>fastcompany</category>
	<category>techcrunch</category>
	<category>store</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=428</guid>
		<description><![CDATA[I have just returned from a full week of work, socializing and excitement in San Francisco with my colleagues from Podio, leading up to official launch of Podio: The product is now open for everyone to try out, and a physical store is open in San Francisco where people can walk right in and get [...]]]></description>
			<content:encoded><![CDATA[<p>I have just returned from a full week of work, socializing and excitement in San Francisco with my colleagues from Podio, leading up to official launch of Podio: The product is now open for everyone to try out, and a <a href="https://store.podio.com/">physical store</a> is open in San Francisco where people can walk right in and get started with Podio. I don&#8217;t think anyone ever done something quite like to launch a software product, and it has generated a fair amount of PR with articles in <a href="http://techcrunch.com/2011/03/24/podio-launches-its-workspace-collaboration-platform-app-store-and-app-builder/">TechCrunch</a>, <a href="http://www.fastcompany.com/1741452/podio-employs-a-novel-approach-for-us-launch">FastCompany</a>, <a href="http://www.inc.com/howard-greenstein/a-pop-up-app-store-in-san-francisco.html">Inc. Magazine</a> and <a href="http://mashable.com/2011/03/25/podio/">Mashable</a> just to mention a few.</p>
<p><img src="http://farm6.static.flickr.com/5227/5558819245_ff7627e18d.jpg" alt="Me given a uke solo during the performance of 'The Podios'" /></p>
<p>I joined the Podio team just three months ago, and leading up to this launch we have been working our asses off to provide a top-quality product to make a serious impact on the U.S. market and the rest of the world. The culmination of all this hard work was this launch week in San Francisco and of course the launch party Thursday which more than 300 people showed up for. There is plenty of photos from the week on the <a href="http://www.flickr.com/photos/podio/">Podio account on Flickr</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ZOzS5iPgGVA:psU4nxNb7jU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ZOzS5iPgGVA:psU4nxNb7jU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=ZOzS5iPgGVA:psU4nxNb7jU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ZOzS5iPgGVA:psU4nxNb7jU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=ZOzS5iPgGVA:psU4nxNb7jU:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2011/03/27/the-podio-launch-in-san-francisco/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The next big thing</title>
		<link>http://casperfabricius.com/site/2011/01/01/the-next-big-thing/</link>
		<comments>http://casperfabricius.com/site/2011/01/01/the-next-big-thing/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 08:00:38 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[podio]]></category>

	<!-- AutoMeta Start -->
	<category>podio</category>
	<category>podio</category>
	<category>python</category>
	<category>lucky</category>
	<category>drupal</category>
	<category>exiting</category>
	<category>challenge</category>
	<category>employee</category>
	<category>podio</category>
	<category>podio</category>
	<category>python</category>
	<category>lucky</category>
	<category>drupal</category>
	<category>exiting</category>
	<category>challenge</category>
	<category>employee</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=386</guid>
		<description><![CDATA[Everybody likes to do a bit of reflection by the turn of the year, so I&#8217;ll take the risk of posting yet another non-technical article to this weblog. Since I graduated from Copenhagen Business School 2,5 years ago I&#8217;ve been living out the dream of working full time with Ruby on Rails as a freelance [...]]]></description>
			<content:encoded><![CDATA[<p>Everybody likes to do a bit of reflection by the turn of the year, so I&#8217;ll take the risk of posting yet another non-technical article to this weblog. Since I graduated from Copenhagen Business School 2,5 years ago I&#8217;ve been living out the dream of working full time with Ruby on Rails as a freelance developer. I been lucky enough to work with several entrepreneurs and be part of some very exiting projects from their very beginnings. I&#8217;ve learned that I&#8217;m quite good at getting a project from nothing to something, but that the real challenge is get it from something to Something Great. I&#8217;ve also learned that I enjoy development more when I have other developers to work with, and that a team effort yields better results of a higher quality than when I hack on something all by myself. What a surprise.</p>
<p>Bearing that in mind it might seem an obvious choice now, but I wasn&#8217;t at all considering becoming a full time employee when the opportunity of <a href="https://podio.com">Podio</a> showed itself little more than a month ago. I was not headhunted by Podio, although I would have liked to say that I was. Rather I was asked by them if I knew any Ruby developers that might be interested in applying for a position and that peaked my curiosity. Podio went out of stealth mode in the summer of 2010 and generated a fair amount of hype boasting both high ambitions and leading employees with a proven track record. But technically it was quite uninteresting to us Ruby-worshippers, as it was written in PHP using the Drupal platform. So why was Podio suddenly seeking Ruby-developers?</p>
<p><span id="more-386"></span></p>
<p>Podio is a social work platform that allows users to build their own data structures, workflows and reports. Some call it Facebook for companies, other call it yet another project management tool. You can use it for both of those purposes if you like &#8211; but you can also use it in a complete different way. This is how Podio really differentiates itself from competitors such as Basecamp and Highrise, which are great tools for project management and CRM but works only like 37signals thinks they should &#8211; take it or leave it. In truth I am still struggling with explaining Podio, but if you try it you will see what I mean.</p>
<p>It turned out that Podio had decided to ditch PHP and Drupal and had already rewritten the entire backend to Python. The next step was to rewrite the entire frontend to Ruby on Rails and that challenge was too exiting for me to resist. So I can now count myself amongst the lucky few in Podio&#8217;s development team and employee no. 15 in the company. I look forward to learn a lot from new colleges, put a lot of hard work into the product and help make Podio realize its full potential as a platform built in Ruby/Python right here in Copenhagen.</p>
<p>Happy New Year!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=yI_FgXzsgVo:yC7QlE5rgLs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=yI_FgXzsgVo:yC7QlE5rgLs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=yI_FgXzsgVo:yC7QlE5rgLs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=yI_FgXzsgVo:yC7QlE5rgLs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=yI_FgXzsgVo:yC7QlE5rgLs:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2011/01/01/the-next-big-thing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Merry Christmas</title>
		<link>http://casperfabricius.com/site/2010/12/24/merry-christmas/</link>
		<comments>http://casperfabricius.com/site/2010/12/24/merry-christmas/#comments</comments>
		<pubDate>Fri, 24 Dec 2010 11:46:55 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[other]]></category>

	<!-- AutoMeta Start -->
	<category>christmas</category>
	<category>merry</category>
	<category>interests</category>
	<category>played</category>
	<category>combine</category>
	<category>greeting</category>
	<category>music</category>
	<category>apple</category>
	<category>christmas</category>
	<category>merry</category>
	<category>interests</category>
	<category>played</category>
	<category>combine</category>
	<category>greeting</category>
	<category>music</category>
	<category>apple</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=380</guid>
		<description><![CDATA[Each year around Christmas and New Years I like to find the time to combine my interests in music and video into some sort of of greeting. This year it seems my interest in Apple&#8217;s products has also played a key part ;) I wish you all a very merry Christmas and a happy New [...]]]></description>
			<content:encoded><![CDATA[<p><iframe src="http://player.vimeo.com/video/17717667?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0"></iframe></p>
<p>Each year around Christmas and New Years I like to find the time to  combine my interests in music and video into some sort of of greeting. This year it seems my interest in Apple&#8217;s products has also played a key part ;)</p>
<p>I wish you all a very merry Christmas and a happy New Year.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=lnNNbY45cS8:g5XMmM50K7Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=lnNNbY45cS8:g5XMmM50K7Y:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=lnNNbY45cS8:g5XMmM50K7Y:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=lnNNbY45cS8:g5XMmM50K7Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=lnNNbY45cS8:g5XMmM50K7Y:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/12/24/merry-christmas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Event-driven javascript with jQuery</title>
		<link>http://casperfabricius.com/site/2010/12/12/event-driven-javascript-with-jquery/</link>
		<comments>http://casperfabricius.com/site/2010/12/12/event-driven-javascript-with-jquery/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 23:46:41 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>locations</category>
	<category>postal</category>
	<category>events</category>
	<category>managers</category>
	<category>trigger</category>
	<category>district</category>
	<category>complex</category>
	<category>subscribe</category>
	<category>locations</category>
	<category>postal</category>
	<category>events</category>
	<category>managers</category>
	<category>trigger</category>
	<category>district</category>
	<category>complex</category>
	<category>subscribe</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=369</guid>
		<description><![CDATA[I&#8217;m not exactly a javascript guru, and this article is not exactly rocket science. However, I have done web development for the past 10 years and almost all projects has involved a decent amount of javascript hacking. The past couple of years jQuery has been the obvious choice, but what&#8217;s both good and bad about [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not exactly a javascript guru, and this article is not exactly rocket science. However, I have done web development for the past 10 years and almost all projects has involved a decent amount of javascript hacking. The past couple of years <a href="http://jquery.com/">jQuery</a> has been the obvious choice, but what&#8217;s both good and bad about this framework is that it doesn&#8217;t enforce any specific style of javascript development. Javascript is an amazingly flexible scripting language, and can used both strictly object-oriented, mind-bendingly function-oriented &#8211; and everything in between. I don&#8217;t have a very consistent style other than the basic rule of thumb of &#8220;namespacing&#8221; by wrapping functions within an object to minimize the risk of clashing method definitions.</p>
<p>One of the most advanced javascript-driven pages I have developed is the <a href="http://www.lokalebasen.dk/kontorlokaler/leje/1000-1499-kobenhavn-k">list page of Lokalebasen.dk</a> (it&#8217;s in Danish only, sorry). The page shows a number of locations available for rent in a Danish postal district, and allows you to select more postal districts &#8211; adding more locations to the map and the list &#8211; and to filter the locations by both size and price, thus limiting the number of shown locations. Furthermore any location can be added to the &#8220;shopping cart&#8221;, and behind the scenes all changes of postal districts and filters are reported back to the server for tracking purposes.</p>
<p>The initial javascript driving the page was developed interchanging by me and another developer on the fly as more features was added to the page. It is one of the most important pages on the site, so it has been through many iterations in attempts to both improve usability and optimize business goals. After almost 2 years in production, the javascript for the page reached a complexity level where it started to seemingly make its own decisions about when to do what, and older browsers and slow computers started to have problems handling the page as more and more locations was added. We decided to drastically refactor the javascript, and I realized that an event-driven approach was what we needed to handle all the complex interaction between the different components of the page.</p>
<p><span id="more-369"></span></p>
<p>Events in jQuery works just like you would expect. You can <a href="http://api.jquery.com/live/">subscribe</a> to events and you can <a href="http://api.jquery.com/trigger/">trigger</a> events. Triggering custom events is not something that javascript natively supports, and for that reason it is easy to overlook that jQuery actually makes this very easy. <a href="http://yehudakatz.com/2009/04/20/evented-programming-with-jquery/">This</a> is a more complex example, and <a href="http://www.mostlygeek.com/tech/event-driven-programming-with-jquery/">this</a> explains jQuery a bit more visually.</p>
<p>But back to how I used event-driven javascript to sort out the list page on Lokalebasen.dk. First I defined to javascript &#8220;classes&#8221; representing the two central business entities of the page: <code>Location</code> and <code>PostalDistrict</code>. I&#8217;m not really sure this is best way to define &#8220;classes&#8221; in javascript (I think there&#8217;s a more &#8220;jQuery&#8221; way of doing it), but here&#8217;s some of the <code>Location</code> definition:</p>
<p><script src="https://gist.github.com/737706.js?file=location.js"></script></p>
<p>The <code>PostalDistrict</code> &#8220;class&#8221; was declared in much the same way. Then I went on to define managers for each UI component on the page:</p>
<p><img src="http://casperfabricius.com/site/wp-content/uploads/2010/12/lokalebasen-list.png" width="435" height="409" /></p>
<p>Each manager was responsible for binding to the user-driven events of its UI component (clicks, keypress, etc.) and of triggering appropriate &#8220;abstract&#8221; events as a result. The <code>Postal District Manager</code>, for instance, would bind to the click event of each check box, and when a new postal district was selected it would load the new locations in the district into a global client-side collection of locations, update it&#8217;s own UI component and trigger a global event: <code>$(document).trigger('postal_districts.filterChanged');</code>. All the other managers would in turn be subscribing to this event, since, when new locations are added, the both map and table must be updated to show them, and size and price filters must recalculate number of locations available in each interval.</p>
<p>Another example is that the location must be highlighted on the map when the cursor hovers over the location&#8217;s row in the table, and visa versa. So the <code>Map Manager</code> subscribes to the events &#8220;table.rowMouseOver&#8221; and &#8220;table.rowMouseOut&#8221;, and the <code>Table Manager</code> subcribes to &#8220;map.markerMouseOver&#8221; and &#8220;map.markerMouseOut&#8221;.</p>
<p><script src="https://gist.github.com/737706.js?file=map_manager.js"></script></p>
<p>To bind it all together, I created a <code>Locations Manager</code> which was responsible for instantiating the other managers and for handling the overall state of the locations. This manager figures out which locations are currently visible by asking the different filter managers about their state, and it also reports the actions of the user back to the server for tracking purposes.</p>
<p>As you have probably realized, a seemingly rather simple list page with a map and some filters can result in a rather complex system of interactions and dependencies between various UI components. The <a href="http://en.wikipedia.org/wiki/Publish/subscribe">publish/subscribe pattern</a> has been used by most desktop applications for decades, and as our web applications grow to be more complex we will have adopt and rediscover more of these mature, yet still incredibly useful patterns.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=PZYjoejkYCM:Ts6eDZcqowY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=PZYjoejkYCM:Ts6eDZcqowY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=PZYjoejkYCM:Ts6eDZcqowY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=PZYjoejkYCM:Ts6eDZcqowY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=PZYjoejkYCM:Ts6eDZcqowY:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/12/12/event-driven-javascript-with-jquery/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Launch: bog.nu</title>
		<link>http://casperfabricius.com/site/2010/11/11/launch-bog-nu/</link>
		<comments>http://casperfabricius.com/site/2010/11/11/launch-bog-nu/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 19:38:27 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<category>bog</category>
	<category>score</category>
	<category>score</category>
	<category>books</category>
	<category>prices</category>
	<category>reviews</category>
	<category>meta</category>
	<category>book</category>
	<category>bog</category>
	<category>score</category>
	<category>score</category>
	<category>books</category>
	<category>prices</category>
	<category>reviews</category>
	<category>meta</category>
	<category>book</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=355</guid>
		<description><![CDATA[A few days ago a new Danish community for book lovers and consumers seeking the best book prices was launched: bog.nu (which translates to &#8220;book.now&#8221;.) The website has (of course) been implemented in Ruby on Rails during the last couple of months by Jesper Hvirring and yours truly for the Danish publisher Forlagsgruppen Bindslev. On [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago a new Danish community for book lovers and consumers seeking the best book prices was launched: <a href="http://bog.nu/">bog.nu</a> (which translates to &#8220;book.now&#8221;.) The website has (of course) been implemented in <a href="http://rubyonrails.org/">Ruby on Rails</a> during the last couple of months by <a href="http://productive.dk/">Jesper Hvirring</a> and yours truly for the Danish publisher <a href="http://www.forlagetbindslev.dk/">Forlagsgruppen Bindslev</a>.</p>
<p><a href="http://bog.nu/"><img src="http://casperfabricius.com/site/wp-content/uploads/2010/11/bognu.png" alt="" title="bog.nu" width="435" height="336" class="alignnone size-full wp-image-357" /></a></p>
<p>On one level it can be used simply to compare the prices of one or more books at the leading Danish internet bookstores. The site allows the user to put several books on her virtual bookshelf, and then make a price search showing where she can get all the books cheapest in total, including shipping and handling.</p>
<p>On another level bog.nu collects all the latest reviews of new Danish books, and calculates a &#8220;meta score&#8221; from 0-100 based on all reviews. This allows users to rank their searches not just by typical parameters, but by how well they have been reviewed. This makes it easy to find, say, <a href="http://bog.nu/soeg?search[format]=&#038;search[translated]=&#038;search[published_on_to]=18-11-2010&#038;search[only]=&#038;search[require_reviews]=1&#038;search[include_unavailable]=0&#038;search[published_on_from]=&#038;search[category_id]=23&#038;search[order_by]=overall_score&#038;search[query]=">the best Danish comics</a>.</p>
<p><span id="more-355"></span></p>
<p>Taking this further, bog.nu even allows it users to review any book or title they have read. This is where the social aspect comes in. To being with, a user&#8217;s review score won&#8217;t change the total meta score much, but he gains more trust on the site his reviews can eventually grow to impact the meta score as much as the ones of the professional reviewers.</p>
<p>On a technical level I can tell that the site is fully <a href="http://www.postgresql.org/">PostgreSQL</a>-based, including all search functionality. We evaluated the various tools available for full text indexing and searching, but we ended up simply using what&#8217;s build into Postgres, and we haven&#8217;t regretted that decision. I can also reveal that we crawl all prices <i>live</i> from the bookstore&#8217;s sites by running a separate, lightning-fast crawler application based on <a href="https://github.com/lifo/cramp">Cramp</a> and <a href="http://rubyeventmachine.com/">Eventmachine</a>. Tests are written in <a href="http://rspec.info/">RSpec 2</a> with <a href="https://github.com/thoughtbot/factory_girl">Factory Girl</a> for fixtures and <a href="https://github.com/btakita/rr">RR</a> for stubbing and mocking.</p>
<p>If you like books &#8211; and you know Danish &#8211; you should definitely checkout <a href="http://bog.nu/">bog.nu</a>!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ocQMCasUHxs:j2KSw78ex-E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ocQMCasUHxs:j2KSw78ex-E:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=ocQMCasUHxs:j2KSw78ex-E:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ocQMCasUHxs:j2KSw78ex-E:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=ocQMCasUHxs:j2KSw78ex-E:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/11/11/launch-bog-nu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learnings from Rails Rumble</title>
		<link>http://casperfabricius.com/site/2010/10/18/learnings-from-rails-rumble/</link>
		<comments>http://casperfabricius.com/site/2010/10/18/learnings-from-rails-rumble/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 20:45:46 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<category>rumble</category>
	<category>spaceshippers</category>
	<category>sprints</category>
	<category>game</category>
	<category>stories</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=347</guid>
		<description><![CDATA[Jakob Skjerning, Laust Rud and I has just finished the 48 hour coding marathon that is Rails Rumble. In just two days we have build a web based space trading game from scratch in Ruby on Rails called SpaceShippers. It&#8217;s online, it&#8217;s working and some even think it&#8217;s rather fun. Jakob live-blogged about it. So [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mentalized.net/">Jakob Skjerning</a>, <a href="http://www.personal-it.dk/">Laust Rud</a> and I has just finished the 48 hour coding marathon that is <a href="http://railsrumble.com/">Rails Rumble</a>. In just two days we have build a web based space trading game from scratch in Ruby on Rails called <a href="http://spaceshippers.com/">SpaceShippers</a>. It&#8217;s online, it&#8217;s working and some even think it&#8217;s rather fun. Jakob <a href="http://mentalized.net/journal/2010/10/17/rails_rumble_2010/">live-blogged about it</a>.</p>
<p><a href="http://spaceshippers.com"><img src="http://casperfabricius.com/site/wp-content/uploads/2010/10/Screen-shot-2010-10-18-at-22.42.10.png" width="435" height="381" class="alignnone size-full wp-image-350" /></a></p>
<p>So why did three guys choose to spend their weekend hacking away at space game? Not because we expect fame, riches and the 1st prize in Rails Rumble, that&#8217;s for sure. Before the weekend, none of us had even checked what the competition prizes was. Not because it&#8217;s our only chance to code Ruby on Rails &#8211; all three of us do that in our professional working life every day. But all three of us are consultants, and we mostly code what other people want us to, not what <i>we</i> want to. And let&#8217;s be honest, inside every highly professional business programmer there&#8217;s a little game developer trying to get out. Computer games are great fun, and they don&#8217;t need fully fledged 3D environments to be good &#8211; although it often helps. We considered many other ideas, but I think we ended up during a game because we knew it would be motivating to build something to be entertaining, rather than just another tool or mash-up site.</p>
<p><span id="more-347"></span></p>
<p>The game still needs a work in terms of balance, usability, interaction between players and so on, but considering the limitations, I think it safe to say that we are all <i>very</i> pleased with the result. So how did we do it? What have we learned from our Rails Rumble?</p>
<p>First of all: Planning works. We have had a lot of meetings before the rumble, first deciding what to build and then preparing as much as we could: A flow chart of how the player would progress through the game screens. Mockups of all important screens. A database diagram, which we actually more or less stuck by. We spend quite some time on naming up front, and that meant no time wasted on philosophical naming discussions during the rumble. An overview of the central urls in the game and how they would map to controllers and actions. Central calculations needed for the game mechanics. And very importantly: A breakdown of all functionality into user stories.</p>
<p>Secondly: Agile is (of course) the way to go. Agile doesn&#8217;t mean chaos or changing everything all the time. Not at all. Quite the opposite in fact. We organized our two days into four sprints of about 6 hours each, not including eating and other breaks. We prioritized our backlog of user stories by assigning a business value between 1 and 13 (Fibonacci scale) and put the highest prioritized user stories into the first two sprints before the rumble. To last two sprints we planned Sunday morning, where we could take into consideration all the new user stories we had come up with during the first day. We made sure we had a working game after the first sprint, and that it was deployed after the second sprint, so server setup wouldn&#8217;t be a last minute thing. Also, with an early version online we were able to ask a few people to start playing and provide us with feedback.</p>
<p>In real life sprints are often 14 days long, starting each day with a standing status meeting (sometimes called a <i>scrum</i>). We decided to make each &#8220;working day&#8221; one hour long, and thus have a standing meeting once every hour. To emphasize this, we always had a big timer counting down to the meeting, and a another timer counting down to the final deadline. This helped us to stay focused and motivated. Even though we talked and helped each other all time &#8211; sitting in the same room and all &#8211; having a meeting once every hour was a great opportunity to report and reflect and make important decisions. I can help wonder how things would be if we had a 2-3 minutes meeting once every hour during a normal work day &#8230;</p>
<p>Thirdly: We build a working game without writing a single test. That&#8217;s kind of sad, because all of us a great fans of test-driven development in our professional work life. There were a few times where tests would have saved us a bit of time, but the fact is that the code base you can produce in two days doesn&#8217;t get large and old enough to make tests really important. Tests are critical for maintainability and as documentation, and if we chose to work on with the game we will pay price for having no tests later. But as it where, not writing tests did help us feeling a bit more &#8220;off-work&#8221; and productive during the rumble.</p>
<p>Last, but not least: As many others have said, having a dedicated designer/front-end developer during a Rails Rumble is essential. Even more when you build a game. Jakob was our designer, and I believe he didn&#8217;t write a single piece of &#8220;back-end&#8221; code. Okay, that&#8217;s not true, because he did make adjustments and fixed bugs during crunch time, but I don&#8217;t think he fully implemented any &#8220;back-end&#8221; stuff. That gave him the time that is needed to get a great design and front end implemented, and I think he rather enjoyed completely ignoring the existence of Internet Explorer and using all the newest HTML 5 and CSS 3 features. To be fair, Jakob was also our dedicated system administrator &#8211; he setup the server and wrote the deployment script, and that all just worked. It&#8217;s a funny mix, but I think all Rails Rumble projects needs to have a person assigned to both design and system administration, although the last thing shouldn&#8217;t take up all that person&#8217;s time.</p>
<p>On the technical side, I learned a bit more about Git from Laust (you can never too much about Git ;), and we were quite happy using <a href="https://rpxnow.com/">Janrain Engage</a> and the <a href="http://github.com/slainer68/devise_rpx_connectable>Devise plugin</a> made for it for authentication. We didn&#8217;t really integrate with anything else, and we didn&#8217;t use any big complicated gems. That meant we were never really stuck on any purely technical issues.</p>
<p>All in all, Rails Rumble was great fun. It will be interesting to see how <a href="http://spaceshippers.com/">SpaceShippers</a> is recieved by the Rails Rumble judges, but several people I know (including myself) has already had great fun playing the game, and that makes it all worthwhile.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=Rf9uw-xjWbU:K0ezn0YPYVk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=Rf9uw-xjWbU:K0ezn0YPYVk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=Rf9uw-xjWbU:K0ezn0YPYVk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=Rf9uw-xjWbU:K0ezn0YPYVk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=Rf9uw-xjWbU:K0ezn0YPYVk:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/10/18/learnings-from-rails-rumble/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AJAX sign in and sign up with Devise</title>
		<link>http://casperfabricius.com/site/2010/09/30/ajax-sign-in-and-sign-up-with-devise/</link>
		<comments>http://casperfabricius.com/site/2010/09/30/ajax-sign-in-and-sign-up-with-devise/#comments</comments>
		<pubDate>Thu, 30 Sep 2010 14:55:37 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>dialog</category>
	<category>devise</category>
	<category>devise</category>
	<category>redirect</category>
	<category>sign</category>
	<category>xhr</category>
	<category>failure</category>
	<category>warden</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=342</guid>
		<description><![CDATA[I would never recommend a client to have login and registration in &#8220;pop-up&#8221; dialogs instead of plain pages, but sometimes clients choose to kindly ignore my well meant advise and ask me implement such things anyway. I&#8217;ve just finished version 1 of an upcoming web application implemented with Rails 3 and &#8211; of course &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>I would never recommend a client to have login and registration in &#8220;pop-up&#8221; dialogs instead of plain pages, but sometimes clients choose to kindly ignore my well meant advise and ask me implement such things anyway. I&#8217;ve just finished version 1 of an upcoming web application implemented with Rails 3 and &#8211; of course &#8211; <a href="http://github.com/plataformatec/devise">Devise</a> for authentication, and this app just happens to have sign in and sign up taking place in dialogs (or overlays) and submitted to the server via AJAX. I expected this use of Devise to be pretty common use case, but the implementation turned out be pretty tricky.</p>
<p>Devise is a pretty amazing authentication system. It&#8217;s modular, flexible, highly configurable and lots of extensions have already been built. It does, however, make the assumption that you want to redirect the user to a new page after he has been authenticated. When sign in takes place in a dialog that is submitted via AJAX, a redirect to the frontpage or somewhere else is not of much use. In this case we need to respond with a javascript snippet that either makes a client-side redirect, or &#8211; better yet &#8211; simply closes the sign in dialog and updates any elements on the page that depends on sign in status.</p>
<p>For this particular web application, the scenario was even more complicated. When an unauthenticated user wanted to comment on something, the sign in box would have to pop up in a dialog. If the user wasn&#8217;t registered with the site, he could click a link to get the sign up shown &#8211; still in the same dialog. Whether the user registered or just signed in, the dialog should finally display the form for writing a new comment. All this would have to take place through AJAX without the actual page location ever changing, and here is how I implemented it.</p>
<p><span id="more-342"></span></p>
<p>Devise relies on <a href="http://github.com/hassox/warden">Warden</a> for the actual bread-and-butter authentication, and Warden operates purely at the Rack level without knowing anything about your Rails app as such. When Warden encounters a user that is not signed in on a page where he was supposed to be, it will invoke a <i>failure app</i>: A small rack application that decides what to do with unauthenticated users. A core part of Devise is the <a href="http://rdoc.info/github/plataformatec/devise/master/Devise/FailureApp">Devise::FailureApp</a>, which generally stores where the user wanted to go and then redirects to the sign in page. Not so for an AJAX request &#8211; or or believe the more correct term is <i>XHR request</i>. In this case, Devise returns a HTTP basic authentication pop-up &#8211; yikes! This even happens when http authentication has been disabled by putting <code>config.http_authenticatable = false</code> in <code>config/initializers/devise.rb</code>. Usually, we don&#8217;t want our users to get this ugly basic authentication box, so first step is to build a custom failure app that ensures that http authentication never happens through Devise:</p>
<p><script src="http://gist.github.com/604661.js?file=custom_failure.rb"></script></p>
<p>We configure Warden to use this failure app in the devise initializer:</p>
<p><script src="http://gist.github.com/604661.js?file=devise.rb"></script></p>
<p>The observant reader will have noticed that the <code>redirect_url</code> method is also overridden in <code>CustomFailure</code>. This is necessary because Devise doesn&#8217;t pass on the format of the original request when it redirects, and we need to know in subsequent requests that we are dealing with an XHR request so we can render javascript in response rather than HTML.</p>
<p>That&#8217;s pretty neat so far. However, Devise is still redirecting when the user has authenticated, rather than responding with javascript to close the dialog and update the page. So we need to control what happens after a successful authentication, and that can only be done by overriding the <code>sign_in_and_redirect</code> method of the Devise&#8217;s <code>SessionsController</code> and <code>RegistrationController</code>. We do this by creating our own set of controllers in <code>app/controllers/sessions_controller.rb</code> and <code>app/controllers/registrations_controller.rb</code>. Our new <code>SessionsController</code> looks something like this:</p>
<p><script src="http://gist.github.com/604661.js?file=sessions_controller.rb"></script></p>
<p>I&#8217;ve got to admit that this is not exactly the prettiest Ruby code I have written, but I&#8217;ll leave it as an exercise to the reader to write a beautiful regular expression that can replace lines 10-12. The first couple of lines are unfortunately duplication of the original method, but the information is needed further down. If the action is invoked with an XHR request, the method takes any redirect url (the page the user originally wanted to go to) stored by Devise and makes sure that it&#8217;s called with the &#8220;js&#8221; format. Further it adds an <code>after_authentication=true</code> query string which was needed in this case, because the redirect was going to the <code>CommentsController</code>, which needed to know that it should close the sign in dialog before proceeding with displaying the comment dialog.</p>
<p>If there is no stored url to redirect to, we simply render the <code>after_authentication</code> partial, which in my case closes the sign in dialog and updates the page to indicate that the user has been logged in. If the action is invoked as a standard HTML call, the method simply redirects to <code>super</code>, so that we can still sign in the old fashioned way. Since I needed exactly the same code in my <code>RegistrationsController</code>, I put the method in a module and included that in both of the controllers. You might want to do that too.</p>
<p>The final missing piece is to configure Devise to use our new custom controllers rather than the built-in ones. We do that in <code>routes.rb</code> by means of Devise&#8217;s controller options:</p>
<p><script src="http://gist.github.com/604661.js?file=routes.rb"></script></p>
<p>Even though I&#8217;m not a big supporter of AJAX sign up and sign up &#8211; or of much use AJAX anywhere where a standard page refresh makes just as much sense &#8211; I must admit that the result was a pretty nice user experience in this case. I hope that Devise gains better support for rendering a response rather than redirecting. Until then, you can use this method.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ZR_UIvOaYfg:2taz-xsEKOQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ZR_UIvOaYfg:2taz-xsEKOQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=ZR_UIvOaYfg:2taz-xsEKOQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?a=ZR_UIvOaYfg:2taz-xsEKOQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/FingerprintsOfCasperFabricius?i=ZR_UIvOaYfg:2taz-xsEKOQ:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/09/30/ajax-sign-in-and-sign-up-with-devise/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

