<?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; rails</title>
	<atom:link href="http://casperfabricius.com/site/category/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://casperfabricius.com/site</link>
	<description>A quiet corner of geeky posts</description>
	<lastBuildDate>Mon, 16 Apr 2012 19:14:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<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>admin</dc:creator>
				<category><![CDATA[podio]]></category>
		<category><![CDATA[rails]]></category>

		<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, &#8230; <a href="http://casperfabricius.com/site/2012/01/24/my-first-week-with-sublime-text-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2012/01/24/my-first-week-with-sublime-text-2/feed/</wfw:commentRss>
		<slash:comments>1</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>admin</dc:creator>
				<category><![CDATA[rails]]></category>

		<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 &#8230; <a href="http://casperfabricius.com/site/2010/11/11/launch-bog-nu/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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>
]]></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>admin</dc:creator>
				<category><![CDATA[rails]]></category>

		<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 &#8230; <a href="http://casperfabricius.com/site/2010/10/18/learnings-from-rails-rumble/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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 <img src='http://casperfabricius.com/site/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> , 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>
]]></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>admin</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

		<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 &#8230; <a href="http://casperfabricius.com/site/2010/09/30/ajax-sign-in-and-sign-up-with-devise/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></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>
]]></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>
		<item>
		<title>Google Apps OpenID with Rails and Devise</title>
		<link>http://casperfabricius.com/site/2010/08/09/google-apps-openid-with-rails-and-devise/</link>
		<comments>http://casperfabricius.com/site/2010/08/09/google-apps-openid-with-rails-and-devise/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 19:12:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://casperfabricius.com/site/?p=335</guid>
		<description><![CDATA[Key points The endpoint for federated OpenID login for Google Apps is https://www.google.com/accounts/o8/site-xrds?hd=[myappsdomain.com]. For the Ruby OpenID gem to play nicely with Google Apps, Google&#8217;s own extension gem for this purpose must be loaded and required with require 'gapps_openid'. The &#8230; <a href="http://casperfabricius.com/site/2010/08/09/google-apps-openid-with-rails-and-devise/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><b>Key points</b></p>
<ul>
<li>The endpoint for <a href="http://code.google.com/intl/da/googleapps/domain/sso/openid_reference_implementation.html">federated OpenID login for Google Apps</a> is <code>https://www.google.com/accounts/o8/site-xrds?hd=[myappsdomain.com]</code>.</li>
<li>For the <a href="http://rubygems.org/gems/ruby-openid">Ruby OpenID gem</a> to play nicely with Google Apps, <a href="http://rubygems.org/gems/ruby-openid-apps-discovery">Google&#8217;s own extension gem</a> for this purpose must be loaded and required with <code>require 'gapps_openid'</code>.
</ul>
<p><b>The story</b></p>
<p>I&#8217;ve been working on a client project consolidating most of their various internal databases, spreadsheets and ad-hoc lists into a coherent and centralized web application &#8211; employee lists, inventory and so on. Early on the client said to me: &#8220;Since we are using Google Apps for email, calendar, document sharing and pretty anything else it can do, it would be really nice if we could simply login to the application you are building using our Google Apps logins.&#8221; I said: &#8220;Sure, how hard can it be?&#8221; It was a fair request that made a lot of sense. After all, everybody hates another login to remember, so wouldn&#8217;t it be nice if the employees was simply &#8211; &#8220;as by magic&#8221; &#8211; instantly signed in to this new application?</p>
<p>I knew a lot of people was doing sign in with ordinary Google accounts. I had also implemented it myself for <a href="http://darebusters.com">darebusters</a>, although the easy way using the very nice <a href="https://rpxnow.com/">RPX</a> solution from JanRain. I could see that I could integrate with Google Apps using both OpenID and OAuth. I had some vague ideas about OAuth being &#8220;newer&#8221; and &#8220;cooler&#8221; than OpenID, and also I was using <a href="http://github.com/hassox/warden">Warden</a> and <a href="http://github.com/plataformatec/devise">Devise</a> for authentication, for which a <a href="http://github.com/roman/warden_oauth">nice OAuth extension</a> existed, so I set out to authenticate against Google Apps with OAuth.</p>
<p><span id="more-335"></span></p>
<p>Big mistake: <i>OAuth stands for Open <b>Authorization</b>, not Open <b>Authentication</b></i>. It says so, right there in <a href="http://oauth.net/">the big green box</a>. OAuth is not well suited for authentication, because the standard dictates that new security tokens are generated for every request. The OAuth extension for Warden comes with a nice example for Twitter and my guess is that this works fine. Twitter apparently doesn&#8217;t follow this aspect of the OAuth standard and allows the same security tokens to be used over and over again. This in turn makes it possible to save these tokens in a local database and use them for subsequent authentications without asking the user to sign in again. Not so for Google.</p>
<p>But that&#8217;s what I thought, and so I went ahead and implemented OAuth authentication using the extension for Warden. This was quite a pain to implement, as you mostly get HTTP errors without much detail back when you don&#8217;t do things exactly right. Remember that I didn&#8217;t know that OAuth is not meant for authentication and I was a bit confused as to how I went ahead and simply asked if the user was signed in. I ended up with a solution where I asked Google&#8217;s API for the user&#8217;s email address, since I in turn needed the email to identify the user in my own application. My working implementation was something on the lines of <a href="http://gist.github.com/515846">this</a>, a mechanism that would in fact be very useful if I needed authorization to grab some data from the user&#8217;s Google account. If you want to go down this road, here is a <a href="http://code.google.com/intl/da/apis/accounts/docs/OAuth_ref.html#RequestToken">few</a> <a href="http://code.google.com/intl/da/apis/apps/profiles/developers_guide_protocol.html">useful</a> <a href="http://code.google.com/intl/da/apis/gdata/faq.html#AuthScopes">links</a>.</p>
<p>I must admit I only realized my error when I tried out the implementation thinking as a user. I started asking my self why I had to choose a Google account <i>and</i> authorize the application to retrieve my email <i>every single time</i> I signed in. That was not how this fancy single sign-on thing was supposed to work. That&#8217;s when I took the time to read the aforementioned green box, and <a href="http://code.google.com/intl/da/apis/accounts/docs/GettingStarted.html">Google&#8217;s explanation</a> of when to OAuth and when to use OpenID. So back to square one: I needed Google Apps <i>authentication</i>, and now I knew that OpenID was the way to go. From there it was it was easy to find the <a href="http://github.com/nbudin/devise_openid_authenticatable">devise_openid_authenticatable gem</a> which adds OpenID support to Devise in the  same nice and modular fashion we have come to expect from this great authentication library. Everything is very nicely explained in the <a href="http://github.com/nbudin/devise_openid_authenticatable/blob/master/README.md">readme</a> &#8211; that is, assuming you want to sign in using a &#8220;normal&#8221; OpenID service such as Google Accounts. To make it work with Google Apps, however, there are two minor snags to overcome &#8211; plus an annoyance that can be easily solved:</p>
<p>The OpenID sign in process starts by submitting an identity url to Devise as explained in the readme. For applications offering any OpenID account to authenticate, this identity is left to the user to enter. In this case, however, I wanted a big shiny &#8220;Google&#8221;-button that took the user directly to Google Apps authentication. Easily done by putting the <code>identity_url</code> in a hidden field, but what to use as an identity url (or end point, which was really the case here) for Google Apps &#8211; specifically, what to use to allow only login for the client&#8217;s specific Google Apps domain? A lot of searching &#8211; so much that unfortunately can&#8217;t point to the exact place I found this viable piece of information &#8211; gave me the solution: <code>https://www.google.com/accounts/o8/site-xrds?hd=[myappsdomain.com]</code>.</p>
<p>Next problem: <a href="http://rubygems.org/gems/ruby-openid">Ruby OpenID</a> was acting all up, throwing errors and telling me that it couldn&#8217;t authenticate <code>http://myappsdomain.com/openid?id=100664348167999321563</code>. Huh, no wonder. There was no OpenID server running on my client&#8217;s domain. Google was doing that for us. Long story short, Ruby OpenID expects the user&#8217;s <i>identity url</i> and the <i>end point</i> for authenticating the user to match. I believe they do so on most OpenID services &#8211; it makes a lot of sense &#8211; but not so on Google&#8217;s. Luckily Google has created a gem that patches Ruby OpenID to handle this specific scenario: <a href="http://rubygems.org/gems/ruby-openid-apps-discovery">Apps Discovery</a>. As soon as I installed this gem and required it in my <code>application.rb</code> (it was a Rails 3 app, it would be <code>environment.rb</code> in a Rails 2.x app) with <code>require 'gapps_openid'</code>, things started working. Yay!</p>
<p>Since Devise requires an email to create a user, I couldn&#8217;t use the <code>create_from_identity_url</code> method suggested in the devise_openid_authenticatable readme for creating new users. Rather, I needed to initialize the user here, and then only create him or her later when I also had the email. <a href="http://gist.github.com/515907">This gist</a> shows how I did it.</p>
<p>And the annoyance? Well, since Google&#8217;s OpenID server runs https, you get a lot of warnings from the OpenID library about missing a certificate for ensuring the security of the connection. One way to solve this it to copy the <a href="http://github.com/skrat/ruby-openid-apps-discovery/blob/master/lib/ca-bundle.crt">certificate bundle from Google&#8217;s gem</a> into, say, <code>/config/certs/</code> and then configure OpenID to use it: <code>OpenID.fetcher.ca_file = "#{Rails.root}/config/certs/ca-bundle.crt"</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/08/09/google-apps-openid-with-rails-and-devise/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Delayed Job with i18n</title>
		<link>http://casperfabricius.com/site/2010/06/06/delayed-job-with-i18n/</link>
		<comments>http://casperfabricius.com/site/2010/06/06/delayed-job-with-i18n/#comments</comments>
		<pubDate>Sun, 06 Jun 2010 08:43:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://casperfabricius.com/site/?p=325</guid>
		<description><![CDATA[I have darebusters.com running on Heroku and I have a worker running Delayed Job (DJ) activated. This allows me to handle heavy tasks such as video processing and payment transactions asynchronously, so the dynos can get right back to serving &#8230; <a href="http://casperfabricius.com/site/2010/06/06/delayed-job-with-i18n/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I have <a href="http://darebusters.com/">darebusters.com</a> running on <a href="http://heroku.com/">Heroku</a> and I have a worker running <a href="http://github.com/tobi/delayed_job">Delayed Job</a> (DJ) activated. This allows me to handle heavy tasks such as video processing and payment transactions asynchronously, so the dynos can get right back to serving requests.</p>
<p>I also use DJ to send out emails, and a typical asynchronous call sending a message from one user to another &#8211; scheduling a delayed job &#8211; used to look like this:</p>
<pre><code>UserMailer.send_later(
  :deliver_message,
   @recipient,
  current_user,
  params[:message]
)
</code></pre>
<p>Since darebusters.com is an internationalized website currently offering users the choice between English and German, this has proved a slight challenge, however. We have the usual internationalization (i18n) bells and whistles: Flags to select the language, and remembering the user&#8217;s language selection in session, cookie and in the users database table. By default, a delayed job will simply run with the default locale of the site. It has no way of accessing the context it was invoked in, so it cannot set the locale from session or cookie. The job only knows what it can work it from the arguments it was created with.</p>
<p><span id="more-325"></span></p>
<p>It looks like an easy problem to solve. DJ shouldn&#8217;t have to know about locales, the code should just set <code>I18n.locale</code> from <code>@recipient.locale</code>. That&#8217;s exactly how I initially thought I had solved it: In the <code>UserMailer.message</code> method I set the locale, and then passed parameters to render the mail. The catch is, however, that I use <a href="http://blog.andischacke.com/2009/10/localized-actionmailer-templates-for.html">a slight hack</a> to get support for localized ActionMailer templates, i.e. when the locale is set to <code>de</code> it will render the <code>message.de.text.plain.erb</code> view rather than the <code>message.en.text.plain.erb</code> view. The template to render is selected <i>before</i> <code>UserMailer.message</code> is invoked, so at that time it&#8217;s too late to set the correct locale. In fact, I needed the entire job to run in a locale specified when the job as scheduled.</p>
<p>For this purpose, I created a custom delayed method to be invoked by DJ: LocalizedJob.</p>
<p><script src="http://gist.github.com/427425.js?file=localized_job.rb"></script></p>
<p>This code should be placed in <code>/lib/</code>. I want the <code>send_later_with_i18n</code> to be available on all objects just like DJ&#8217;s own <code>send_later</code>, so I also also created an initializer to extend the <code>Object</code> class:</p>
<p><script src="http://gist.github.com/427428.js?file=delayed_job.rb"></script></p>
<p>This code should be placed in <code>/config/initializers/</code>. I am now able to replace all my <code>send_later</code> calls with <code>send_later_with_i18n</code> calls, storing the required locale with job to be extracted when it&#8217;s run:</p>
<pre><code>UserMailer.send_later_with_i18n(
  :deliver_message,
  @recipient.locale,
  @recipient,
  current_user,
  params[:message]
)
</code></pre>
<p>So on darebusters.com, Germans get all their mails in German &#8211; no matter what locale the sender used (although the actual message written by the sender is of course not translated <img src='http://casperfabricius.com/site/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  &#8211; and everyone else gets mails in English. Now that was a real Ruby fairytale.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/06/06/delayed-job-with-i18n/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bundler and Rails 3 environments</title>
		<link>http://casperfabricius.com/site/2010/04/17/bundler-and-rails-3-environments/</link>
		<comments>http://casperfabricius.com/site/2010/04/17/bundler-and-rails-3-environments/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 13:50:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://casperfabricius.com/site/?p=312</guid>
		<description><![CDATA[I usually write very long blog posts. Not this time! This is just a small tip, the first of hopefully many learnings I&#8217;ll make as I am working with my first project in Rails 3. Bundler (Github &#124; Website) is &#8230; <a href="http://casperfabricius.com/site/2010/04/17/bundler-and-rails-3-environments/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I usually write very long blog posts. Not this time! This is just a small tip, the first of hopefully many learnings I&#8217;ll make as I am working with my first project in Rails 3.</p>
<p>Bundler (<a href="http://github.com/carlhuda/bundler">Github</a> | <a href="http://gembundler.com">Website</a>) is the new way to manage gem dependencies in Rails and other Ruby applications. If you haven&#8217;t heard about it, there is (of course) a <a href="http://railscasts.com/episodes/201-bundler">great introduction at Railcasts</a>. It&#8217;s pretty easy and straight-forward to use, especially if you are used to the <code>config.gem</code> format of Rails.</p>
<p>However, one very common use case in Bundler&#8217;s <code>Gemfile</code> that is not explicitly documented anywhere I&#8217;ve seen, is how to configure gems to be installed in <i>both development and test environments, but not in staging and production environments</i>. You have probably seen the examples of how you can assign a gem to a specific environment using the <code>:group</code> option or method. So you&#8217;d probably write something like this:</p>
<pre>
group :test do
  gem "rspec-rails", ">= 2.0.0.beta.1"
end

group :development do
  gem "ruby-debug"
end
</pre>
<p><span id="more-312"></span></p>
<p>The gems you don&#8217;t need on the server are usually all those related to testing, debugging and perhaps generating fake data and so on. But wait a minute. You also need the RSpec in the development environment so you can use it&#8217;s generators, right? And you need Ruby Debug in the test environment so you can put breakpoints in your tests.</p>
<p>Luckily there is a very easy, and &#8211; once you know it &#8211; obvious solution to this: You can pass multiple environments to the </code>group</code> method, just like this:</p>
<pre>
group :development, :test do
  gem "rspec-rails", ">= 2.0.0.beta.1"
  gem "ruby-debug"
end
</pre>
<p>And that's probably the only grouping of gems you'll need in many Rails projects. Most gems installed and required in all environments, and a few just in the development and test environments. Happy Rails 3 coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/04/17/bundler-and-rails-3-environments/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Community Day &#8217;10 is coming up</title>
		<link>http://casperfabricius.com/site/2010/02/19/community-day-10-is-coming-up/</link>
		<comments>http://casperfabricius.com/site/2010/02/19/community-day-10-is-coming-up/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 21:59:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ironruby]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://casperfabricius.com/site/?p=282</guid>
		<description><![CDATA[I did a well-received talk on ActiveRecord at last year&#8217;s Community Day. Community Day &#8217;09 was the first of its kind in Copenhagen, and it was quite successful in bringing developers with different technical backgrounds together as well as attracting &#8230; <a href="http://casperfabricius.com/site/2010/02/19/community-day-10-is-coming-up/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I did a well-received talk on ActiveRecord at <a href="http://casperfabricius.com/site/2009/05/31/community-day-2009-in-copenhagen/">last year&#8217;s Community Day</a>. Community Day &#8217;09 was the first of its kind in Copenhagen, and it was quite successful in bringing developers with different technical backgrounds together as well as attracting students &#8211; probably because of the free beer <img src='http://casperfabricius.com/site/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://communityday.in/copenhagen/">Community Day in Copenhagen</a> is back again this year, so reserve May 27 if you are near Copenhagen and like free tech-talks, networking and beer. This year <a href="http://danielfrost.dk/">Daniel Frost</a>, the Microsoft evangelist that makes it happen, has involved me and several other developers actively in the planning of the day. With CD &#8217;10 we have raised the level of ambition &#8211; bigger venue, more people, more talks and if course more fun.</p>
<p>We will have <a href="http://communityday.in/copenhagen/Home/Agenda">20 sessions</a> distributed on four concurrent tracks covering a surprisingly wide number of topics &#8211; very few of the talks are on Microsoft-technologies, in fact so few that we might loose a few of those .NET consultants who thinks anything non-MS are not worth listening to <img src='http://casperfabricius.com/site/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Still, if you are doing anything at all related to the web (and most of us are, right?) you will surely find topics such as HTML 5, Single Sign On, Azure, Advanced jQuery etc. interesting.</p>
<p><span id="more-282"></span></p>
<p>I will be giving a talk with the rather bold title &#8220;Replace ASP.NET with IronRuby on Rails&#8221;. It will give me an excuse to seriously dive into IronRuby and how to make a Rails site talk fluently with .NET libraries and assemblies. Coming from a serious amount of ASP.NET development myself, I really think a lot of web-based .NET projects could benefit from Ruby on Rails. The only time I was really happy with ASP.NET was when I switched to that from classic ASP &#8211; but since then, it hasn&#8217;t evolved that much. Granted, ASP.NET MVC has rescued developers from the annyoing &#8220;webform&#8221; structure, but it still has a long way to go.</p>
<p>I&#8217;m getting ahead of myself here, come watch the session &#8211; <a href="http://cd10.eventbrite.com">sign up for Community Day &#8217;10 now</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/02/19/community-day-10-is-coming-up/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multiple Ruby versions with RVM</title>
		<link>http://casperfabricius.com/site/2010/01/24/multiple-ruby-versions-with-rvm/</link>
		<comments>http://casperfabricius.com/site/2010/01/24/multiple-ruby-versions-with-rvm/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 11:47:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://casperfabricius.com/site/?p=276</guid>
		<description><![CDATA[Rails 3 is just around the corner. It is optimized for the better performance and superior features of Ruby 1.9, but it also plays nicely with version 1.8.7. Ruby 1.8.6, on the other hand, cannot run Rails 3. This might &#8230; <a href="http://casperfabricius.com/site/2010/01/24/multiple-ruby-versions-with-rvm/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com/rails/rails/">Rails 3</a> is just around the corner. It is optimized for the better performance and superior features of Ruby 1.9, but it also plays nicely with version 1.8.7. Ruby 1.8.6, on the other hand, cannot run Rails 3. This might not be a problem for you at all. If you are on a Mac, you were probably faced with Ruby 1.8.7 last year at the latest, when the upgrade to Snow Leopard changed the built-in Ruby version from 1.8.6 to 1.8.7. Most applications built for 1.8.6 runs fine on 1.8.7 &#8211; but many servers and deployment environments still runs only 1.8.6.</p>
<p>For me, the situation is like this: My standard version of Ruby on my development machine is 1.8.7. I deploy to many different environments, some (the ones I have a degree of control over) runs 1.8.7 and others (such as Heroku and some customer&#8217;s servers) runs 1.8.6. I can test and code away happily only to get some ugly exceptions when I deploy because I have called <code>count</code> on an array instead of <code>length</code>. Further, I also want to play with the new features of Ruby 1.9 and run Rails 3 on it. And that&#8217;s not to mention that I also use alternative Ruby implementations such as JRuby for projects where I need to tap into Java libraries.</p>
<p><span id="more-276"></span></p>
<p>So that&#8217;s at least four different versions and implementations of Ruby I want to use at various times. I need to compile gems separately for each of them, and I don&#8217;t want them to clutter up my default and very functional Ruby 1.8.7 installation which I still use most of the time. </p>
<p><a href="http://rvm.beginrescueend.com/">Ruby Version Manager</a> (rvm) to the rescue! This very welcome open source project allows us to easily install, manage and switch between multiple Ruby versions and implementations with a single command. The software itself is also easy to install:</p>
<pre><code>
sudo gem install rvm
rvm-install
</code></pre>
<p>Once you have followed the instructions and pasted the line of script into the correct file and restarted (or sourced) your shell, I recommend that you upgrade to the edge version of rvm by running this command:</p>
<pre><code>
rvm update --head
</code></pre>
<p>This gives you access to the newest versions of the installation scripts, and that is needed if you for instance want to install JRuby:</p>
<pre><code>
rvm install jruby
rvm jruby
</code></pre>
<p>That second line is all you need to switch between ruby implementations &#8211; here we switch to JRuby. Note that this is <i>not</i> a system-wide change &#8211; the switch is done simply by changing a few environment variables in your current shell so <code>ruby</code>, <code>rake</code> and so on now refers to the JRuby versions.</p>
<p>One gotcha is that gem will installed the wrong place if you have the <code>â€”user-install</code> flag in your <code>.gemrc</code> file. The only current resolution I know is to remove the flag.</p>
<p>Never the less, I will highly recommend that you install Ruby Version Manager and play with different Ruby version and implementations &#8211; it has never been easier.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/01/24/multiple-ruby-versions-with-rvm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Happy New Year</title>
		<link>http://casperfabricius.com/site/2010/01/01/happy-new-year-2/</link>
		<comments>http://casperfabricius.com/site/2010/01/01/happy-new-year-2/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 15:14:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://casperfabricius.com/site/?p=270</guid>
		<description><![CDATA[Enjoy the new decade &#8211; take care of our world.]]></description>
			<content:encoded><![CDATA[<p><object width="400" height="225"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8456985&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8456985&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"></embed></object></p>
<p>Enjoy the new decade &#8211; take care of our world.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/01/01/happy-new-year-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

