<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>//dennisreimann</title>
  <link href="http://dennisreimann.de/atom.xml" rel="self" />
  <link href="http://dennisreimann.de" />
  <updated>2012-05-15T22:20:22+02:00</updated>
  <id>http://dennisreimann.de/</id>
  <author>
    <name>Dennis Reimann</name>
    <email>mail@dennisreimann.de</email>
  </author>
  <entry>
    <title>Deployment with Vlad</title>
    <link href="http://dennisreimann.de/blog/deployment-with-vlad" />
    <updated>2012-02-11T19:16:00+01:00</updated>
    <id>http://dennisreimann.de/blog/deployment-with-vlad</id>
    <content type="html">
      &lt;p&gt;When I ask people about how they deploy their Rails apps, most of them answer that they are using good old &lt;a href=&quot;http://capify.org&quot;&gt;Capistrano&lt;/a&gt;. It is the most popular solution because it has been around since almost when people started deploying Rails applications and it works well in most cases. However, if you want to do a lot of custom tasks and need to look under the hood to extend it, Capistrano seems somewhat complicated. At least it did at the time I left it in favor of &lt;a href=&quot;http://rubyhitsquad.com/Vlad_the_Deployer.html&quot;&gt;Vlad&lt;/a&gt; - an &lt;em&gt;imho&lt;/em&gt; more intuitive deployment tool.&lt;/p&gt;
            
            &lt;p&gt;Though one might not like the &lt;a href=&quot;http://rubyhitsquad.com/Ruby_Hit_Squad.html&quot;&gt;offense against Capistrano&lt;/a&gt; that was shown when Vlad was released in 2007, it addresses &lt;a href=&quot;http://www.infoq.com/news/2007/08/vlad-the-deployer&quot;&gt;some valid points&lt;/a&gt; when arguing against needless complexity. But enough of the history, this was almost five years ago, both of the tools have improved, made their way and all I wanted to share is some snippets and insights I got from using Vlad over the last years.&lt;/p&gt;
            
            &lt;p&gt;The main thing I like abot Vlad is that it is based on Rake, which makes it so easy to learn, understand and extend. If you want to do something custom, all you have to do is to write a Rake task. And as you will want to use them across different projects, you can even bundle them up and distribute them as a gem, like I&#8217;ve done with &lt;a href=&quot;https://github.com/dbloete/vlad-extras&quot;&gt;vlad-extras&lt;/a&gt;, a set of extensions for tools like DelayedJob, ThinkingSphinx, Monit, Whenever and so on.&lt;/p&gt;
            
            &lt;p&gt;Here is what a simple &lt;code&gt;config/deploy.rb&lt;/code&gt; file might look like:&lt;/p&gt;
            
            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# Custom variables used in the following config&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;appname&quot;&lt;/span&gt;
            
            &lt;span class=&quot;c1&quot;&gt;# Required variables&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.com&quot;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/www/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;git@github.com:myaccount/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.git&quot;&lt;/span&gt;
            
            &lt;span class=&quot;c1&quot;&gt;# Optional variables&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;deploy&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# if different from your current login&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:bundle_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/bin/bundle&quot;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rake_cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bundle_cmd&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; exec rake&quot;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:revision&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;origin/master&quot;&lt;/span&gt;
            
            &lt;span class=&quot;c1&quot;&gt;# vlad-extras config&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:copy_shared&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;config/maintenance.html&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;config/maintenance.html&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;config/database.yml&#39;&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;config/database.yml&#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:symlinks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;assets&#39;&lt;/span&gt;              &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;public/assets&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;config/database.yml&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;config/database.yml&#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy_tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:maintenance:on&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:update&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:symlink&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:bundle:install&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:assets:precompile&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:migrate&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:start_app&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:maintenance:off&lt;/span&gt;
            &lt;span class=&quot;sx&quot;&gt;  vlad:cleanup)&lt;/span&gt;
            
            &lt;span class=&quot;c1&quot;&gt;# Bundler ships with vlad integration you&#39;ll have to require&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# in order to use the vlad:bundle tasks&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;bundler/vlad&#39;&lt;/span&gt;
            
            &lt;span class=&quot;c1&quot;&gt;# Require custom vlad tasks or recipes from vlad-extras&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;vlad/maintenance&#39;&lt;/span&gt;
            
            &lt;span class=&quot;c1&quot;&gt;# Some custom tasks, can be included directly in the deploy file&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:vlad&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:custom_script&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                &lt;span class=&quot;sx&quot;&gt;%w(start stop restart)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; the custom script&quot;&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;remote_task&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:roles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;cd &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_release&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; RAILS_ENV=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rails_env&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&lt;/span&gt;
            &lt;span class=&quot;s2&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bundle_cmd&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; exec ruby script/custom &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;/pre&gt;
            &lt;/div&gt;
            
            
            &lt;p&gt;Here is an example of how easy it is for instance to add staging support:&lt;/p&gt;
            
            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:staging&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rails_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;staging&quot;&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/www/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rails_env&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            
            &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:production&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rails_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;production&quot;&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/www/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rails_env&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;/pre&gt;
            &lt;/div&gt;
            
            
            &lt;p&gt;All you need to do is to change some variables based on the environment that is set with a simple Rake task. You&#8217;d invoke it by running&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;$ bundle exec rake staging vlad:deploy
            &lt;/code&gt;&lt;/pre&gt;
            
            &lt;h3&gt;Gemfile&lt;/h3&gt;
            
            &lt;p&gt;You can include Vlad and it&#8217;s requirements in the development group, because it you do not need it in any other environment. Requiring is done in the &lt;code&gt;Rakefile&lt;/code&gt; like shown below.&lt;/p&gt;
            
            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:development&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
              &lt;span class=&quot;c1&quot;&gt;# Deployment&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;vlad&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:require&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;vlad-git&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:require&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;vlad-extras&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:require&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;/pre&gt;
            &lt;/div&gt;
            
            
            &lt;h3&gt;Rakefile&lt;/h3&gt;
            
            &lt;p&gt;Add this snippet to your Rakefile, just before &lt;code&gt;MyApp::Application.load_tasks&lt;/code&gt;&lt;/p&gt;
            
            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;development?&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;vlad&#39;&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;vlad-extras&#39;&lt;/span&gt;
                &lt;span class=&quot;no&quot;&gt;Vlad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:git&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:nginx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:passenger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LoadError&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Could not load Vlad&#39;&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;/pre&gt;
            &lt;/div&gt;
            
            
            &lt;p&gt;You might have to configure the options given to &lt;code&gt;Vlad.load&lt;/code&gt;.&lt;/p&gt;
            
            &lt;p&gt;If you want to get started, take a look at &lt;a href=&quot;http://hitsquad.rubyforge.org/vlad/&quot;&gt;the documentation&lt;/a&gt; to find out about the parts that this post leaves out.&lt;/p&gt;
            
            &lt;h2&gt;Troubleshooting&lt;/h2&gt;
            
            &lt;p&gt;This part is about some trouble I&#8217;ve had and it is not really Vlad specific. You might encounter these problems when trying to deploy to your production server and maybe these tips and links will help.&lt;/p&gt;
            
            &lt;h3&gt;The deployment shell environment&lt;/h3&gt;
            
            &lt;p&gt;If Vlad does not find some commands, try the following:&lt;/p&gt;
            
            &lt;p&gt;To enable per user PATH environments for ssh logins you need to add to your &lt;code&gt;sshd_config&lt;/code&gt;:&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;PermitUserEnvironment yes
            &lt;/code&gt;&lt;/pre&gt;
            
            &lt;p&gt;After that, restart sshd!&lt;/p&gt;
            
            &lt;p&gt;Then in your users ssh home directory (&lt;code&gt;~/.ssh/environment&lt;/code&gt;), add something to this effect (your mileage will vary):&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;PATH=/opt/ruby-1.9.3/bin:/usr/local/bin:/bin:/usr/bin
            &lt;/code&gt;&lt;/pre&gt;
            
            &lt;p&gt;For details on that, see this article on &lt;a href=&quot;http://zerobearing.com/2009/04/27/capistrano-rake-command-not-found&quot;&gt;setting the deployment shell environment&lt;/a&gt;&lt;/p&gt;
            
            &lt;h3&gt;SSH Agent Forwarding&lt;/h3&gt;
            
            &lt;p&gt;Maybe you also need to configure SSH Agent Forwarding:&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;$ ssh-add ~/.ssh/&lt;private_keyname&gt;
            &lt;/code&gt;&lt;/pre&gt;
            
            &lt;p&gt;Edit your &lt;code&gt;~/.ssh/config&lt;/code&gt; file and add something like this:&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;Host &lt;name&gt;
              HostName &lt;ip or host&gt;
              User &lt;username&gt;
              IdentityFile ~/.ssh/&lt;filename&gt;
              ForwardAgent yes
            &lt;/code&gt;&lt;/pre&gt;
            
            &lt;p&gt;For details on that see this article on &lt;a href=&quot;http://jordanelver.co.uk/articles/2008/07/10/rails-deployment-with-git-vlad-and-ssh-agent-forwarding/&quot;&gt;SSH Agent Forwarding&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Seeds for different environments</title>
    <link href="http://dennisreimann.de/blog/seeds-for-different-environments" />
    <updated>2012-01-25T13:59:00+01:00</updated>
    <id>http://dennisreimann.de/blog/seeds-for-different-environments</id>
    <content type="html">
      &lt;p&gt;Here&#8217;s a little Rails tip for splitting up seed data for various environments:
              Create the folder &lt;code&gt;db/seeds/&lt;/code&gt;. For each environment you want to seed put a file in there named after the env. Your general seeds are put into &lt;code&gt;db/seeds/all.rb&lt;/code&gt;. Here&#8217;s what it might look like:&lt;/p&gt;
              
              &lt;pre&gt;&lt;code&gt;|___seeds
              | |___all.rb
              | |___development.rb
              | |___staging.rb
              | |___production.rb
              |___seeds.rb
              &lt;/code&gt;&lt;/pre&gt;
              
              &lt;p&gt;Change the content of your &lt;code&gt;db/seeds.rb&lt;/code&gt; to something like this:&lt;/p&gt;
              
              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;all&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;seed_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/db/seeds/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.rb&quot;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*** Loading &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; seed data&quot;&lt;/span&gt;
                  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed_file&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
              &lt;/pre&gt;
              &lt;/div&gt;
              
              
              &lt;p&gt;Running &lt;code&gt;rake db:seed&lt;/code&gt; will now load up the seed data defined in &lt;code&gt;db/seeds/all.rb&lt;/code&gt; and the current environment.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Configuring Nginx for the Asset Pipeline</title>
    <link href="http://dennisreimann.de/blog/configuring-nginx-for-the-asset-pipeline" />
    <updated>2011-12-07T15:00:00+01:00</updated>
    <id>http://dennisreimann.de/blog/configuring-nginx-for-the-asset-pipeline</id>
    <content type="html">
      &lt;p&gt;Following up on the series of posts about the Rails Asset Pipeline, here are some things to keep in mind when you are using Nginx as your webserver.&lt;/p&gt;
                
                &lt;h3&gt;Installation via Passenger&lt;/h3&gt;
                
                &lt;p&gt;When you are installing Nginx automatically with the script that comes with Passenger, you will not be able to serve the gzipped file variants that get precompiled. That&#8217;s because Passenger currently does not configure Nginx with the &lt;code&gt;http_gzip_static_module&lt;/code&gt; that would be necessary for including the directive &lt;code&gt;gzip_static on&lt;/code&gt;. I&#8217;ve opened a &lt;a href=&quot;https://github.com/dbloete/passenger/commit/db3a8de7cf3b644831471d2fc2167799c5291070&quot;&gt;pull request&lt;/a&gt; for that, but for now you&#8217;ll have to choose the manual installation, if that&#8217;s what you are after - and why wouldn&#8217;t you?&lt;/p&gt;
                
                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# download and untar nginx&lt;/span&gt;
                wget -O /tmp/nginx.tar.gz http://www.nginx.org/download/nginx-1.0.10.tar.gz
                tar xzvf /tmp/nginx.tar.gz
                rm /tmp/nginx.tar.gz
                
                &lt;span class=&quot;c&quot;&gt;# install nginx via passenger install script, already includes&lt;/span&gt;
                &lt;span class=&quot;c&quot;&gt;# --with-http_ssl_module&lt;/span&gt;
                &lt;span class=&quot;c&quot;&gt;# --add-module for passenger&lt;/span&gt;
                passenger-install-nginx-module --auto --prefix&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/opt/nginx&#39;&lt;/span&gt; --nginx-source-dir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/tmp/nginx-1.0.10&#39;&lt;/span&gt; --extra-configure-flags&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;--with-http_gzip_static_module&quot;&lt;/span&gt;
                &lt;/pre&gt;
                &lt;/div&gt;
                
                
                &lt;p&gt;You might want to change the version and prefix to fit your needs. Like mentioned in the comments you don&#8217;t have to take care of including the passenger or ssl module, because the installation script adds them automatically.&lt;/p&gt;
                
                &lt;h3&gt;Nginx configuration&lt;/h3&gt;
                
                &lt;p&gt;This is already part of the &lt;a href=&quot;http://guides.rubyonrails.org/asset_pipeline.html#in-production&quot;&gt;Asset Pipeline Guide&lt;/a&gt;, but I&#8217;ll mention it here again, so that this article is complete - here are the directives for the assets location config:&lt;/p&gt;
                
                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;^/(assets)/&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;kn&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/path/to/site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                  &lt;span class=&quot;kn&quot;&gt;gzip_static&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                  &lt;span class=&quot;kn&quot;&gt;expires&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                  &lt;span class=&quot;kn&quot;&gt;add_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Cache-Control&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                  &lt;span class=&quot;c1&quot;&gt;# access_log /dev/null;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;/pre&gt;
                &lt;/div&gt;
                
                
                &lt;p&gt;&lt;del&gt;I&#8217;ve also disabled access logging, so that asset requests do not clutter up the log.&lt;/del&gt;&lt;/p&gt;
                
                &lt;p&gt;Mathias &lt;a href=&quot;https://twitter.com/#!/roidrage/status/144335957158658048&quot;&gt;brought up a good point&lt;/a&gt;, why one might not want to do that.&lt;/p&gt;
                
                &lt;h3&gt;Sendfile Header&lt;/h3&gt;
                
                &lt;p&gt;In your app&#8217;s &lt;code&gt;production.rb&lt;/code&gt; you should uncomment to following line, to let Nginx send static files:&lt;/p&gt;
                
                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action_dispatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x_sendfile_header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;X-Accel-Redirect&#39;&lt;/span&gt;
                &lt;/pre&gt;
                &lt;/div&gt;
                
                
                &lt;h3&gt;Verify that it&#8217;s working&lt;/h3&gt;
                
                &lt;p&gt;After deploying the changes, you can check if Nginx is now serving the gzipped compressed versions of your asset files. For that you can use tools like this
                &lt;a href=&quot;http://www.whatsmyip.org/http-compression-test/&quot;&gt;HTTP Compression Tester&lt;/a&gt; and enter the address of your &lt;code&gt;application.js&lt;/code&gt; and &lt;code&gt;application.css&lt;/code&gt;&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Referencing Rails Assets in CoffeeScript</title>
    <link href="http://dennisreimann.de/blog/referencing-rails-assets-in-coffeescript" />
    <updated>2011-12-06T00:45:00+01:00</updated>
    <id>http://dennisreimann.de/blog/referencing-rails-assets-in-coffeescript</id>
    <content type="html">
      &lt;p&gt;Sometimes you&#8217;ll want to refer to your image assets from inside of your CoffeeScript (or JavaScript). While we have &lt;a href=&quot;http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets&quot;&gt;nice helpers for that in SASS&lt;/a&gt; (namely &lt;code&gt;image-path&lt;/code&gt; and &lt;code&gt;image-url&lt;/code&gt;), we would have to resort to appending .erb to every .js or .coffee file, we want to reference images in, so that we could use something like this in there:&lt;/p&gt;
                  
                  &lt;pre&gt;&lt;code&gt;icon = &lt;%= image_path('icon.png') %&gt;
                  &lt;/code&gt;&lt;/pre&gt;
                  
                  &lt;p&gt;I didn&#8217;t like it that way, because ERB inside of CoffeeScript looks odd and having the file end with .erb messes up syntax highlighting. But we can circumvent this easily by adding this (admittedly not the most beautiful) piece of code to one single file that ends on .erb (i.e. &lt;code&gt;images.js.coffee.erb&lt;/code&gt;) and let it provide the helper method we need:&lt;/p&gt;
                  
                  &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&lt;%&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
                  &lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/app/assets/images/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;**&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({})&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                  &lt;span class=&quot;cp&quot;&gt;%&gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
                  
                  &lt;span class=&quot;x&quot;&gt;window.image_path = (name) -&gt;&lt;/span&gt;
                  &lt;span class=&quot;x&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;%=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;[name]&lt;/span&gt;
                  &lt;/pre&gt;
                  &lt;/div&gt;
                  
                  
                  &lt;p&gt;This adds up all images inside of &lt;code&gt;app/assets/images&lt;/code&gt; and makes them available via the global helper method &lt;code&gt;image_path&lt;/code&gt; - your milage may vary, but you get the idea. From there on it&#8217;s simply&lt;/p&gt;
                  
                  &lt;pre&gt;&lt;code&gt;icon = image_path('icon.png')
                  &lt;/code&gt;&lt;/pre&gt;
                  
                  &lt;p&gt;inside of your CoffeeScript (or JavaScript) files and it also works in production as the returned filename contains the digest.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>OpenData Bremen</title>
    <link href="http://dennisreimann.de/blog/opendata-bremen" />
    <updated>2011-11-30T10:00:00+01:00</updated>
    <id>http://dennisreimann.de/blog/opendata-bremen</id>
    <content type="html">
      &lt;p&gt;Im Rahmen des OpenData-Wettbewerbs &lt;a href=&quot;http://apps4deutschland.de/&quot;&gt;Apps4Deutschland&lt;/a&gt; fand in Bremen am Freitag, den 11. November 2011 die Auftaktveranstaltung zu &lt;a href=&quot;http://daten.bremen.de/&quot;&gt;Apps4Bremen&lt;/a&gt; statt. Nach dem &lt;a href=&quot;http://daten.berlin.de/&quot;&gt;Vorbild Berlin&lt;/a&gt; macht nun auch das Land Bremen Teile der Daten staatlicher Stellen öffentlich und läd dazu ein, diese zu verwerten und sinnvoll aufzubereiten - auf der Apps4Deutschland-Website heißt es dazu:&lt;/p&gt;
                    
                    &lt;blockquote&gt;&lt;p&gt;Behörden in Deutschland erheben, speichern und verarbeiten viele interessante Daten. Dazu gehören Wetterdaten ebenso wie Informationen über die Luftqualität oder über die Verwendung der Steuergelder. Diese Daten sind von öffentlichem Interesse und bergen ein großes Potenzial für unsere Gesellschaft, weil sie Transparenz, Beteiligung, Innovationen und neue Dienstleistungen fördern.&lt;/p&gt;
                    
                    &lt;p&gt;Mit dem Wettbewerb „Apps für Deutschland“ laden wir Designer, Entwickler, Journalisten, Forscher und die breite Öffentlichkeit ein, Anwendungen zu schaffen, um diese Daten nutzbar zu machen.&lt;/p&gt;&lt;/blockquote&gt;
                    
                    &lt;p&gt;Da ich das Thema Open Government spannend finde und für sehr wichtig halte, war der Wettberwerb ein guter Anlass, um mir eine neue &lt;a href=&quot;http://bremen.innovated.de/&quot;&gt;Spielwiese für die offenen Daten Bremens&lt;/a&gt; zu schaffen. Das Projekt besteht aktuell nur aus einer &lt;a href=&quot;http://kitas-in-bremen.de&quot;&gt;Übersicht der Bremer Kindertagesstätten&lt;/a&gt;, lässt sich aber auf dem bisherigen Stand gut erweitern, da es bereits Beispiele für Datenimporter, Geokodierung und Darstellung von Orten auf einer Google Map enthält. Basis dafür sind Ruby on Rails und Backbone.js und der &lt;a href=&quot;https://github.com/dbloete/OpenData-Bremen&quot;&gt;Quelltext ist auf GitHub verfügbar&lt;/a&gt;, so dass das Projekt gerne erweitert werden kann. Gerne lasse ich mich auch &lt;a href=&quot;https://github.com/dbloete/OpenData-Bremen/issues&quot;&gt;auf Ideen, Verbesserungswünsche oder Fehler hinweisen&lt;/a&gt;.&lt;/p&gt;
                    
                    &lt;p&gt;Wer sich inspirieren lassen möchte, kann auch mal einen Blick in den &lt;a href=&quot;http://opendata-showroom.org/&quot;&gt;OpenData Showroom&lt;/a&gt; werfen, der Projekte aus aller Welt enthält, die sich offener Daten bedienen. Würde mich freuen, wenn sich viele weitere Leute finden, die mit den Daten was nettes auf die Beine stellen.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Precompiling Rails Assets for Development</title>
    <link href="http://dennisreimann.de/blog/precompiling-rails-assets-for-development" />
    <updated>2011-11-28T15:22:00+01:00</updated>
    <id>http://dennisreimann.de/blog/precompiling-rails-assets-for-development</id>
    <content type="html">
      &lt;p&gt;First off: I love Rails&#8217; &lt;a href=&quot;http://guides.rubyonrails.org/asset_pipeline.html&quot;&gt;asset pipeline&lt;/a&gt; from the bottom of my heart. It&#8217;s a great thing and makes frontend development such a lovely task. There are two little drawbacks though when using it in development: It slows down page reloads and clutters up the log output. Here I&#8217;ll show you how to get rid of that.&lt;/p&gt;
                      
                      &lt;p&gt;When you are mainly doing backend development or most of your apps frontend code doesn&#8217;t change too much do yourself a favor and precompile your assets for the development environment:&lt;/p&gt;
                      
                      &lt;pre&gt;&lt;code&gt;$ RAILS_ENV=development bundle exec rake assets:precompile
                      &lt;/code&gt;&lt;/pre&gt;
                      
                      &lt;p&gt;This really speeds up page reloads as Rails does not need to look up and precompile the asset files every time a request hits the app anymore.&lt;/p&gt;
                      
                      &lt;p&gt;Another change you might want to make is to set &lt;code&gt;config.assets.debug&lt;/code&gt; to false in your development environment. This makes Sprocket concatenate all your files (users.css, search.css, …) into one javascript and stylesheet file (application.css):&lt;/p&gt;
                      
                      &lt;pre&gt;&lt;code&gt;config.assets.debug = false
                      &lt;/code&gt;&lt;/pre&gt;
                      
                      &lt;p&gt;This also cleans up the noisy logging info concerning the asset files that were previously loaded one by one.&lt;/p&gt;
                      
                      &lt;p&gt;When you need to precompile additional assets that aren&#8217;t already referenced in you application.js or application.css you&#8217;ll want to move the &lt;code&gt;config.assets.precompile&lt;/code&gt; directive from production.rb to application.rb:&lt;/p&gt;
                      
                      &lt;pre&gt;&lt;code&gt;config.assets.precompile += %w( search.js )
                      &lt;/code&gt;&lt;/pre&gt;
                      
                      &lt;p&gt;This isn&#8217;t directly related but while you are at speeding up our development experience you might also want to have a look at the &lt;a href=&quot;https://github.com/wavii/rails-dev-tweaks&quot;&gt;rails-dev-tweaks&lt;/a&gt; gem. This gem defines rules for managing what files get reloaded on page requests in development.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Setting up Ubuntu with Teleport</title>
    <link href="http://dennisreimann.de/blog/setting-up-ubuntu-with-teleport" />
    <updated>2011-11-15T14:15:00+01:00</updated>
    <id>http://dennisreimann.de/blog/setting-up-ubuntu-with-teleport</id>
    <content type="html">
      &lt;p&gt;Some time ago I came across &lt;a href=&quot;https://github.com/gurgeous/teleport&quot;&gt;Teleport&lt;/a&gt; which pitches itself as a lightweight way to set up Ubuntu machines. Having failed at mastering the steep learning curve that full-blown tools like &lt;a href=&quot;http://www.opscode.com/chef/&quot;&gt;Chef&lt;/a&gt; or &lt;a href=&quot;http://projects.puppetlabs.com/projects/puppet&quot;&gt;Puppet&lt;/a&gt; provide, I was willing to give Teleport a shot. Teleport stays simple by focusing on Ubuntu and providing just the right set of tools to set up the whole Ruby/Rails eco system. This makes it less powerful than the other aforemention tools, but in my case it&#8217;s just what I was looking for.&lt;/p&gt;
                        
                        &lt;h3&gt;Some facts: Teleport …&lt;/h3&gt;
                        
                        &lt;ul&gt;
                        &lt;li&gt;consists of a configuration (Telfile) plus files you want to be present on the target&lt;/li&gt;
                        &lt;li&gt;copies itself onto the target via ssh and then runs itself there (hence the name)&lt;/li&gt;
                        &lt;li&gt;works idempotently - run it over and over again without breaking the target&lt;/li&gt;
                        &lt;/ul&gt;
                        
                        
                        &lt;h3&gt;My setup&lt;/h3&gt;
                        
                        &lt;p&gt;For each project I store everything that belongs to Teleport in a specific &lt;code&gt;deployment&lt;/code&gt; folder. This folder might look something like this:&lt;/p&gt;
                        
                        &lt;pre&gt;&lt;code&gt;|____Telfile
                        |____recipes
                        | |____install_passenger_nginx.rb
                        |____files
                        | |____etc
                        | | |____gemrc
                        | | |____init.d
                        | | | |____nginx
                        | |____Gemfile
                        | |____Gemfile.lock
                        | |____opt
                        | | |____nginx
                        | | | |____conf
                        | | | | |____nginx.conf
                        &lt;/code&gt;&lt;/pre&gt;
                        
                        &lt;p&gt;The configuration is done inside the &lt;code&gt;Telfile&lt;/code&gt;:&lt;/p&gt;
                        
                        &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;deploy&quot;&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;ruby&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1.9.3&quot;&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;my-own-vps&quot;&lt;/span&gt;
                        
                        &lt;span class=&quot;n&quot;&gt;apt&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;deb http://ppa.launchpad.net/chris-lea/node.js/ubuntu lucid main&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;C7917B12&quot;&lt;/span&gt;
                        
                        &lt;span class=&quot;n&quot;&gt;packages&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(openssl libreadline5 libreadline5-dev curl&lt;/span&gt;
                        &lt;span class=&quot;sx&quot;&gt;  git-core libopenssl-ruby libcurl4-openssl-dev imagemagick&lt;/span&gt;
                        &lt;span class=&quot;sx&quot;&gt;  libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev&lt;/span&gt;
                        &lt;span class=&quot;sx&quot;&gt;  libmysqlclient-dev mysql-client mysql-server nodejs)&lt;/span&gt;
                        
                        &lt;span class=&quot;n&quot;&gt;recipes&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(&lt;/span&gt;
                        &lt;span class=&quot;sx&quot;&gt;  install_passenger_nginx.rb)&lt;/span&gt;
                        &lt;/pre&gt;
                        &lt;/div&gt;
                        
                        
                        &lt;p&gt;&lt;code&gt;user&lt;/code&gt; defines the name of the account you will later use to deploy your app. This user gets added to the sudoers and your ssh key is uploaded for password-less login. &lt;code&gt;ruby&lt;/code&gt; tells Teleport which version to install and &lt;code&gt;server&lt;/code&gt; is the name you gave to the machine in your &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
                        
                        &lt;p&gt;As you can see you can also define customs apts and packages that should get installed. For performing special setup routines or invoking more complex tasks you can utilize the &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki/Recipes&quot;&gt;recipes&lt;/a&gt; feature. Recipes are standalone files that can be written in Ruby and allow for sharing and reuse. Here&#8217;s an example of how to install nginx via the passenger gem:&lt;/p&gt;
                        
                        &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gem_version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;passenger&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`passenger-config --version`&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;
                        
                        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt;
                          &lt;span class=&quot;nb&quot;&gt;warn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Passenger is not installed. Please add it to your Gemfile.&quot;&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;banner&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Passenger &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; is already installed&quot;&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;banner&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Installing Nginx via Passenger (installed: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, gem version: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;passenger-install-nginx-module&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(--auto --auto-download --prefix=/opt/nginx)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# install without prompting&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;update-rc.d nginx defaults&quot;&lt;/span&gt;                                                      &lt;span class=&quot;c1&quot;&gt;# activate autostart&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;service nginx restart&quot;&lt;/span&gt;                                                           &lt;span class=&quot;c1&quot;&gt;# restart nginx&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                        &lt;/pre&gt;
                        &lt;/div&gt;
                        
                        
                        &lt;p&gt;The files directory contains files and directories that get copied over to the target machine - not much magic about that. To install system-wide gems you can place a Gemfile and Gemfile.lock inside the files directory.&lt;/p&gt;
                        
                        &lt;p&gt;Finally you can run the setup with&lt;/p&gt;
                        
                        &lt;pre&gt;&lt;code&gt;$ teleport my-own-vps
                        &lt;/code&gt;&lt;/pre&gt;
                        
                        &lt;p&gt;Keep in mind that you can re-run this every time you make a change to the Telfile or add new files. Teleport strives to be idempotent and can be run  repeatedly without breaking the target machine(unless you explicitely messed up something ;)).&lt;/p&gt;
                        
                        &lt;h3&gt;Let&#8217;s go…&lt;/h3&gt;
                        
                        &lt;p&gt;There is much more to Teleport than what I could cover in this short post. For example you can define &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki#wiki-telfile&quot;&gt;multiple servers with different roles&lt;/a&gt; or &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki#wiki-infer&quot;&gt;reverse engineering existing servers&lt;/a&gt; which makes it very easy to generate a Telfile from your current setup. In case you want to get started head over to the &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki&quot;&gt;project wiki&lt;/a&gt; which contains a lot of information and examples.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Capybara Finder for Cucumber Rails&#8217; Deprecated Tableish</title>
    <link href="http://dennisreimann.de/blog/capybara-finder-for-cucumber-rails-deprecated-tableish" />
    <updated>2011-11-12T22:35:00+01:00</updated>
    <id>http://dennisreimann.de/blog/capybara-finder-for-cucumber-rails-deprecated-tableish</id>
    <content type="html">
      &lt;p&gt;The cucumber-rails gem recently &lt;a href=&quot;https://github.com/cucumber/cucumber-rails/issues/145&quot;&gt;deprecated the tableish method&lt;/a&gt; which could be used to verify data in tables using &lt;a href=&quot;https://github.com/cucumber/cucumber/wiki/multiline-step-arguments&quot;&gt;Table#diff!&lt;/a&gt;. Tableish was easy to use but also had some limitations so that from now on you are advised to use Capybara&#8217;s finder API which is much more flexible.&lt;/p&gt;
                          
                          &lt;p&gt;In case you are now searching for a replacement for tableish, look no further:&lt;/p&gt;
                          
                          &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;table#selector&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;tr&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;th,td&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;expected_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diff!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;/pre&gt;
                          &lt;/div&gt;
                          
                          
                          &lt;p&gt;This maps the table into a two dimensional array containing all cell contents. The last line diffs this array against the &lt;code&gt;expected_table&lt;/code&gt; which is the table that&#8217;s passed into the step definition like explained on this &lt;a href=&quot;https://github.com/cucumber/cucumber/wiki/multiline-step-arguments&quot;&gt;Cucumber wiki page&lt;/a&gt;.&lt;/p&gt;
                          
                          &lt;p&gt;You&#8217;ll have to replace &lt;code&gt;table#selector&lt;/code&gt; with the actual table selector you are looking for.&lt;/p&gt;
                          
                          &lt;p&gt;When using capybara-webkit for testing elements that get inserted into the page via JavaScript I had to change this a little bit, because the finder did not seem to work with capybara-webkit. One can circumvent this by parsing the page body and using the finder on the new result:&lt;/p&gt;
                          
                          &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Capybara&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Simple&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;table#selector&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;tr&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;th,td&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;expected_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diff!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                          &lt;/pre&gt;
                          &lt;/div&gt;
    </content>
  </entry>
  <entry>
    <title>Programmiert Ihr Deutsch?</title>
    <link href="http://dennisreimann.de/blog/programmiert-ihr-deutsch-nachgeladen" />
    <updated>2011-06-01T15:37:00+02:00</updated>
    <id>http://dennisreimann.de/blog/programmiert-ihr-deutsch-nachgeladen</id>
    <content type="html">
      &lt;p&gt;Mit diesem Post würde ich gerne ein Thema wieder aufgreifen, dass ich vor drei Jahren
                            einmal angeschnitten habe: &lt;a href=&quot;http://dennisreimann.de/blog/programmiert-ihr-deutsch/&quot;&gt;Programmiert Ihr Deutsch?&lt;/a&gt;&lt;/p&gt;
                            
                            &lt;p&gt;Grund dafür ist, dass wir in zwei aktuellen Projekten dazu übergegangen sind, alles was
                            mit der Domäne und Tests zu tun hat komplett in deutsch zu entwickeln. Nach anfänglicher Skepsis
                            darüber muss ich nun sagen, dass ich meine Meinung deutlich geändert habe und es in jedem kommenden
                            Projekt wohl wieder so machen würde – es sei denn natürlich, es gibt Beschränkungen bzw. gute Gründe eben
                            nicht deutsch als Sprache zu verwenden (bspw. englischsprachige Teammitglieder oder Kunden).&lt;/p&gt;
                            
                            &lt;p&gt;Wir haben Modell-, Controller- und Attributnamen auf deutsch definiert, was auch erstaunlich
                            problemlos funktioniert. Die einzigen Anpassungen die in Rails daraus resultieren sind, dass
                            es erfordert die Inflections (&lt;code&gt;config/initializers/inflections.rb&lt;/code&gt;) anzupassen. Alles weitere
                            (bspw. Datenbanktabellennamen) resultiert daraus und benötigt weiter keine Konfiguration. Wir
                            waren bislang noch nicht wagemutig genug das auf die Spitze zu treiben und auch Umlaute in Klassen-
                            und Dateinamen zu verwenden, das bleibt dann dem geneigten Leser als Übung überlassen ;)&lt;/p&gt;
                            
                            &lt;h3&gt;Testing&lt;/h3&gt;
                            
                            &lt;p&gt;Richtig angenehm wird es in den Tests: Cucumber bringt von Haus aus mit, Features auch in anderen
                            Sprachen als Englisch zu verfassen. Alles was dazu nötig ist, ist bei der Installation das Kürzel
                            der Sprache mitzugeben, für die zusätzliche Web Steps generiert werden sollen, in unserem Fall:&lt;/p&gt;
                            
                            &lt;p&gt;&lt;code&gt;rails generate cucumber:install de&lt;/code&gt;&lt;/p&gt;
                            
                            &lt;p&gt;Eine Übersicht der in deutsch benötigten Keywords gibt es mittels&lt;/p&gt;
                            
                            &lt;p&gt;&lt;code&gt;bundle exec cucumber --i18n de&lt;/code&gt;&lt;/p&gt;
                            
                            &lt;p&gt;Die Testdaten legen wir über Tabellen an, was meiner Meinung nach mittlerweile auch etwas übersichtlicher
                            ist als Bibliotheken zu verwenden, die Factory Steps generieren (wie &lt;a href=&quot;https://github.com/makandra/cucumber_factory&quot;&gt;cucumber_factory&lt;/a&gt;
                            oder &lt;a href=&quot;https://github.com/ianwhite/pickle&quot;&gt;pickle&lt;/a&gt;). Dies ist aber sicherlich Geschmacksache und es gäbe
                            auch Möglichkeiten, die Stepgeneratoren so anzupassen, dass sie auch für deutsche Steps funktionieren.
                            Hier ein kurzes Beispiel für eines unserer Features (wichtig für Cucumber ist dabei der Kommentar in der
                            ersten Zeile):&lt;/p&gt;
                            
                            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# language: de&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&lt;/span&gt;
                            
                            &lt;span class=&quot;k&quot;&gt;Funktionalität:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Kunde-Login&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;  Als Kunde&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;  Möchte ich mich mit meinen Zugangsdaten einloggen&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;  Um an der Auktion teilnehmen zu können&lt;/span&gt;
                            
                            &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Grundlage:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Bestehender Kunde&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;    Angenommen &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;es gibt die folgenden Kunden:&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;      |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; email&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; kundennummer&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; password&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;   |&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;      |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; kunde@web.de&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; 123456&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;       |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; top_secret&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;
                            
                            &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Szenario:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Erfolgreiches Login mit E-Mail-Adresse&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;    Wenn &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich auf die Login-Seite gehe&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Login&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; mit &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;kunde@web.de&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; ausfülle&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Passwort&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; mit &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;top_secret&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; ausfülle&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich auf &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Anmelden&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; drücke&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Dann &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sollte ich auf der Startseite sein&lt;/span&gt;
                            &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich sollte &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Sie wurden erfolgreich eingeloggt&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; sehen&lt;/span&gt;
                            &lt;/pre&gt;
                            &lt;/div&gt;
                            
                            
                            &lt;p&gt;Auch die Specs lassen sich bis auf die Keywords sehr gut auf deutsch schreiben, was bei uns dann
                            in etwa so aussieht:&lt;/p&gt;
                            
                            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# encoding: utf-8&lt;/span&gt;
                            
                            &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;spec_helper&#39;&lt;/span&gt;
                            
                            &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Auktionator&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                              
                              &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bei bevorstehender Auktion&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                
                                &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:auktionstermin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@los1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:los&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auktionstermin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;losnummer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@los2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:los&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auktionstermin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;losnummer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                                
                                &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#phase&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                  
                                  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sollte &#39;auktion_bevorstehend&#39; zurückgeben&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                    &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;auktion_bevorstehend&#39;&lt;/span&gt;
                                    &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auktion_bevorstehend?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_true&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                                
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                            
                                &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#los&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                
                                  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sollte das aktuelle Los zurückgeben&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                    &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;los&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@los1&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                                
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                            
                            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                            &lt;/pre&gt;
                            &lt;/div&gt;
                            
                            
                            &lt;p&gt;Mich würde wie gesagt eure Meinung dazu interessieren, vielleicht habt ihr Tips und weitere Tools
                            dafür. Wer darüber hinaus auf der Suche nach Anregungen zum Thema Domänenabbildung ist, dem sei ggf.
                            noch Eric Evans&#8217; Buch &lt;a href=&quot;http://www.amazon.de/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215&quot;&gt;Domain Driven Design&lt;/a&gt;
                            empfohlen - dies aber wohl eher nur als Randnotiz.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Silencing the Rails log on a per-action basis</title>
    <link href="http://dennisreimann.de/blog/silencing-the-rails-log-on-a-per-action-basis" />
    <updated>2011-05-26T13:14:00+02:00</updated>
    <id>http://dennisreimann.de/blog/silencing-the-rails-log-on-a-per-action-basis</id>
    <content type="html">
      &lt;p&gt;In our current project we are having an action that is polled every ten seconds by the clients.
                              This clutters up the log, so I was looking for a way to completely silence the Rails logger
                              for this action. It turns out that you have to swap the default logger with a custom one, because
                              even when you use the &lt;code&gt;Rails.logger.silence&lt;/code&gt; block in your action, you will still find a line
                              in your log that is printed out before the request gets dispatched.&lt;/p&gt;
                              
                              &lt;p&gt;Here&#8217;s our custon logging class:&lt;/p&gt;
                              
                              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# lib/custom_logger.rb&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomLogger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:silenced&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                                
                                &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;X-SILENCE-LOGGER&#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:silenced&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;PATH_INFO&#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                    &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;silence&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                      &lt;span class=&quot;vi&quot;&gt;@app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                                    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              &lt;/pre&gt;
                              &lt;/div&gt;
                              
                              
                              &lt;p&gt;This way you can either define request paths that should not get logged or send the &lt;code&gt;X-SILENCE-LOGGER&lt;/code&gt;
                              header for the request you don&#8217;t want to log.&lt;/p&gt;
                              
                              &lt;p&gt;To make use of your own logger, you&#8217;ll have to swap the default logger, which is included as
                              a Rack middleware:&lt;/p&gt;
                              
                              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# config/application.rb&lt;/span&gt;
                              &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;/../lib/custom_logger.rb&#39;&lt;/span&gt;
                              
                              &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;MyApp&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Application&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Application&lt;/span&gt;
                                  &lt;span class=&quot;c1&quot;&gt;# Middlewares&lt;/span&gt;
                                  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;middleware&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CustomLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:silenced&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/noisy/action.json&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              &lt;/pre&gt;
                              &lt;/div&gt;
    </content>
  </entry>
  <entry>
    <title>Using Cucumber Step Argument Transforms</title>
    <link href="http://dennisreimann.de/blog/using-cucumber-step-argument-transforms" />
    <updated>2011-03-24T10:25:00+01:00</updated>
    <id>http://dennisreimann.de/blog/using-cucumber-step-argument-transforms</id>
    <content type="html">
      &lt;p&gt;In a recent project that is tested with Cucumber we were using „within“ steps with CSS selectors.
                                Though &lt;a href=&quot;http://mislav.uniqpath.com/2010/09/cuking-it-right/&quot;&gt;this isn&#8217;t basically considered a good idea&lt;/a&gt;
                                I&#8217;d say it made sense for us, because we had to select specific parts of the page. Cuking it like that, our steps
                                usually looked something like this:&lt;/p&gt;
                                
                                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;Scenario:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Edit something&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;  Given &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;there is something&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;another something&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;When &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I go to the page of somethings&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I follow &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;edit&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; within &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ul.somethings li:nth-child(1)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot;&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Then &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I should be on the edit page for &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;something&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot;&lt;/span&gt;
                                &lt;/pre&gt;
                                &lt;/div&gt;
                                
                                
                                &lt;p&gt;Besides looking just ugly, CSS selectors also don&#8217;t offer any business value and are likely to change. Cucumber&#8217;s
                                &lt;a href=&quot;https://github.com/aslakhellesoy/cucumber/wiki/Step-Argument-Transforms&quot;&gt;Step Argument Transforms&lt;/a&gt; can help you
                                avoid that by refactoring common operations.&lt;/p&gt;
                                
                                &lt;p&gt;Transforms are defined with the &lt;code&gt;Transform&lt;/code&gt; keyword and can be a part of your step definition files. Cucumber matches
                                the captures in your steps (i.e. &lt;code&gt;the 1st something&lt;/code&gt;) against the defined transforms. If the regexp matches, it yields
                                the transformed value as an argument to the step definition block. This sounds complicated, so here&#8217;s an example:&lt;/p&gt;
                                
                                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nf&quot;&gt;Transform /^the (\d+)(?:st|nd|rd|th) something$/ do&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                                &lt;span class=&quot;s&quot;&gt;  &quot;ul.somethings li:nth-child(&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#{num})&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                                &lt;span class=&quot;s&quot;&gt;end&lt;/span&gt;
                                &lt;/pre&gt;
                                &lt;/div&gt;
                                
                                
                                &lt;p&gt;This transform allows us to refactor the scenario above to be more readable and maintainable:&lt;/p&gt;
                                
                                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;Scenario:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Edit something&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;  …&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;  When &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I go to the page of somethings&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I follow &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;edit&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; within &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;the 1st something&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot;&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;  …&lt;/span&gt;
                                &lt;/pre&gt;
                                &lt;/div&gt;
                                
                                
                                &lt;p&gt;We can even abstract this a little further and make it usable on a common level:&lt;/p&gt;
                                
                                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nf&quot;&gt;Transform /^the (\d+)(?:st|nd|rd|th) (.+)$/ do&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;num, type&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                                &lt;span class=&quot;s&quot;&gt;  &quot;ul.&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#{type.pluralize} li:nth-child(#{num})&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                                &lt;span class=&quot;s&quot;&gt;end&lt;/span&gt;
                                &lt;/pre&gt;
                                &lt;/div&gt;
                                
                                
                                &lt;p&gt;This is just a basic example of how this often unknown Cucumber feature might help you to refactor your step definitions.
                                For more information and decent examples check out the wiki page on &lt;a href=&quot;https://github.com/aslakhellesoy/cucumber/wiki/Step-Argument-Transforms&quot;&gt;Step Argument Transforms&lt;/a&gt;.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Masquerade now runs on Rails 3</title>
    <link href="http://dennisreimann.de/blog/masquerade-now-runs-on-rails-3" />
    <updated>2010-11-09T08:11:00+01:00</updated>
    <id>http://dennisreimann.de/blog/masquerade-now-runs-on-rails-3</id>
    <content type="html">
      &lt;p&gt;During the last week I finished updating &lt;a href=&quot;https://github.com/dbloete/masquerade&quot;&gt;masquerade&lt;/a&gt; to Rails 3. It took me some time to do this, because currently I&#8217;m not using it in production myself and so I was kind of lacking the motivation to do this chore ;).&lt;/p&gt;
                                  
                                  &lt;p&gt;Nevertheless, now that this is done there are still some more functional things that would be great to have, like &lt;a href=&quot;https://github.com/dbloete/masquerade/issues/#issue/13&quot;&gt;restricting signups&lt;/a&gt; or extracting the login logic, so that people could &lt;a href=&quot;https://github.com/dbloete/masquerade/issues/#issue/15&quot;&gt;authenticate with an LDAP backend&lt;/a&gt;. For the latter there&#8217;s already a &lt;a href=&quot;https://github.com/dbloete/masquerade/tree/auth_strategy&quot;&gt;branch&lt;/a&gt; which I&#8217;ll update eventually and implement the functionality that I wrote and used for the project that &lt;a href=&quot;http://dennisreimann.de/blog/studium-beendet/&quot;&gt;accompanied my thesis&lt;/a&gt;.&lt;/p&gt;
                                  
                                  &lt;p&gt;There are also some other interesting things that could be accomplished, like turning the whole OpenID server into a Rails engine, so that it ain&#8217;t a standalone app no more, but can be integrated into other applications. It would be great if I could find some people that are interested in that, because at the moment I myself will not find the time to do that, but I&#8217;d be glad to provide help in improving masquerade even further.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Codeshelver is open source</title>
    <link href="http://dennisreimann.de/blog/codeshelver-is-open-source" />
    <updated>2010-11-07T13:24:00+01:00</updated>
    <id>http://dennisreimann.de/blog/codeshelver-is-open-source</id>
    <content type="html">
      &lt;p&gt;Yesterday I took the time to fix some bugs and clean up the &lt;a href=&quot;http://codeshelver.com&quot;&gt;Codeshelver&lt;/a&gt; code, so I could finally &lt;a href=&quot;https://github.com/dbloete/Codeshelver&quot;&gt;open source it&lt;/a&gt;. Some people asked about that and I think it&#8217;s a good resource for dipping your toes into &lt;a href=&quot;http://nodejs.org/&quot;&gt;nodeJS&lt;/a&gt; and get up to speed with &lt;a href=&quot;http://expressjs.com/&quot;&gt;ExpressJS&lt;/a&gt;, because the app is not too complex (350 lines of code) but goes beyond a simple &#8220;hello world&#8221; and utilizes some &lt;a href=&quot;http://dennisreimann.de/blog/codeshelver-tag-github-repositories/&quot;&gt;interesting technologies&lt;/a&gt;. If you&#8217;d like to extend it, feel free to send me pull requests and I&#8217;ll be glad to merge in extensions and enhancements and deploy them to codeshelver.com.&lt;/p&gt;
                                    
                                    &lt;p&gt;btw: I&#8217;ll be talking about ExpressJS and some of the learnings in developing Codeshelver at the next meeting of the &lt;a href=&quot;http://www.rubyonrails-ug.de/wiki/hamburgsync&quot;&gt;Rails Usergroup Hamburg&lt;/a&gt;, taking place the upcoming wednesday at XING.&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Interview mit Nico Hagenburger</title>
    <link href="http://dennisreimann.de/blog/interview-mit-nico-hagenburger" />
    <updated>2010-11-02T00:00:00+01:00</updated>
    <id>http://dennisreimann.de/blog/interview-mit-nico-hagenburger</id>
    <content type="html">
      
                                      &lt;p&gt;
                                        &lt;strong&gt;
                                          Interview mit
                                          &lt;a href=&quot;http://twitter.com/hagenburger&quot;&gt;Nico Hagenburger&lt;/a&gt;
                                          auf dem Railscamp Hamburg am 24.10.2010.
                                        &lt;/strong&gt;
                                      &lt;/p&gt;
                                      &lt;p&gt;
                                        Wir sprechen über einige
                                        &lt;a href=&quot;http://www.hagenburger.net/TALKS/rails-3.1-frontend-performance.html&quot;&gt;Neuerungen in Rails 3.1&lt;/a&gt;
                                        , die die Frontendentwicklung betreffen:
                                        Die neue Rails-Version wird das Preprocessing von CSS mit SCSS/Compass und Javascript mit
                                        &lt;a href=&quot;http://jashkenas.github.com/coffee-script/&quot;&gt;Coffeescript&lt;/a&gt;
                                        standardmäßig unterstützen. Zusätzlich dazu wird das von Nico
                                        geschriebene Gem
                                        &lt;a href=&quot;https://github.com/hagenburger/lemonade&quot;&gt;Lemonade&lt;/a&gt;
                                        fester Bestandteil von
                                        &lt;a href=&quot;http://compass-style.org/&quot;&gt;Compass&lt;/a&gt;
                                        , so dass Rails 3.1 auch
                                        das Generieren von Sprite-Images out-of-the-box unterstützt.
                                      &lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Interview mit Jan Krutisch</title>
    <link href="http://dennisreimann.de/blog/interview-mit-jan-krutisch" />
    <updated>2010-10-26T00:00:00+02:00</updated>
    <id>http://dennisreimann.de/blog/interview-mit-jan-krutisch</id>
    <content type="html">
      
                                        &lt;p&gt;
                                          &lt;strong&gt;
                                            Interview mit
                                            &lt;a href=&quot;http://twitter.com/halfbyte&quot;&gt;Jan Krutisch&lt;/a&gt;
                                            auf dem Railscamp Hamburg am 23.10.2010.
                                          &lt;/strong&gt;
                                        &lt;/p&gt;
                                        &lt;p&gt;
                                          Wir sprechen ueber den
                                          &lt;a href=&quot;http://railsrumble.com&quot;&gt;Railsrumble&lt;/a&gt;
                                          und das Projekt
                                          &lt;a href=&quot;http://awesome-fontstacks.com&quot;&gt;Awesome Fontstacks&lt;/a&gt;
                                          , das von Jan,
                                          &lt;a href=&quot;http://twitter.com/enebo&quot;&gt;Thorsten Böttger&lt;/a&gt;
                                          ,
                                          &lt;a href=&quot;http://twitter.com/theflow&quot;&gt;Florian Munz&lt;/a&gt;
                                          und
                                          &lt;a href=&quot;http://twitter.com/wowo101&quot;&gt;Wolfgang Wopperer&lt;/a&gt;
                                          während
                                          des Rumbles gebaut wurde. Awesome Fontstacks ermöglicht es passende Webfont-
                                          Schriftsätze zusammenzustellen und wurde zum Sieger der Kategorie „Most Useful“ gewählt.
                                        &lt;/p&gt;
    </content>
  </entry>
</feed>

