<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Art Of Programming]]></title>
  <link href="http://ApproachE.com/atom.xml" rel="self"/>
  <link href="http://ApproachE.com/"/>
  <updated>2013-07-10T13:44:45+10:00</updated>
  <id>http://ApproachE.com/</id>
  <author>
    <name><![CDATA[Dmytrii Nagirniak]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Testing Rails across time zones]]></title>
    <link href="http://ApproachE.com/blog/testing-rails-across-time-zones/"/>
    <updated>2013-07-10T11:14:00+10:00</updated>
    <id>http://ApproachE.com/blog/testing-rails-across-time-zones</id>
    <content type="html"><![CDATA[<h2>Why?</h2>

<p>Because it is easy to get the dates/times wrong without even realising it.
Even if you don&rsquo;t need to support multiple time zones, you can catch a lot of
the edge cases.</p>

<h2>How?</h2>

<ol>
<li>Randomise time zone when running specs</li>
<li>Run the specific specs across the different time zones</li>
</ol>


<!-- more -->


<h2>Usage: Randomise time zone when running specs</h2>

<p>The RSpec support file (see below) will set the Rails&#8217; <code>Time.zone</code> to a random time zone.
So if something is wrong then your CI should eventually fail.</p>

<p>When it will, you should look for the message at the very beginning:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Current rand time zone: (GMT+06:30) Rangoon. Repro: Time.zone = ActiveSupport::TimeZone["Rangoon"]</span></code></pre></td></tr></table></div></figure>


<p>Then go to your failing spec and in the context of it add the following
(assuming you copy pasted the &ldquo;Repro&rdquo; part from the message):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="n">before</span> <span class="p">{</span> <span class="no">Time</span><span class="o">.</span><span class="n">zone</span> <span class="o">=</span> <span class="ss">ActiveSupport</span><span class="p">:</span><span class="ss">:TimeZone</span><span class="o">[</span><span class="s2">&quot;Rangoon&quot;</span><span class="o">]</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now you can re-run the spec and it should repeatably and predictably fail (much like RSpec&rsquo;s random order with a given seed).</p>

<p>This works without changing any of the existing specs and relies on
the fact that your CI is running specs often enough.</p>

<h2>Usage: Run the specific specs across the different time zones</h2>

<p>You may have some specs that you want to specifically test across all the time zones.
That doesn&rsquo;t mean you want to support all time zone, it just means that the transitions
between the dates are very important.
Getting it run for all timezones will give good confidence about the correctness of the functionality, even for one time zone.</p>

<p>This can be used, for example, with tests on reports that are quite sensitive
(all financial/sales reports probably).</p>

<p>So how do you do it?</p>

<p>Just write the normal specs without thinking about the time zone.
Let&rsquo;s take this as an example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;spec_helper&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="k">module</span> <span class="nn">SalesReport</span>
</span><span class='line'>  <span class="n">describe</span> <span class="no">SalesChart</span>  <span class="k">do</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">it</span> <span class="s2">&quot;should return chart with data for a week as daily summary&quot;</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">create_three_reservations_per_day</span> <span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">1</span>
</span><span class='line'>      <span class="n">chart</span> <span class="o">=</span> <span class="no">SalesChart</span><span class="o">.</span><span class="n">for_company</span><span class="p">(</span><span class="n">reservations</span><span class="p">,</span> <span class="n">company</span><span class="p">)</span>
</span><span class='line'>      <span class="n">chart</span><span class="o">.</span><span class="n">data_table</span><span class="o">.</span><span class="n">cols</span><span class="o">.</span><span class="n">size</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="mi">4</span>
</span><span class='line'>      <span class="n">rows_from</span><span class="p">(</span><span class="n">chart</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="o">[</span>
</span><span class='line'>        <span class="o">[</span><span class="mi">1</span><span class="o">.</span><span class="n">day</span><span class="o">.</span><span class="n">ago</span><span class="o">.</span><span class="n">to_date</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>        <span class="o">[</span><span class="no">Date</span><span class="o">.</span><span class="n">current</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span>
</span><span class='line'>      <span class="o">]</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># helpers ommited...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Make sure it passes in your timezone.</p>

<p>Then just wrap your spec in <code>across_time_zones</code>, like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;spec_helper&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="k">module</span> <span class="nn">SalesReport</span>
</span><span class='line'>  <span class="n">describe</span> <span class="no">SalesChart</span>  <span class="k">do</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">across_time_zones</span> <span class="ss">step</span><span class="p">:</span> <span class="mi">2</span><span class="o">.</span><span class="n">hours</span> <span class="k">do</span>
</span><span class='line'>      <span class="n">it</span> <span class="s2">&quot;should return chart with data for a week as daily summary&quot;</span> <span class="k">do</span>
</span><span class='line'>        <span class="n">create_three_reservations_per_day</span> <span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">1</span>
</span><span class='line'>        <span class="n">chart</span> <span class="o">=</span> <span class="no">SalesChart</span><span class="o">.</span><span class="n">for_company</span><span class="p">(</span><span class="n">reservations</span><span class="p">,</span> <span class="n">company</span><span class="p">)</span>
</span><span class='line'>        <span class="n">chart</span><span class="o">.</span><span class="n">data_table</span><span class="o">.</span><span class="n">cols</span><span class="o">.</span><span class="n">size</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="mi">4</span>
</span><span class='line'>        <span class="n">rows_from</span><span class="p">(</span><span class="n">chart</span><span class="p">)</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="o">[</span>
</span><span class='line'>          <span class="o">[</span><span class="mi">1</span><span class="o">.</span><span class="n">day</span><span class="o">.</span><span class="n">ago</span><span class="o">.</span><span class="n">to_date</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="no">Date</span><span class="o">.</span><span class="n">current</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span>
</span><span class='line'>        <span class="o">]</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># helpers ommited...</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>You&rsquo;ll be surprised how many things can go wrong. Especially if you have some more advanced DB queries
that use (in PostgreSQL terms) dates, times and times with time zone, maybe <code>DATE_TRUNC</code> etc.</p>

<p>Now that spec will be created for each time zone with the given step.</p>

<h2>Tips/Gotchas</h2>

<ul>
<li>The default <code>step</code> here is set to 8 hours (it is optional), meaning that only 3 time zones will be tested. It may be sufficient or may not. So prefer to provide it expclicitly.</li>
<li>The smaller the <code>step</code> is, the more specs will be created and the slower the example will become. So choose the number wisely (less than 2 hours is <em>usually</em> not necessary).</li>
<li>Always, always use <code>Time.zone.now</code> (or <code>Time.current</code>) instead of <code>Time.now</code>.</li>
<li>Always, always use <code>Date.current</code> instead of <code>Date.today</code>.</li>
<li>Move any <code>let!</code> (with bang) and <code>before</code> blocks under the <code>across_time_zones</code> to ensure the correct time zone is used at all times.</li>
</ul>


<p>You can grab the RSpec <a href="https://gist.github.com/dnagir/5962765">support file</a> to leaverage it.
Feedback on this is welcome.</p>

<div><script src='https://gist.github.com/5962765.js'></script>
<noscript><pre><code></code></pre></noscript></div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Increase your productivity in Vim and Terminal]]></title>
    <link href="http://ApproachE.com/blog/increase-your-productivity-with-vim-and-terminal/"/>
    <updated>2012-03-12T06:30:00+11:00</updated>
    <id>http://ApproachE.com/blog/increase-your-productivity-with-vim-and-terminal</id>
    <content type="html"><![CDATA[<p>This post will give you <em>minimal</em> suggestions that
you can apply in your daily work to immediately increase your productivity.</p>

<p>I&rsquo;m writing this after watching the <a href="http://blog.steveklabnik.com/posts/2012-02-22-two-pomodoros">Steve Klabnik&rsquo;s screencast</a>
where he is working <em>&ldquo;in a wild&rdquo;</em>.</p>

<p>I love this idea and have done videoing
how I work on a little <a href="http://approache.com/blog/rails-plugin-with-tested-assets/">ios-checkboxes</a>
and <a href="http://approache.com/blog/knockoutjs-validations-video/">knockout-rails</a>.</p>

<p>The world would an awesome place if more people (yes, including <strong>you</strong>) would start sharing the way they work.
Well done Steve!</p>

<p>But today I want to focus on just a few things that should dramatically improve the productivity.</p>

<!-- more -->


<h1>Vim productivity</h1>

<blockquote><p>Vim is one of a select bunch of tools for which I have no substitute.<br/>It is a brilliant piece of work!</p><footer><strong>Biju Chacko</strong> <cite>Vim Quotes</cite></footer></blockquote>


<p>The power of vim is huge. Very small number of people actually do know how to use most of it.
I&rsquo;m certainly not one of them.</p>

<p>But let me suggest some of the things that keep myself more productive.</p>

<h2>Remap your CapsLock key to Control</h2>

<p><em>Why?</em> Because the <em>Control</em> key is located extremely inconveniently
while <em>CapsLock</em> is right under your baby-finger. All the time.</p>

<p><em>How?</em> Follow <a href="http://www.manicai.net/comp/swap-caps-ctrl.html">this guide</a>.</p>

<p>I blindly trusted the <em>command</em> given by <a href="http://twitter.com/garybernhardt">Garry Bernhard</a>
in his <a href="http://www.destroyallsoftware.com/screencasts/catalog/some-vim-tips">DestroyAllSoftware &ndash; Some Vim Tips</a>
on this. Never regretted.</p>

<p>Don&rsquo;t think about it. Just do it and I&rsquo;m sure you won&rsquo;t go back.</p>

<h2>Use Vim jumps</h2>

<p><em>Why?</em> A lot of times you need to jump forth and back between 2 place or go to where you&rsquo;ve been a minute ago.
A log of people just find that line/file again. It&rsquo;s a waste of time.</p>

<p><em>How?</em></p>

<ul>
<li><code>Ctrl-o</code> and <code>Ctrl-i</code> to go to the previous/next location you jumped to.</li>
<li><code>``</code> (two backticks) &ndash; jump back to where you were.</li>
<li><code>gi</code> &ndash; go to the last place you inserted a text.</li>
</ul>


<h2>Use appropriate Vim navigations</h2>

<p><em>Why?</em> Typing <code>l</code> (move right one symbol) or similar multiple times is waste of time.</p>

<p><em>How?</em></p>

<ul>
<li><code>{</code> and <code>}</code> &ndash; jump <em>paragraph</em> back and forth.</li>
<li><code>Ctrl-F/B</code> &ndash; move one <em>screen</em> back and forth.</li>
<li><code>Ctrl-E/Y</code> &ndash; <em>scroll</em> the screen.</li>
<li><code>*</code> (star) &ndash; search for the word under cursor, then <code>n/p</code> to jump to next/previous.</li>
<li>add <code>imap jj &lt;Esc&gt;</code> to your <code>.vimrc</code> and don&rsquo;t use <code>Esc</code> anymore.</li>
</ul>


<h2>Changing case and repeating a command</h2>

<p><em>Why?</em> Because a lot of things can be done much more efficiently.</p>

<p><em>How?</em></p>

<ul>
<li><code>~</code> (tilde) &ndash; toggle the casing of a letter/selection (upper-case/down-case).</li>
<li><code>.</code> (dot) &ndash; repeat the last set of commands (use in a combination with search, such as <code>*</code>, and jumps).</li>
</ul>


<h2>Temporarily map commands you run</h2>

<p><em>Why?</em> Because you don&rsquo;t want to type the same command over and over again.</p>

<p><em>How?</em> One example is <code>nmap &lt;leader&gt;s :! bundle exec rspec % --colour --focus&lt;cr&gt;</code>.
This will run the current spec file when you press <code>,s</code> (in my case).</p>

<p><strong>Rule of thumb</strong>: if you do something more then twice in the terminal outside of Vim, map it using <code>nmap</code>.
Don&rsquo;t switch windows, <em>don&rsquo;t lose your context</em>.</p>

<h1>Terminal productivity</h1>

<p>Just a couple of things here.</p>

<h2>Use iTerm2</h2>

<p><em>Why?</em> At least because you can split window without losing the context.</p>

<p><em>How?</em> Install it from the <a href="http://www.iterm2.com/">iterm2.com</a> site (or even use tmux!).</p>

<p>Use <code>Ctrl-D/Ctrl-Shift-D</code> (while in Vim or any iTerm tab/window) to split the current terminal window opening a new shell but still being able to see what you are currently working on.</p>

<h2>Use <code>!!</code> (double bang) or arrow up</h2>

<p><em>Why?</em> Because it repeats the previous command that you should have mapped in Vim but didn&rsquo;t.</p>

<p><em>How?</em> Just type <code>!!</code> and it will execute last command.
This is simple, but strangely enough I can see people are actually retyping commands.</p>

<h2>Enable Vim mode in bash</h2>

<p><em>Why?</em> Because you navigate in the terminal too. And Vim mode makes it seamless.</p>

<p><em>How</em>? <a href="http://linuxart.com/log/archives/2005/10/13/super-useful-inputrc/">Create an inputrc file</a> and
add <code>set editing-mode vi</code> to it.</p>

<h1>Useful links</h1>

<ul>
<li><a href="http://blog.sanctum.geek.nz/vim-anti-patterns/">Vim anti-patterns</a> &ndash; must-read if you want to be better at Vim.</li>
<li><a href="http://peepcode.com/products/smash-into-vim-i">Smash into Vim</a> &ndash; always awesome PeepCode series on Vim.</li>
<li><a href="https://workshops.thoughtbot.com/vim">Vim for Rails developers</a> &ndash; nice overview of the plug-ins and more productive use of Vim.</li>
<li><a href="http://peepcode.com/products/meet-the-command-line">Meet the Command Line</a> and <a href="http://peepcode.com/products/advanced-command-line">Advanced Command Line</a> &ndash; great screencasts if you want to get better with command line.</li>
<li><a href="http://www.destroyallsoftware.com">DestroyAllSoftware screencasts</a> &ndash; screencasts covering Vim, Unix, Ruby.</li>
</ul>


<p>The DestroyAllSoftware stands out here because Gary covers range of extremely focused, professional topics that you can&rsquo;t ignore.</p>

<p>Hope this post will help you to leverage your tools a bit better and will teach you a thing or two.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to care for Introverts]]></title>
    <link href="http://ApproachE.com/blog/how-to-care-for-introverts/"/>
    <updated>2012-03-08T08:25:00+11:00</updated>
    <id>http://ApproachE.com/blog/how-to-care-for-introverts</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve just found an <a href="http://afterwordss.tumblr.com/post/5274763919">interesting poster</a> that describes how to deal with introverts.</p>

<p>Being an introvert myself I agree with most of the points:</p>

<ul>
<li>Respect their <strong>need for privacy</strong>.</li>
<li>Never embarrass them in <strong>public</strong>.</li>
<li>Let them observe first in <strong>new situations</strong>.</li>
<li>Give them <strong>time to think</strong>. Don&rsquo;t demand instant answers.</li>
<li><strong>Don&rsquo;t interrupt </strong>them.</li>
<li>Give them <strong>advance notice</strong> of expected changes in their lives.</li>
<li>Give them <strong>15 minute warnings</strong> to finish whatever they are doing before calling them to dinner or moving on to the next activity.</li>
<li>Reprimand them <strong>privately</strong>.</li>
<li><strong>Teach</strong> them new skills privately rather than in public.</li>
<li>Enable them to find <strong>one best friend</strong> who has similar interests and abilities; encourage this relationship even if the friend moves.</li>
<li>Do not push them to make <strong>lots of friends</strong>.</li>
<li><strong>Respect</strong> their introversion. Don&rsquo;t try to remake them into extroverts.</li>
</ul>


<p>I&rsquo;m pretty sure it is just a common sense. But it helps when people do know it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Migrating from Blogger to Octopress]]></title>
    <link href="http://ApproachE.com/blog/migrating-from-blogger-to-octopress/"/>
    <updated>2012-03-04T20:09:00+11:00</updated>
    <id>http://ApproachE.com/blog/migrating-from-blogger-to-octopress</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve been a Blogger user since 2006 and decided to switch over to something more geeky.</p>

<p>This post will cover some of the reasons for that and also will provide an overview
of how to migrate from Blogger to Octopress.</p>

<h2>What do I want to achieve?</h2>

<ul>
<li><strong>Merging</strong> my personal site and blog &ndash; those were totally separate, unrelated entities, not good enough.</li>
<li>Write <strong>more often</strong>, using the same tools I use on a daily basis (Vim ATM).</li>
<li>More <strong>hands-on</strong> kind of blogging, I actually do want to do the dirty work messing with HTML/CSS etc.</li>
</ul>


<h2>Reasons for switching:</h2>

<ul>
<li><strong>Markdown, HAML, bare bones HTML</strong>. I wanted to have a bit more control over how my blog looks like.</li>
<li><strong>Blogging software</strong> isn&rsquo;t good enough. Unfortunately I haven&rsquo;t found yet a good <strong>geeky</strong> S/W for blogging.</li>
<li><strong>Easier to write</strong> from Vim. Writing is much easier, not moving my hands off the keyboard and staying in the terminal.</li>
<li><strong>Version controlled</strong>. Nice to have, but not crucial for me.</li>
</ul>


<h2>Why I didn&rsquo;t want to switch:</h2>

<ul>
<li>Losing <strong>PageRank</strong>, which shouldn&rsquo;t really be an issue (see below).</li>
<li><strong>Uncerteinities</strong>. So now I have to maintain it myself? Take care of updates? Hell, yeah!</li>
<li><strong>Self-hosted</strong>. Nothing to say here.</li>
<li>I have never ever needed to do anything with the blog in terms of maintenance while being on Blogger. I really just worked.</li>
</ul>


<p>Switching to a self-hosted blog/site will require a bit of involvement from me.
But this is something I am willing to take. It&rsquo;s time to take my ass out of the comfy couch of Blogger.</p>

<h2>So how to actually migrate?</h2>

<p>I would split it into the following larger steps:</p>

<ol>
<li>Preparation.</li>
<li>Deployment.</li>
<li>Finalisation.</li>
</ol>


<h2>Preparation</h2>

<p>At this stage you need to <a href="http://octopress.org/docs/setup">setup the Octopress itself</a>, <a href="http://octopress.org/docs/configuring">configure</a> it and import your existing posts from Blogger.</p>

<p>I won&rsquo;t go into details how to <a href="http://octopress.org/docs/theme">customise</a> and set it up, you see the links.</p>

<p>I&rsquo;ll go directly into the migrating the Blogger posts over to Octopress.</p>

<p>What you need to do is</p>

<ol>
<li>Export your Blogger posts.</li>
<li>Use <a href="https://gist.github.com/1765496">this script</a> to import it into Octopress.</li>
</ol>


<p>After you do this, all you&rsquo;ll get a bunch of posts that are already part of your site.
Double check whether everything is correct or not. You may want to tweak the script for your needs.</p>

<p><em>Note</em> that the script also imports the comments, but in a little ugly way.
(<em>TIP</em>, you may want to disable commenting before exporting the posts from Blogger).</p>

<p>Next thing you want to do is to update your Octopress RSS feed URL so that existing subscribers won&rsquo;t be lost.
I am using FeedBurner and I had to set <code>subscribe_rss: http://feeds.feedburner.com/DmitriyNagirnyak</code> in the <code>_config.yml</code></p>

<p>Now that you&rsquo;ve got your posts, you want to set-up the redirection from your blog to your new site.</p>

<p>I prepared <a href="https://github.com/dnagir/approache-redirects/blob/master/app.rb">simple Sinatra application</a> for that.
You definitely want to fork and tweak it to your needs. Note that I&rsquo;m not using the <code>blog/YYYY/MM/DD/title</code> format.
I just use the <code>blog/title</code> format.</p>

<p>Now go ahead and deploy this app. I&rsquo;ve decided to use Heroku for that which is the simplest and easiest way to go.</p>

<p>But <strong>make sure you deploy to the domain of your blog</strong>. For example, my Blogger blog was hosted on the <code>blog.approache.com</code> and I deployed it to this domain.</p>

<p>It of course will not take any affect until you change your DNS settings.
But this will enable permanent redirects immediately when you&rsquo;ll do that (thus preserving all your old links).</p>

<h2>Deployment</h2>

<p>By now you should have:</p>

<ul>
<li>The Octopress site ready to go (with all the posts migrated).</li>
<li>Blogger redirection deployed.</li>
</ul>


<p>It&rsquo;s time to go ahead and actually <a href="http://octopress.org/docs/deploying">deploy</a> your Octopress site.</p>

<p>I wanted to merge <code>blog.approache.com</code> into the <code>approache.com</code> so I deployed the new site to <code>approache.com</code>
(hosted on <em>Github Pages</em>).</p>

<p>Now make sure everything is working properly and you have dome everything right.
If you&rsquo;ve missed something out, then go ahead and fix it. Then redeploy.</p>

<p>This may take a couple of iterations to get it right.</p>

<p>The point here is that you basically now have 2 blogs &ndash; one is the old Blogger, the other &ndash; the Octopress.
You can experiment with the Octopress here, but don&rsquo;t do it for too long (I would say max of 1 day).</p>

<p>After you&rsquo;re happy with the new site and blog it&rsquo;s time to finalise everything.</p>

<h2>Finalisation</h2>

<p>Next step is to make sure your subscribers will still receive updates through the FeedBurner.
For that:</p>

<ol>
<li>Sign in into FeedBurner.</li>
<li>Replace the original feed URL by the Octopress&#8217; one (which is something like <code>http://ApproachE.com/atom.xml</code>).</li>
</ol>


<p>By now you should be ready to switch your your Blogger domain to your main site.</p>

<p>You probably will do it simply by changing your DNS record to point to your Octopress server.
In my case I had to change the DNS record from <code>blog - CNAME - ghs.google.com</code> to <code>. - A - 207.97.227.245</code> (dot means top-level domain here).</p>

<p>Since you&rsquo;ve already deployed your redirection app, all the old links will still work.
All the PageRank should be preserved.</p>

<p>The very last thing to do is to <strong>disable the Blogger</strong> if you want to.</p>

<h2>Summary</h2>

<p>Switching to Octopress was relatively painless thanks to Blogger&rsquo;s ability to export posts and the script that could import it into Octopress.</p>

<p>Preserving URL was relatively easy too and the rest was left to FeedBurner and DNS hosting.</p>

<p>Hope this is helpful for you.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[KnockoutJS Validations Screencast]]></title>
    <link href="http://ApproachE.com/blog/knockoutjs-validations-video/"/>
    <updated>2011-12-22T20:31:00+11:00</updated>
    <id>http://ApproachE.com/blog/knockoutjs-validations-video</id>
    <content type="html"><![CDATA[<div class='post'>
<div>
If you wonder how you can use KnockoutJS with Rails in a similar way to Backbone.js or Spine.js then <a href="http://www.youtube.com/watch?v=cJzQl-bpmUI">watch the video</a>. It also shows how easy it is to apply client side validations that work alongsite with the server-side validations.<br />
<br />

<iframe width="560" height="315" src="http://www.youtube.com/embed/cJzQl-bpmUI?hd=1" frameborder="0" allowfullscreen></iframe>

<div>
Have a look at the <a href="https://github.com/dnagir/knockout-rails">knockout-rails</a> project for more details.
</div>

</div></div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
This is actually <a href="https://gist.github.com/9ca5dce0524927d69655" rel="nofollow">one of the options</a> of validating in the background: <br /><br />It doesn&#39;t include the bindings, but gives idea how it can be done. Easier than I thought actually.</div>
</div>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
Pre-validating on the server can technically be done with the Model Events. But it&#39;s not supported out of the box.<br /><br />It is a good idea, but there&#39;s a bit more complexity involved on both client and server. But I&#39;ll gladly accept pull requests to knockout-rails if somebody needs to support that.</div>
</div>
<div class='comment'>
<div class='author'>Aleksey Gureiev</div>
<div class='content'>
This comment has been removed by the author.</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Issues switching to JRuby from MRI 1.9]]></title>
    <link href="http://ApproachE.com/blog/issues-switching-to-jruby-from-mri-19/"/>
    <updated>2011-11-29T11:51:00+11:00</updated>
    <id>http://ApproachE.com/blog/issues-switching-to-jruby-from-mri-19</id>
    <content type="html"><![CDATA[<div class='post'>
<div dir="ltr" style="text-align: left;" trbidi="on">
<b>UDPATE</b>: The reason for switching to JRuby the native neo4j API. Have to use REST API with MRI.<br />
<br />
This is just a quick recap of what issues I have had trying to switch existing app from MRI Ruby (1.9.3) to JRuby (1.6.4).<br />
<br />
Unfortunately I stepped back and didn&#8217;t want to spend more time as it felt an unbreakable chain of issues. Resolving one, you think &#8220;huh, awesome&#8221;. But very soon you hit the next.<br />
And I couldn&#8217;t see it stopping.<br />
<br />
<b>But PLEASE bear in mind</b> that I only spent a couple of hours on that. With a little bit more persistence, you may be able to the end of the tunnel.<br />
<br />
The overall impression is that it is not a big deal really. The problems arise when trying to use other libraries. And unfortunately, not all of the gems <b>care deep enough to support JRuby</b>. And this is the biggest issue in my opinion, there are very little issues with JRuby itself. The transition (from the syntax perspective) was extremely easy.<br />
<br />
The application is pretty standard Rails 3.1 app that uses gems like Dragonfly, inherited_resources, cancan, paper_trail, Authlogic, CoffeeScript, Haml, Sass, Formtastic etc. For testing - things like rspec-rails, cucumber-rails, capybara-webkit, guard (rspec and cucumber), database_cleaner etc.<br />
<br />
So here is a quick list of the things that I faced on my way.<br />
<br />
Before everything else I enabled support for 1.9 syntax in JRuby (export JRUBY_OPTS=&#8211;1.9).<br />
<br />
It all first started with <a href="https://gist.github.com/1402753">the weird issue</a> where the <b>wrong arguments were passed to RSpec shared example</b>.<br />
Unfortunately I did not figure out why it happened and just patched it as you can see in the comments there.<br />
<script src="https://gist.github.com/1402753.js?file=sample_spec.rb">
</script>

<br />
<br />
<br />
After fixing this issue I had another one related to <b>database_cleaner</b>. So I ended up with a <a href="https://github.com/bmabey/database_cleaner/pull/83">pull request</a> that worked for me.<br />
<br />
The other issue was a<b> huge stack trace</b>. I scrolled 3 pages in the terminal to get to the top. Most of that stack trace is deep inside Java. Additionally I got <b>wrong line number</b> on exception. This &#8220;features/step_definitions/company_steps.rb:234&#8221; makes me thing that the exception is at line 234. But that file only had 49 lines of code. Now, go figure.<br />
<br />
Going on&#8230; <a href="https://github.com/colszowka/simplecov">SimpleCov</a> gem didn&#8217;t work out of the box and gave the warning that I need to enable debugging. That&#8217;s fine and understandable. But after half an hour of debugging of unrelated exception, it turned out that <b>SimpleCove threw an exception</b> because of that. So had to go and explicitly disable it.<br />
<br />
Then I managed to run all of my specs. But I was pretty surprised how <b>slow</b> it was:<br />
<pre><code>
# rvm use 1.9.3
# time rspec # real=14s, rspec time ~ 12s

# rvm use jruby
# time rspec # real=52s, rspec time ~ 30s

</code>
</pre>
But this is expected as JRuby doesn&#8217;t have enough time to optimise here. It should be much better in production. But it will be also shit slow after deployment.<br />
Ok. That&#8217;s fine. <b>I can trust it&#8217;s fast</b>.<br />
<br />
Then I tried running the cucumber specs and had to file the <a href="http://jira.codehaus.org/browse/JRUBY-6237">issue</a> to support <b>new Ruby 1.9.3 syntax</b> (a = b = f 1). Not a big deal, easily fixed with parens: a = b = f(1).<br />
<br />
Next and the <b>final issue</b> - I could not run the <b>headless cucumber specs</b> (capybara-webkit). It just got stuck (no CPU used) and feels like there is a <b>dead-lock</b> or something similar.<br />
<br />
I couldn&#8217;t see way of fixing it easily and decided that for now I am <b>done with</b> it. So going <b>back to Ruby 1.9.3</b>.<br />
<br />
<br />
<b>To summarise</b>, I <b>did not feel like it&#8217;s a problem</b> to switch to JRuby. But it&#8217;s really a <b>big deal to actually use</b> it due to the number of <b>C extensions</b> that JRuby doesn&#8217;t really support.<br />
<br />
Again, to emphasise, there is nothing horribly wrong with JRuby and it seems to be pretty good. But the real showstoppers are the C extensions.</div></div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
Totally with you on this. But real world seems to be a bit different :)</div>
</div>
<div class='comment'>
<div class='author'>Postmodern</div>
<div class='content'>
Yet another reason to avoid C-extensions. When selecting dependencies for a new project, I prefer to select pure-Ruby libraries or FFI bindings (https://github.com/ffi/ffi#readme). Pure-Ruby libraries should be faster on Rubinius/JRuby. FFI bindings work perfectly on both MRI and JRuby.<br /><br />If developers want faster Ruby code, they should help make MRI faster (or switch to Rubinius/JRuby), instead of writing more code in C.</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rails Plugin with Tested Assets Screencast]]></title>
    <link href="http://ApproachE.com/blog/rails-plugin-with-tested-assets/"/>
    <updated>2011-11-19T20:47:00+11:00</updated>
    <id>http://ApproachE.com/blog/rails-plugin-with-tested-assets</id>
    <content type="html"><![CDATA[<div class='post'>
<div dir="ltr" style="text-align: left;" trbidi="on">
Some of the most valuable things you can learn are not written in books, not shown in the presentations and demos. Those come from seeing how <i>others</i> work.<br />
<br />
How do they do all those small things? What tricks do they have? How would they approach that problem?<br />
<br />
Unfortunately, I can&#8217;t remember seeing people sharing the way they actually work (unless they pair). I want to see what mistakes they make, how they fix those, how they try to come up with a word erasing a line 10 times.<br />
I believe all this is of a great value for a lot of us.<br />
<br />
What I described is <i>partially</i>&nbsp;done by PeepCode&#8217;s Play By Play series and Tekpub. Those are amazing (usually). But that&#8217;s not exactly what I am after. Those screencasts are high quality, polished and prepared ones. YOU are NOT featuring there. I want to see YOU there. All of you, guys.<br />
<br />
<br />
So I decided to make a first step (or maybe not so) and screencast myself while working on a Rails Plugin.<br />
<br />
This is mostly real-time work. You&#8217;ll see how I fail, you&#8217;ll spot the mistakes I&#8217;ve done and did not even notice, you&#8217;ll see how I write README. And, most importantly, you will hopefully see some of the things that will help <i>yourself</i>.<br />
<br />
This video features the following tools/technologies:<br />
<br />
<ul style="text-align: left;">
<li>Ruby, Ruby On Rails</li>
<li>CoffeeScript</li>
<li>SASS</li>
<li>Git, Github</li>
<li>Vim (MacVim and Terminal)</li>
<li>Jasmine and basic testing of JavaScript and even CSS assets</li>
<li>etc</li>
</ul>
<div>
Additionally, before watching, make sure you Turn On the Volume. Rare person doesn&#8217;t like the music that my wife helped me prepare. Even if you don&#8217;t not like the video, you should like the music :)</div>
<div>
<br /></div>
<div>
I hope you enjoy it. <strong>UPDATE: Please watch it in full screen as the quality is lower than I expected.</strong>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>

<iframe width="560" height="315" src="http://www.youtube.com/embed/MWvLofLz04k?hd=1" frameborder="0" allowfullscreen></iframe>


</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
P.S.: Screencasting is really hard. And that&#8217;s my first. So&nbsp;apologies&nbsp;if something isn&#8217;t in-place.</div>
<div>
(If you can&#8217;t see the video here, open it on&nbsp;<a href="http://vimeo.com/32357445">Vimeo</a>. Alternatively, try <a href="http://www.youtube.com/watch?v=MWvLofLz04k">YouTube</a> - it should work with HTML5-only browser).</div>
<br />
<br />
<br />
<br /></div></div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
Pleased to know that you liked it. Yeah, the music sometimes goes a bit off. But it is still fun as for me :)</div>
</div>
<div class='comment'>
<div class='author'>Flaviu Simihaian</div>
<div class='content'>
Great video. I also love the music. Beethoven seems to get extra-dramatic near the testing pain point :)<br /><br />Look forward to seeing more in the future and hope to do some  myself.<br /><br />Thanks,<br /><br />Flaviu</div>
</div>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
Sorry about that. I&#39;ve embedded the YouTube version of the video. It is of a little better quality.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
Video on vimeo is bad quality, I had to watch it on Youtube. Thanks for videolesson.</div>
</div>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
If more people will need it, I will probably upload higher resolution somewhere. Have you tried <a href="http://www.youtube.com/watch?v=MWvLofLz04k" rel="nofollow">YouTube</a>?<br /><br />And in the future I will have to record at much lower screen resolution</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
If see screencast from page - text is unreadable and font size is too small, at full screen (1080p) - too blur and unreadable too. may be if i&#39;ll have possibility to view at custom player size - it&#39;s will be ok.</div>
</div>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
Try it on YouTube: http://www.youtube.com/watch?v=MWvLofLz04k<br /><br />I&#39;ll update the post a bit later with both links.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
Unfortunately vimeo does not support html5 video</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Use your Terminal like a Pro]]></title>
    <link href="http://ApproachE.com/blog/tips-on-usingterminal-in-mac/"/>
    <updated>2011-10-04T12:53:00+11:00</updated>
    <id>http://ApproachE.com/blog/tips-on-usingterminal-in-mac</id>
    <content type="html"><![CDATA[<div class='post'>
<div>
Keep your config in a separate dotfiles directory and under source control with the structure like:<br />

<pre><code>
~/dotfiles:
--+ bashrc, bash_profile
--+ ssh/config
-->--bash -&gt; (env, config, aliases). bash has source bach/env, bash/config etc.
</code></pre>

<br />
Then:<br />
<code>ln -s ~/.bashrc ~/bin/dotfiles</code>
<br />
<code>echo ". ~/.bashrc" > ~/.bash_profile</code>

<br />
<br />

Put everything into .bashrc except any long running tasks.<br />
.bash_profile - for interactive shells. But you can just usually source .bashrc.<br />

Now some keyboard shortcuts:<br />
<br />

<ul>
<li>Cntrl-a - go to the beginning of line</li>
<li>Cntrl-e - go to the end of line</li>
<li>Cntrl-k - delete everything to the right</li>
<li>Cntrl-w - delete previous word</li>
<li>ESC->-b - go back one word</li>
<li>ESC->-f - go forward one word</li>
</ul>

<br />
If you often connect via SSH like so:
<code>ssh -p 2323 username@my-server.example.com</code>

Then you can shorten it to <code>ssh my-server</code> if you will add entry to <code>~/.ssh/config</code>:
<pre><code>
Host my-server
    HostName my-server.example.com
    Port 2323
    User username
</code></pre>

Then you can use it as:

<pre><code>
# Tunnelling
ssh -L7997:127.0.0.1:7979 my-server

# Copy folder to server
scp my_folder my-server:my_other_folder/

# Or even use it with git
git clone my-server:repo-name.git

</code></pre>

<br /><br />

Now some useful things you can do in the terminal:

<ul>
<li><code>!!</code> - run previously executed command (you can do `sudo !!` for example)</li>
<li><code>!$</code> - last argument of previous command</li>
<li><code>!60</code> - run the command #60. Number comes from <code>history</code> command</li>
(for example: run <code>tail file.log</code> and then <code>cat !$</code> is same as <code>cat file.log</code></li>
<li><code>!echo</code> - rerun last command starting with echo</li>
<li>Ctrl-r - interactive search on history of commands; Use Ctrl-j to abandon.</li>
<li><code>!?file.log?!</code> - run the last matching command (not interactive)</li>
<li><code>^file.log^another-file.log</code> - run the last matching command replacing file.log with another-file.log</li>
<li><code>!?file.log?!</code> - run the last matching command (not interactive)</li>
<li><code>mv README.{txt,markdown}</code> - same as <code>mv README.txt README.markdown</code>.</li>
</ul>

<br /><br />

You will also appreciate power of the shell when using aliases and functions:
<pre><code>
alias ss=&quot;./script/server&quot;
alias s=&quot;git status&quot;
alias gca=&quot;git commit -am&quot;
alias zipr=&quot;zip -r&quot;

function take {
  mkdir $1
  cd $1
}
# take create-and-go-here

function gg() {
  git commit -v -a -m &quot;$*&quot;
}
# gg Commit message with no quotes
</code></pre>

<br /> <br />
But when functions get more complicated, you might want to use a scripting language (Ruby, Python etc).

<br />
Put those scripts into your ~/bin directory and add it to your PATH variable.

<br /><br />
There are also number of Mac specific tricks.
<br />
One is is <code>open anything</code> command that will open the file/directory in the default application.
<br />
You can also force it to use a specific app:
<code>open -a /Applications/Firefox.app index.html</code>.
<br />
This one becomes a good candiate for an alias.

<br /> <br />
You can also pipe output of any command into <code>pbcopy</code> command to copy it to the clipboard.
<br />
For example:
<code>cat index.html | pbcopy</code> will copy the content of the file into clipboard.
<br /><br />
You can also do it the other way around: <code>pbpaste &gt; index.html</code> or 
<code>pbpaste | grep "jquery"</code>.
<br /><br /><br />

Another useful thing <a href='http://homepage.mac.com/thomasw/OpenTerminal/'>OpenTerminal</a> (drag the app to finder toolbar).
It allows you to open terminal with the current directory set to the Finder window.

<br /><br /><br />
You can also use the keyboard to open terminal using <a href='http://www.obdev.at/products/launchbar/'>LaunchBar</a>. It does much more though. It acts like a global terminal for the system.


<br /><br /><br />
You can also try to use <code>zsh</code> shell. It will work with the existing bash aliases just fine.
<br /><br /><br />

Most of the tips here come from the PeepCode&#8217;s Advanced Command Line screencast.
<br />

Hope this helps you on your way to becoming a Terminal Guru.

</div></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Templating done easy - JavaScript HAML with Rails]]></title>
    <link href="http://ApproachE.com/blog/templating-done-easy-javascript-haml/"/>
    <updated>2011-08-19T19:26:00+10:00</updated>
    <id>http://ApproachE.com/blog/templating-done-easy-javascript-haml</id>
    <content type="html"><![CDATA[<div class='post'>
<h3>
HAML templating with no worries: native, precompiled HAML. Blazing fast and as easy to use as it can be. </h3>

<h3>
<strong>
<em>UPDATE: this functionality moved into <a href='https://github.com/dnagir/ruby-haml-js'>ruby-haml-js</a> gem, please use it instead.</em>
</strong>
</h3>

Recently I have been working on a Ruby gem that packs a set of common JavaScript libraries in one place so you can just reference those easily from <b>Rails 3.1</b> app.  But now I want to write a bit about a very handy tool that the gem includes.  I needed to work on a <a href='http://documentcloud.github.com/backbone'>Backbone</a> app and, unfortunately, there was no very simple and easy way of using HAML markup for my client side templates. Main problems: <ol>
<li>I don&#8217;t want to <b>embed</b> the template into the document.</li>
<li>The Underscore.js templating is ok, but it is <b>too verbose</b> for me (as most of others).</li>
<li>The <a href="https://github.com/creationix/haml-js">haml-js</a> is great, but I do not want to bother <b>precompiling</b> the templates.</li>
<li>I do not want to think about templating as another layer or component. I want it to <b>just work</b>.</li>
</ol>

<div>
Fortunately it was pretty easy solve these <em>problems</em> with the <a href="https://github.com/sstephenson/sprockets">Sprockets</a> and Rails 3.1.
</div>

<div>
So from now on you can just write normal HAML templates and consume those with no worries from JavaScript.
</div>

<div>
All you need to do, is to add <a href="https://github.com/dnagir/pakunok">pakunok</a> gem to your Rails 3.1 Gemfile.  This will give you templates as <b>native JavaScript functions</b> that you can use.
</div>


<div>
It&#8217;s better to <a href='https://gist.github.com/1156409'>see than hear</a>
</div>

<div>
<script src="https://gist.github.com/1156409.js">
</script>
</div>

<div>
 Feel free to head to the <a href="https://github.com/dnagir/pakunok/issues">issues</a> and provide some feedback or <a href="https://github.com/dnagir/pakunok/">read more</a>.</div></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Easy Rails deployment with Capistrano and custom Nginx configs]]></title>
    <link href="http://ApproachE.com/blog/easy-rails-deployment-with-capistrano/"/>
    <updated>2011-05-19T00:58:00+10:00</updated>
    <id>http://ApproachE.com/blog/easy-rails-deployment-with-capistrano</id>
    <content type="html"><![CDATA[<div class='post'>
<p>
In my <a href="http://blog.approache.com/2011/05/setting-up-ubuntu-1104-server-for-rails.html">previous post</a> I provided some info about setting up the server for rails app.

</p>

<p>
Now I am going to describe the Nginx configuration and example of Capistrano deployment file.
</p>

<p>
One thing that I don&#8217;t want to do for every new app I deploy is to go to the web server and change the settings (as a root user) so that the web server picks the Rails application.
</p>

<p>
In order to avoid that I decided to use nginx&#8217;s <a href="http://wiki.nginx.org/CoreModule#include">include</a> command. It allows to add include multiple nginx config files using UNIX wildcards.
</p>

<p>
So by simply adding this line to the nginx.config I make it possible to configure Nginx from Rails applicatoins themselves:
<code>include /home/*/apps/*/current/nginx.conf;</code>.

I decided to include all configs within <code>http</code> tag so that a Rails app can configure multiple servers for itself.
</p>

<p>
There are obvious drawbacks for this:

<ol>
<li>It is less &#8220;safe&#8221; as on application might affect others if you will start adding Nginx settings outside of the <code>server</code> tag. But I am ready to sacrifice this for the sake of having more flexibility by assuming all server citizens are good guys.</li>
<li>We still need to have root access to restart the Nginx. We shouldn&#8217;t need to do it often, so that&#8217;s ok with me.</li>
</ol>

Now relying on a very simple conventions, I can configure Nginx from within the app. Just in case you&#8217;ve missed it, the conventions are:

<ol>
<li>To deploy a rails app (and any Rack based app), user should put the app under his home directory in <code>apps/[name]/current</code>.</li>
<li>To &#8220;enable&#8221; an app, user should put <code>nginx.conf</code> file in <code>apps/[name]/current</code>.</li></ol>

</p>


<p>
But for now, all this cool structure isn&#8217;t very helpful unless we deploy the app.
</p>

<p>
I went with the Ruby de-facto deployment tool - Capistrano. There are enough resources on the net on how to &#8220;Capify&#8221; your application, so I won&#8217;t go into details. I assume you have just done <code>capify .</code> and understand what is going in there.
</p>

<p>
Briefly, what I need to do is following:

<ol>
<li>Deploy the app explicitly to a particular domain (staging, production, local server etc).</li>
<li>On every deployment - backup SQLite database (I know, I&#8217;ll use something better when I&#8217;ll have 1 million users).</li>
<li>Prepare Nginx config file for the server (it depends on the domain we deploy at).</li>
<li>Pre-Compile assets (SCSS in my case).</li>
</ol>

</p>

<p>
So grab <a href="https://gist.github.com/978737">the gist</a> (embedded below) with all the details and let me know what can be improved there. The usage is pretty simple: 
</p>

<p>
<code>cap deploy user=dnagir domain=connecty.approache.com</code>
</br />
You can deploy the same app multiple times to the same server with different subdomains and they will not conflict:
<br />

<code>cap deploy user=dnagir domain=staging.connecty.approache.com</code>
<br />
<code>cap deploy user=dnagir domain=demo.connecty.approache.com</code>

</p>

<p>
The most interesting I think is that the <code>nginx.conf</code> file is created during deployment using default Ruby templating engine and transfered over to the right location on the server. (But still remember root-ed Nginx restart is still required).
</p>

<p>You can look at the complete source in the <a href="https://github.com/dnagir/connecty/tree/bdd10b8e2bcd946a62cc66075d87ac107e513305">Connecty project</a> at Github.
</p>

<p>Please feel free to tell me what you think about this process.</p>

<script src="https://gist.github.com/978737.js?file=deploy.rb"></script>
<script src="https://gist.github.com/978737.js?file=nginx.production.conf.erb"></script></div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>jlertle</div>
<div class='content'>
Love it!</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setting up Ubuntu 11.04 server for Rails with RVM]]></title>
    <link href="http://ApproachE.com/blog/setting-up-ubuntu-1104-server-for-rails/"/>
    <updated>2011-05-19T00:09:00+10:00</updated>
    <id>http://ApproachE.com/blog/setting-up-ubuntu-1104-server-for-rails</id>
    <content type="html"><![CDATA[<div class='post'>
<p>
I had to set up the server (Ubuntu 11.04) for running couple of Rails apps and thought I could share the notes I&#8217;ve written while doing that. 

Any feedback and improvements are welcome.

</p>

<p>

<code>
<pre>
apt-get update ; apt-get upgrade

# set timezone
dpkg-reconfigure tzdata


# RVM
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

# update /etc/bash.bashrc


# -y to answer YES for questions
aptitude -y install build-essential bison openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev

rvm install 1.9.2; rvm use 1.9.2 --default

# while ruby is being installed prepare nginx
cd /usr/src
wget http://nginx.org/download/nginx-1.0.0.tar.gz
tar -xf nginx-1.0.0.tar.gz
cd nginx-1.0.0

# Use one place for installation
rm -r /opt/ && ln -fs /usr/local /opt

gem update --system ; gem update
gem install bundler
#install imagemagic
apt-get -y install imagemagick

# proceed with passenger
apt-get -y install libcurl4-openssl-dev
gem install passenger
passenger-install-nginx-module
# additional otions:
# --prefix=/opt/nginx
# --with-http_gzip_static_module --with-http_stub_status_module --with-http_sub_module


# add nginx autostart script: http://wiki.nginx.org/Nginx-init-ubuntu
# verify the correct paths
cd /opt && \
wget -O init-deb.sh http://library.linode.com/assets/602-init-deb.sh && \
mv /opt/init-deb.sh /etc/init.d/nginx && \
chmod +x /etc/init.d/nginx && \
/usr/sbin/update-rc.d -f nginx defaults


# add to /opt/nginx/conf/nginx.conf
include /home/*/apps/*/current/nginx.conf;
/etc/init.d/nginx restart



# copy ssh keys (from local computer)
cat ~/.ssh/id_rsa.pub | ssh root@my.server.com "mkdir ~/.ssh ; cat - >> ~/.ssh/authorized_keys"

# change default ssh port from 22 to something to get rid of nasty attacks
vim /etc/ssh/sshd_config # change the port number
service ssh reload

#install firewall?? No need for now as only openning 80,443 ports
# apt-get install ufw
</pre>
</code>

</p>

<p>
That should be enough for you to start using the server.
In the <a href="http://blog.approache.com/2011/05/easy-rails-deployment-with-capistrano.html">future post I plan to describe my setup to make deploying new applications easier</a>.
</p></div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
I&#39;ve used this guide for 3 apps and it&#39;s worked great.  However the step &quot;use one place for installation&quot; wipes everything out for some reason so I skip that part but otherwise thanks.</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Unix - do not reinvent the wheel]]></title>
    <link href="http://ApproachE.com/blog/unix-do-not-reinvent-wheel/"/>
    <updated>2011-05-19T00:00:00+10:00</updated>
    <id>http://ApproachE.com/blog/unix-do-not-reinvent-wheel</id>
    <content type="html"><![CDATA[<div class='post'>
<p>
One of the most interesting videos I watched from the <a href="http://video2010.scottishrubyconference.com/">Scottish RubyConf 2010</a> is <a href="http://video2010.scottishrubyconference.com/show_video/6/1">Unix: Rediscovering the wheel</a>. If you use Ruby/Rails and POSIX systems you gotta know those things.
This is just a quick list of notes to keep it mind. So you will have to Google if something catches your attention.
</p>

<p>

<code>
<pre>

Scheduling tasks with Cron
==========================
- define all tasks in cron
- don't make Ruby do scheduling


Background processing with ATD daemon
======================================
echo "convert image.jpg image.png" | batch


Logging with syslog
======================================
- don't use rails log

Resource limiting with rlimit
======================================
ulimit -v 102400
ruby -e "' ' * 1024 * 1024 * 1024 *1"
failed to allocate memory (NoMemoryError)

CPU and Disk IO priorities
======================================
nice -n 19 rake xapian:update # run rake with priority 19
ionice -c3 rake xapian:update # same for disk IO


Atomic renames
======================================
- don't use locks
- write to temp then rename

Secure self-cleaning temporary files
======================================
- create temp fie
- delete it while holding it open
- write/read securely


Page cache expiry with find
======================================
find public/cache -type f --mmin +10 -delete # del all files 10 mins old in a "transaction"

Log rotation with logrotate
======================================
- Rails sucks at it, use time proven and tested UNIX


Managing daemons with start-stop-daemon
==========================================
- don't reinvent the wheel starting/stoping daemons (mogrels etc)
    start-stop-daemon -d $railsdir -b -o -p $pidfile --start --starts rake xapian:update
- run cron tasks using start-stop-daemon to avoid race condition (it will exit if process already runs)


Real time signals
==========================================
use it in ruby:
trap("USR1") { reopen_xapian_db }


Raliable messaging with... SMTP!
==========================================
Due to atomic and reliable delivery it can be use as a message queue.
Can replace RabbitHQ etc


dbus
==========================================
UNIX based Messaging system


Self-organising systems with AVAHI
==========================================
Bonjour??


Modularised config files
==========================================
/etc/cron.d/rails-myapp
/etc/logrotate.d/rails-myapp


Watchdog daemon
==========================================





</pre>
</code>

</p></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What I've learned from Scottish RubyConf]]></title>
    <link href="http://ApproachE.com/blog/what-ive-learned-from-scottish-rubyconf/"/>
    <updated>2011-05-18T23:52:00+10:00</updated>
    <id>http://ApproachE.com/blog/what-ive-learned-from-scottish-rubyconf</id>
    <content type="html"><![CDATA[<div class='post'>
<p>
I watched the videos from the <a href="http://video2010.scottishrubyconference.com/">Scottish RubyConf 2010</a> and thought I could share some interesting moments as simple notes. So there you go:
</p>

<p>

<code>
<pre>

Harmony for browser testing

Capybara.driver = :rack_test # uses Harmony and can run JS

Good talk about Arel: 1LT_04-mp4_500mbs.mp4

Rack GeoIP.
Rack GoogleAnalytics
Rack::Cache (standard)
Rack::CacheBuster

Server side include to render page without parts of content that fail
(Nginx + Rack)

EvenMachine:: WebSockets add-on uses JS like API.
Other options:
-em-websocket
-cramp (higher level websocket)
-sunshowers
-node.js
pusherapp.com

Initialise multiple variables in JS:
var a = 1, b = 2, noInitialised;
jQuery has "end" method to go up in the chain.



VIM
:copen - opens the console output
f - find next occurence of char in this line
dap - delete paragraph
cap - change
yap - yank
ytCHAR - yank from here to next CHAR
Ctrl-v - visual block mode
:split, :sp, :vspilt, :vsp - split into 2 wins
ls - list buffers touched
q1, q2, q3... - record macro into register
@1, @2, @3... - play the macro from register

:R - Rails related file
:A - Rails alternate file
:Rextract - Rails partial extract
Shift-k - integrated Ruby ri

figutive.vim - more extensions: Glog, Gblame, Gstatus, Gdiff, Ggrep etc
snippets.vim
nerdtree.vim - files tree view
surround.vim
unimpaired.vim - auto-brackets
Hashrocket configured Vim at Github hashrocket/dotmatrix
Vimium, Vimperator - Vim in browser
Remotely connect and pair in Vim


UTF-8 is backwards compatible with ASCII
Ruby doesn't know about UTF-16 - it's messy

Globalization TODO:
- Do same as .NET CultureInfo
- Do different ways to localize different kinds of langs


You can generate UML model of Rails model using:
railroad -M | dot Tpng > model.png
uml dumper

Metrics:
- rake stats # LOCs
- FLOG Weighting the code AST - Assignment Branch Condition (ABC)
- FLAY - code similarities
- Saikuro - cyclomatic complexity
- Roodi - design issues
- Reek - design issues and specific smells
- Churn - changes to file with Git
- Rcov - test coverage
- Heckle - test coverage with code mutation
- metric_fu


</pre>
</code>

</p>

<p>
You can also grab the <a href="https://gist.github.com/978593">Gist</a>. Hope you find some moment useful.
</p></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Unit test actions with ValueProviderFactories in ASP.NET MVC3]]></title>
    <link href="http://ApproachE.com/blog/unit-test-actions-with/"/>
    <updated>2011-03-18T11:35:00+11:00</updated>
    <id>http://ApproachE.com/blog/unit-test-actions-with</id>
    <content type="html"><![CDATA[<div class='post'>
<p><strong>The problem:</strong> In the process of upgrading from MVC2 to MVC3 we have faced an issue where some of the <a href="http://stackoverflow.com/questions/4603741/how-to-unit-test-valueproviderfactories-in-asp-net-mvc3">ValueProviders gain explicit access to static HttpContext</a> thus making it too hard to test complex actions.</p>  <p>The solution was not obvious at first and I want to provide enough context before the solution. The way I test the controllers is this:</p>  <p>&#160;</p>  <p>&#160;</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">[TestFixture]
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> CurrentUserControllerTest : BaseTestFixture {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">private</span> CurrentUserController controller;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">private</span> Mock&lt;ICurrentUserService&gt; userService;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">private</span> FakeHttpContext http;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> Init() {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        userService = <span style="color: #0000ff">new</span> Mock&lt;ICurrentUserService&gt;();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        controller = <span style="color: #0000ff">new</span> CurrentUserController(Services.Account, userService.Object)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            .FakeContext(context =&gt; http = context);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    [Test]
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CanSeeSecuritySettingsPage() {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        userService.Setup(x =&gt; x.ViewUser()).Returns(<span style="color: #0000ff">new</span> User {SecurityQuestion = &quot;<span style="color: #8b0000">sq</span>&quot;});
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        controller.SecuritySettings()
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            .ShouldHaveModel&lt;CurrentUserController.SecuritySettingsInfo&gt;()
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            .User.SecurityQuestion.Should().Be(&quot;<span style="color: #8b0000">sq</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    [Test]
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SuccesfulUpdateRedirects() {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        controller.UpdateSecuritySettings()
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            .ShouldRedirectTo(action: &quot;<span style="color: #8b0000">Index</span>&quot;, controller: &quot;<span style="color: #8b0000">Dashboard</span>&quot;);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<p>The most relevant piece of code here is the extension method <strong>FakeContext</strong>. It ensures the controller is not going to access real HttpContext. The main difference between MVC2 and 3 is that the latter uses HttpContext in FormValueProviderFactory and QueryStringValueProviderFactory. So we need to get rid of it. And of course we don’t want to modify all our tests and complicate them providing explicitly <a href="http://weblogs.asp.net/scottgu/archive/2008/10/16/asp-net-mvc-beta-released.aspx#six">FormCollection</a>. Additionally we definitely do not want to go into trouble <a href="http://stackoverflow.com/questions/1686778/why-mock-httpcontext-if-it-can-be-constructed">instantiating HttpContext</a>.</p>

<p>Fortunately MVC is extensible enough and has number of hook that we can use. In this case we need to replace those two bustards (FormValueProviderFactory and QueryStringValueProviderFactory). Which can be done with this simple extension method:</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span> ValueProviderFactoresExtensions {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ValueProviderFactoryCollection ReplaceWith&lt;TOriginal&gt;(<span style="color: #0000ff">this</span> ValueProviderFactoryCollection factories, Func&lt;ControllerContext, NameValueCollection&gt; sourceAccessor) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        var original = factories.FirstOrDefault(x =&gt; <span style="color: #0000ff">typeof</span>(TOriginal) == x.GetType());
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">if</span> (original != <span style="color: #0000ff">null</span>) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            var index = factories.IndexOf(original);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            factories[index] = <span style="color: #0000ff">new</span> TestValueProviderFactory(sourceAccessor);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">return</span> factories;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">class</span> TestValueProviderFactory : ValueProviderFactory {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> Func&lt;ControllerContext, NameValueCollection&gt; sourceAccessor;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">public</span> TestValueProviderFactory(Func&lt;ControllerContext, NameValueCollection&gt; sourceAccessor) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">this</span>.sourceAccessor = sourceAccessor;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> IValueProvider GetValueProvider(ControllerContext controllerContext) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> NameValueCollectionValueProvider(sourceAccessor(controllerContext), CultureInfo.CurrentCulture);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}</pre></pre>

<p>&#160;</p>

<p>And the final implementation of FakeContext extension that I use (you will need to trim it to your particular case) is:</p>

<p>&#160;</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> TController FakeContext&lt;TController&gt;(this TController controller, Action&lt;FakeHttpContext&gt; exposeAction = null) where TController: Controller {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    ApplicationMetaData.RegisterAll(); // Additionally register all ModelBinder so tests behave <span style="color: #0000ff">is</span> <span style="color: #0000ff">in</span> production
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">if</span> (ViewEngines.Engines.Where(x =&gt; x <span style="color: #0000ff">is</span> SparkViewEngine).Empty()) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        // We only use Spar view engine that can render view during testing
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        ViewEngines.Engines.Clear();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        ViewEngines.Engines.Insert(0, GetTestViewFactory());
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }            
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    // That <span style="color: #0000ff">is</span> the entry <span style="color: #0000ff">to</span> all the fakes, implementation <span style="color: #0000ff">is</span> trivial so <span style="color: #0000ff">not</span> here
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    var context = <span style="color: #0000ff">new</span> FakeHttpContext();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    controller.ControllerContext = <span style="color: #0000ff">new</span> ControllerContext(context, <span style="color: #0000ff">new</span> RouteData(), controller);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    controller.Url = <span style="color: #0000ff">new</span> UrlHelper(<span style="color: #0000ff">new</span> RequestContext(context, <span style="color: #0000ff">new</span> RouteData()));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    // <span style="color: #0000ff">And</span> <span style="color: #0000ff">finally</span>, here we ensure no ValueProviders access HttpContext
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    ValueProviderFactories.Factories
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        .ReplaceWith&lt;FormValueProviderFactory&gt;(ctx =&gt; ctx.HttpContext.Request.Form))
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        .ReplaceWith&lt;QueryStringValueProviderFactory&gt;(ctx =&gt; ctx.HttpContext.Request.QueryString));
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">if</span> (exposeAction != null)
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        exposeAction.Invoke(context);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">return</span> controller;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}        </pre></pre>

<p>&#160;</p>

<p>Hope that helps. Have fun!</p>  </div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
I can&#39;t remember already, but there are couple of the ValueProviders that you need to replace. Just look at the exceptions you get. Should be pretty straight forward. Worked for all other people.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
duzn&#39;t work</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Screencasts for this weekend]]></title>
    <link href="http://ApproachE.com/blog/screencasts-for-this-weekend/"/>
    <updated>2010-12-13T09:53:00+11:00</updated>
    <id>http://ApproachE.com/blog/screencasts-for-this-weekend</id>
    <content type="html"><![CDATA[<div class='post'>
<p>This weekend I was watching the screencasts instead of Sunday movies. It left me with a lot of inspiration and impressions. So I thought I would share the stuff you might also be interested in:</p>  <ol>   <li><a href="http://tekpub.com/conferences/ndc2010/aspnet-mvc-vs-ruby-on-rails---the-net-rocks-smackdown">ASP.NET MVC vs Ruby on Rails - The .NET Rocks Smackdown</a></li>    <li><a href="http://tekpub.com/conferences/rubyconf2010/dhh">Why Ruby?</a></li>    <li><a href="http://tekpub.com/conferences/ndc2010/testing-csharp-and-aspnet-applications-with-ruby">Testing C# and ASP.NET Applications with Ruby</a></li>    <li><a href="http://tekpub.com/conferences/ndc2010/ruby-for-net-developers">Ruby for .NET developers</a> (Scott Belware is awesome BTW)</li>    <li><a href="http://tekpub.com/conferences/ndc2010/riding-ironruby-on-rails">Riding IronRuby On Rails</a></li> </ol>  <p>&#160;</p>  <p>Other things are:</p>  <ol>   <li><a title="http://tekpub.com/conferences/ndc2010/monotouch-deep-dive" href="http://tekpub.com/conferences/ndc2010/monotouch-deep-dive">MonoTouch DeepDive</a></li>    <li><a href="http://peepcode.com/pages/rails-3-screencasts">Meet Rails 3</a> by PeepCode (a producer of high-quality screencasts)</li> </ol>  <p>I think if you are a software engineer with open mind then you do need to watch some of the videos. This is especially true if you are a .NET developer who wants to explore other areas and technologies.</p>  </div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Stuff learned today - Ruby and Rails]]></title>
    <link href="http://ApproachE.com/blog/stuff-learned-today-ruby-and-rails/"/>
    <updated>2010-12-09T09:50:00+11:00</updated>
    <id>http://ApproachE.com/blog/stuff-learned-today-ruby-and-rails</id>
    <content type="html"><![CDATA[<div class='post'>
<ol>
<li>Ruby ignores underscores in numbers, so you can write 53782156 as&nbsp;53_782_156 which is much nicer.</li>
<li><a href="https://groups.google.com/group/formtastic/browse_thread/thread/d4b200e3d8073329">Suggested</a> localisation for Formtastic&#8217;s collections.&nbsp;Not sure whether it is important as it is still pretty easy to workaround.</li>
<li>To use all the ActiveSupport (v3), do <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">require &#8216;active_support/all&#8217;</span> (note the underscore!).</li>
<li>We can add methods to associations by opening a block and (but scopes are much cleaner on the other end of association class).</li>
<li>Testing &#8220;access denied&#8221; and &#8220;requires user&#8221; is easier with custom matchers.</li>
<li>Rails URL helpers are not available in custom matchers for some reason.</li>
<li>Shoulda&#8217;s RSpec matcher validates_presence_of does not work with non-persistent models.</li>
<li>Rails params hash has string keys, not symbols. Got issues with it when relying on keys being symbols.</li>
</ol></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rules of Productivity]]></title>
    <link href="http://ApproachE.com/blog/rules-of-productivity/"/>
    <updated>2010-11-29T15:29:00+11:00</updated>
    <id>http://ApproachE.com/blog/rules-of-productivity</id>
    <content type="html"><![CDATA[<div class='post'>
<p>How do we get more work done? It is a question that every manager and every passionate worker faces. Yet, for the most part, teams operate on gut instinct and habit. The results are less than optimal. [<a href="http://www.lostgarden.com/2008/09/rules-of-productivity-presentation.html">source</a>]</p>  <h2></h2>  <h2>What is productivity?</h2>  <ul>   <li>+ Work accomplished </li>    <li>- Work required to fix defects </li>    <li>- Work required to fix bad design decisions </li> </ul>  <p>Productivity can be <strong><em>negative </em></strong>when there is more harm than good.</p>  <p><a href="http://lh3.ggpht.com/_6a0bIbZ1HXw/TPMsQV26e9I/AAAAAAAAEx4/W_cKdhYLIEc/s1600-h/image%5B9%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_6a0bIbZ1HXw/TPMsREicCvI/AAAAAAAAEx8/UGFxiCYKKxc/image_thumb%5B5%5D.png?imgmax=800" width="455" height="347" /></a> </p>  <h2>&#160;</h2>  <h2>Experiment 1: Overtime</h2>  <p>Working more than&#160; 40 hours a week leads to decreased productivity.</p>  <ul>   <li>&lt; 40 hours/week – working not “enough”. </li>    <li>&gt; 60 hours/week – small productivity boost. </li> </ul>  <p>The boost only lasts for 3 to 4 weeks and then turns <em><strong>negative</strong></em>. Though can be used for a short-time productivity increase.</p>  <p>So, work 40 hours a week with time for rest and family. Never work 2 months of 60 hrs/week. Overall productivity will be lower, despite the initial boost.</p>  <h2></h2>  <h2>Experiment 2: Work harder in bursts.</h2>  <ul>   <li>Take advantage of the burst during overtime. </li>    <li>Crunch for a week and work only 40 hrs on another week. </li>    <li>Any more efficient work patterns? </li> </ul>  <p>Anything over 40 hrs/week results in a recovery period, no matter how you split it up. 40 hrs/week can be 10 hrs/day for 4 days and one day off. This pattern of work can increase productivity by 10-70%.<a href="http://lh4.ggpht.com/_6a0bIbZ1HXw/TPMsSG9AnZI/AAAAAAAAEyA/Wq0Ax8mVAgc/s1600-h/image%5B5%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_6a0bIbZ1HXw/TPMsS0R9wwI/AAAAAAAAEyE/3C1FYViAnek/image_thumb%5B3%5D.png?imgmax=800" width="468" height="357" /></a></p>  <p>So:</p>  <ul>   <li>Raise productivity immediately with short spurts &lt; 3 weeks. </li>    <li>Overtime temporarily to meet deadlines. </li>    <li>Plan for the reduction in productivity immediately afterwards. </li>    <li>Consider 4-day work week as a flexitime option. </li> </ul>  <p>&#160;</p>  <h2>Experiment 3:&#160; Performance for knowledge workers declines after 35 hrs, not 40.</h2>  <ul>   <li>Creativity and problem solving decreases faster with fatigue than manual labour. </li>    <li>Grinding&#160; out problems by working longer&#160; on average result in inferior solutions. </li>    <li>Lack of sleep is particularly damaging. </li> </ul>  <p>So:</p>  <ul>   <li>Overtime kills creativity. </li>    <li>If you are stuck on a problem, go home or take a break. </li>    <li>Get 8 hrs of sleep to improve your problem solving abilities. </li> </ul>  <p>&#160;</p>  <h2>Experiment 4: Teams on overtime feel like they are doing more, but actually accomplish less.</h2>  <ul>   <li>Team with overtime feels like they are doing much more than the team without overtime. </li>    <li>Team without overtime produces the better product and accomplishes more. </li> </ul>  <p><a href="http://lh3.ggpht.com/_6a0bIbZ1HXw/TPMsTkqVtLI/AAAAAAAAEyI/HZvCvNe_lNY/s1600-h/image%5B13%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_6a0bIbZ1HXw/TPMsUp4sGLI/AAAAAAAAEyM/IHbhVUR7D-k/image_thumb%5B7%5D.png?imgmax=800" width="476" height="363" /></a> </p>  <p>Humans ignore the systematic costs and physiological biases:</p>  <ul>   <li>Failure to measure (cost of defects, bad design decisions, missed opportunities). </li>    <li>Linear extrapolation (initial productivity boost is seen as same in the future). </li>    <li>Habit (a bad one!). </li>    <li>Self reported excellence (behaviour rewarded independent of the results). </li> </ul>  <p>So:</p>  <ul>   <li>The feeling of increased long-term productivity is FALSE. </li>    <li>Use customer metrics to determine the productivity. </li> </ul>  <p>&#160;</p>  <h2>Experiment 5: Productivity is maximised in small teams of 4-8 people.</h2>  <ul>   <li>Productivity of a small group is 30-50% higher than groups over 10 people. </li>    <li>Too high cost of communication for groups with &gt; 10 people. </li>    <li>Smaller teams don’t have enough breadth to solve a wide array of problems. </li> </ul>  <p>So:</p>  <ul>   <li>Split your teams into cross-functional teams. </li>    <li>Link small teams using &#8216;”scrum-of-scrums”. </li>    <li>Create processes for:      <ul>       <li>growing new teams; </li>        <li>splitting large teams; </li>        <li>transitioning to new projects; </li>     </ul>   </li> </ul>  <p>&#160;</p>  <h2>Experiment 6: Seat people on the same team together in a closed team room.</h2>  <ul>   <li><em><strong>100% increase </strong></em>in productivity. </li>    <li>Faster communication and problem-solving. </li>    <li>Fewer external interruptions to the team increase overall productivity. </li> </ul>  <p>So:</p>  <ul>   <li>Seat the team in their own room. With walls. </li>    <li>Give at least 5 sqr/meters per person. </li>    <li>Create side rooms for private conversations, phone calls, meetings. </li>    <li>Minimise non-team distractions. </li> </ul>  <p>&#160;</p>  <h2>Experiment 6: Cross-functional teams outperform siloed teams</h2>  <ul>   <li>Produced more effective solutions in the same time. </li>    <li>Much more likely to generate breakthrough solutions. </li>    <li>Short-term loss of negotiation of norms. </li> </ul>  <p>This is why:</p>  <ul>   <li>Fewer external dependencies mean fewer lengthy blockages. </li>    <li>Team has the breadth to see the forest, not just the trees. </li>    <li>Different perspectives mean lower chance of groupthink. </li> </ul>  <p>So:</p>  <ul>   <li>Create the team where every skill needed to solve the problem at hand is in the same room. </li>    <li>Limit the charter: “Do everything = big team”. </li>    <li>Fulltime: focused team member efforts. <em><strong>Multitasking = 15% drop in productivity</strong></em>. </li> </ul>  <p>&#160;</p>  <h2>Experiment 8: Scheduling at 80% of team capacity produces better products.</h2>  <ul>   <li>Scheduling at 100% doesn’t give space to creativity. </li>    <li>No lost time: passionate workers keep thinking. </li>    <li>The 20% goes into new idea generation and process improvements. </li>    <li><em><strong>Producing 20 great features is usually far more profitable than 100 competent features</strong></em>. </li> </ul>  <p>Why?</p>  <ul>   <li>Allows employees to explore many options cheaply. </li>    <li>Gives time to prototype breakthrough solutions that sound crazy on paper. </li>    <li><em><strong>Allows people to pursue passions</strong></em>. </li> </ul>  <p>So:</p>  <ul>   <li>Schedule 20% below possible velocity. </li>    <li>Hold periodic reviews of side projects and award interesting ideas. </li>    <li>Publicise and reward side projects that make their way into production. </li>    <li>Keep a public list of important things if anyone runs out of work (happens rarely). </li> </ul>  <p>&#160;</p>  <h2>Other productivity Techniques</h2>  <h3>Experimentation culture:</h3>  <ul>   <li>Fail faster to find success sooner. </li>    <li>Short iterations. </li>    <li>User metrics such as A/B testing. </li>    <li>State gate portfolio management. </li> </ul>  <h3>Safety nets:</h3>  <ul>   <li>Test-Driven-Development. </li>    <li>Daily/weekly access to real customers. </li> </ul>  <h3>Empower the team</h3>  <ul>   <li>Constraints-based requirements, not mandates from above. </li>    <li>Training. </li> </ul>  <p>See the original <a href="http://www.lostgarden.com/2008/09/rules-of-productivity-presentation.html">PDF</a>.</p>  </div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby On Rails vs ASP.NET MVC]]></title>
    <link href="http://ApproachE.com/blog/ruby-on-rails-vs-aspnet-mvc/"/>
    <updated>2010-11-28T23:59:00+11:00</updated>
    <id>http://ApproachE.com/blog/ruby-on-rails-vs-aspnet-mvc</id>
    <content type="html"><![CDATA[<div class='post'>
I have been watching the ASP.NET MVC vs Ruby On Rails talk from the <a href="http://tekpub.com/conferences/ndc2010">Norwegian Developers Conference 2010</a> and just want to make a number of quotes that I particularly liked. My apologies if I missed something, but I believe it would be interesting to read it for those who don’t want to spend 48 minutes to watch the whole thing. I believe the quotes here really summarise the atmosphere during the talk.<br />
So here we go:<br />
<blockquote>
Rails was extracted from the real world work sweat, blood, tears, everything..</blockquote>
And it feels like it is.<br />
<blockquote>
ASP.NET MVC is a &#8220;me too&#8221; framework - trying to compete with other solutions. ASP.NET MVC is not part of the story for WebForms, not quite fit.</blockquote>
Aha. Try to tell WebForms guy about MVC :)<br />
<blockquote>
Microsoft promotes it as an option. Option for what?</blockquote>
These words from Rob Conery probably mean that MVC is something that was not “designed” to be mainstream. But rather an “option” for… well web development on .NET.<br />
<blockquote>
[About TekPub]…rewrite point for startup - reconsidered BizSpark. We wanted to stay small.We needed fast, easy framework. Up in the cloud, scalable, zero cost, everything.</blockquote>
There was a lot of buzz behind the <a href="http://blog.approache.com/2010/05/quotes-moving-from-aspnet-mvc-to-ruby.html">decision to move to Rails</a> by Rob Conery who was a .NET advocate. But it was a happy business AND technical decision.<br />
<blockquote>
Rails came out of a need. MVC hasn&#8217;t. NHibernate came out of a need. Entity Framework hasn&#8217;t. It&#8217;s always the same: solving problems they personally don&#8217;t have, so they are not in the context of their problems.<br />
Microsoft projects often come out of suppositions.</blockquote>
That is very common with Microsoft. They have to be everywhere and at the same time nowhere. Anything “new” that comes out from Microsoft has already been adopted and they are just catching up.<br />
<blockquote>
Dell is rebuilding everything in <a href="http://asp.net/">ASP.NET</a> MVC (instead of WebForms).</blockquote>
Good for them. In any case, ASP.NET MVC&nbsp; IS a good thing to have in .NET world. And that’s my preference for Web development in .NET. Probably same goes with Dell.<br />
<blockquote>
MVC redirected the attention back to .NET after .NET Web developers started moving to Rails.</blockquote>
True. And in fact, most of the features of ASP.NET MVC were borrowed from Rails. So that was one of the easiest ways to hold .NET gurus back.<br />
<blockquote>
Why would .NET developers move to Rails?      <br />Testing in rails is…uhh… it’s something you realise when you do it. Testing tools like RSpec and Cucumbet are just natural.       <br />Deployment – Capistrano, Heroku – just unbelievable.</blockquote>
Cannot agree more on this. Testing “just works”, deployment “just works” it all “just works”.<br />
<blockquote>
In .NET we like to overcomplicate ourselves. Something too simplistic can’t be good. [No worries with SRP principle – objects aware of the persistence and similar].      <br />In .NET we question more.</blockquote>
Speaking about myself, I do agree with it. Partially due to the nature of .NET (C#), partially because testing is harder, but also just because .NET developers try to solve problems in advance assuming those will exists (while in many cases they will not).<br />
<blockquote>
The MVC/MonoRail and Ruby On Rails have the same features.</blockquote>
Read on…<br />
<blockquote>
You have the same names of the features, but the experience is dramatically different. There’s incredible amount of software out of the box to do anything.      <br />ASP.NET NVC hasn’t even got a plug-in mechanism.</blockquote>
So true! So true!<br />
<blockquote>
Why do we have to wait for 2 years to get the innovation that we already have available to us right now in Rails?</blockquote>
The rails community moves with small changes all the time, while .NET – with large in couple of years time. So for Rails it is a normal evolution, while for .NET it is rather a revolution.<br />
<blockquote>
[about Rails]… it means you are building a web site, and you are not rebuilding the stuff that has already been built. You are building Business.</blockquote>
Oh, yes. Having higher level plug-ins (nearly as Service-Oriented-Architecture components) it opens much more opportunities for business.<br />
<blockquote>
Not everybody is fortunate of making decisions at work [on choosing technology].</blockquote>
Try to push a new technology in a corporate environment with all the bureaucratic procedures. No f…ing way! Unless you are the one who decides.<br />
<blockquote>
Building web sites on .NET is about building web sites in a corporate environment. And that’s not about productivity. That’s not about really, really, really compressed budget where every decision is your life and death decision…[and then] It’s like we have a budget, but is is rather a suggestion.</blockquote>
Not much to comment on here. Don’t care about money – you are a .NET shop. Otherwise – probably Rails.<br />
<blockquote>
It’s about how fast you can turn your ideas into money.</blockquote>
Well said!<br />
<blockquote>
Most of the cost of long lived projects is re-learning. Ruby code is just scan and get it.</blockquote>
Indeed, Rails, would not even exist without such a beautiful language as Ruby. It makes code easy to understand.<br />
<blockquote>
In Ruby there is just less code to see where a problem might be. A lot less code! And the code is so usable that you can really spot the problems really quickly.</blockquote>
Again so true. Just have a look, for example, at some OSS projects. They do so much with so little code. That’s just amazing.<br />
<br />
At the end, I must admit that I do like the .NET platform, but Ruby and Rails just feels much better to me and ALL of the things I currently do for myself, I do using Ruby/Rails.<br />
It is just much more fun!</div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
Twitter &#8230;<br /><br />Remember running your site in .NET or RoR is not going to make a whole lot of difference in speed if your database architecture sucks or your website does alot of IO.<br /><br />ex. alot of Google&#39;s products are written in Python but thats just a front alot of the actual business logic is probably implemented in the back in Java or whatever they prefer.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
Check benchmarks on the web, java and .net have better performance.<br /><br />Also, i&#39;d like to know a big app (300 tables and millions of entries) on RoR.<br /><br />Visual Studio is a big thing also.<br /><br />But, normally i use rails for blogs and websites x)</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
I expected a serious comparison but instead I get an idiot ranting about no further innovation needed because he found something he likes.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
So biased. One more thing, rails is designed as dsl for web apps while .net is platform for everything in windows.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
haha, soooo biased&#8230;. and lame.</div>
</div>
<div class='comment'>
<div class='author'>Alex Kaushovik</div>
<div class='content'>
Rails is the best!</div>
</div>
<div class='comment'>
<div class='author'>4nkh</div>
<div class='content'>
Long live to ROR!!!!</div>
</div>
<div class='comment'>
<div class='author'>p()thesis</div>
<div class='content'>
Good post.  I&#39;m a PHP/Rails developer considering venturing into .NET development, so I find this helpful.</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Render any ASP.NET MVC ActionResult to a string]]></title>
    <link href="http://ApproachE.com/blog/render-any-aspnet-mvc-actionresult-to/"/>
    <updated>2010-11-11T17:05:00+11:00</updated>
    <id>http://ApproachE.com/blog/render-any-aspnet-mvc-actionresult-to</id>
    <content type="html"><![CDATA[<div class='post'>
<p>I often see questions on the net about how to render a view to a string so it can be used somewhere.</p>  <p>My approach allows doing it without thinking about all the boilerplate code. Additionally not only the ViewResult can be rendered into a string but just about any type of the result. Here is example on how to return a JSON including the result of the view as additional information:</p>  <p>&#160;</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #008000">// Controller Action:</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> JsonResult DoSomething() {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    var viewString = View(&quot;<span style="color: #8b0000">TheViewToRender</span>&quot;).Capture(ControllerContext);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> JsonResult {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        Data = <span style="color: #0000ff">new</span> {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            time = DateTime.Now,
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            html = viewString
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    };
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>&#160;</p>

<p>This can be done with 2 simple utility classes below. Just include them somewhere into your project.</p>

<p>&#160;</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ResponseCapture : IDisposable {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> HttpResponseBase response;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> TextWriter originalWriter;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">private</span> StringWriter localWriter;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">public</span> ResponseCapture(HttpResponseBase response) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">this</span>.response = response;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            originalWriter = response.Output;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            localWriter = <span style="color: #0000ff">new</span> StringWriter();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            response.Output = localWriter;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">string</span> ToString() {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            localWriter.Flush();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">return</span> localWriter.ToString();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Dispose() {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">if</span> (localWriter != <span style="color: #0000ff">null</span>) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                localWriter.Dispose();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                localWriter = <span style="color: #0000ff">null</span>;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                response.Output = originalWriter;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span> ActionResultExtensions {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">string</span> Capture(<span style="color: #0000ff">this</span> ActionResult result, ControllerContext controllerContext) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">using</span> (var it = <span style="color: #0000ff">new</span> ResponseCapture(controllerContext.RequestContext.HttpContext.Response)) {
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                result.ExecuteResult(controllerContext);
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                <span style="color: #0000ff">return</span> it.ToString();
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    }
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>Enjoy and let me know if it works for you.</p>  </div>
<h2>Comments</h2>
<div class='comments'>
<div class='comment'>
<div class='author'>The Dode</div>
<div class='content'>
Never mind. I found the problem. I miss the @model.</div>
</div>
<div class='comment'>
<div class='author'>The Dode</div>
<div class='content'>
Does this work with Razor?<br /><br />Compiler Error Message: CS1973: &#39;System.Web.Mvc.HtmlHelper&#39; has no applicable method named &#39;TextBox&#39; but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
After very long looking at the code, I noticed that I typed &quot;@Model&quot;. it should be &quot;@model&quot;.<br />I didn&#39;t know model is case-sensitive.</div>
</div>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
Email me a sample project and I will have a look. Hard to say anything without seeing it.</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
It almost works.. <br />If my view contains &quot;@Model&quot; on the first line. This line will be also in the output.<br /><br />&quot;@Model x.y&quot; will be in the string as &quot;x.y x.y&quot;<br /><br />any ideas ?</div>
</div>
<div class='comment'>
<div class='author'>Anonymous</div>
<div class='content'>
Thanks a lot, this helped!</div>
</div>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
For the .NET 3.5 it will be needed to substitute the HttpContext on the controller and involves a bit more code, but still is possible. Have a look for an <a href="http://www.klopfenstein.net/lorenz.aspx/render-partial-view-to-string-in-asp-net-mvc" rel="nofollow">example</a></div>
</div>
<div class='comment'>
<div class='author'>tecnocrata</div>
<div class='content'>
Hello<br />I have a question. How can I do it in .NET Framework 3.5? in thi, Output property doesn&#39;t have a setter method.<br />Could you help me please?</div>
</div>
<div class='comment'>
<div class='author'>Dmytrii Nagirniak</div>
<div class='content'>
You can write:<br /><br />View(&quot;ViewName&quot;).With(&quot;name&quot;, &quot;Dima&quot;).With(&quot;likes&quot;, &quot;Ruby&quot;).Capture(ControllerContext)<br /><br /><br />with this simple extension method:<br /><br />public static ViewResult With(this ViewResult vr, string key, object value) {<br />  vr[key] = value;<br />  return vr;<br />}</div>
</div>
<div class='comment'>
<div class='author'>Gabriel</div>
<div class='content'>
This is a cleaner solution that others out there.  Does anyone have an example if the Action also uses parameters?</div>
</div>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RSpec 2.0 cheat sheet by example]]></title>
    <link href="http://ApproachE.com/blog/rspec-hints-and-techniques/"/>
    <updated>2010-11-05T20:33:00+11:00</updated>
    <id>http://ApproachE.com/blog/rspec-hints-and-techniques</id>
    <content type="html"><![CDATA[<div class='post'>
<p>The Ruby developers know and hear a lot of buzz about RSpec BDD framework. The RSpec specifications code is so easy to read, but for my it is often hard to write. So I intend to produce a small cheat-sheet for RSpec syntax for myself.</p>  <p>Most of it come from the <a href="http://www.pragprog.com/titles/achbd/the-rspec-book">RSpec Book</a> in rather unusual way. As a RSpec itself (unfortunately not runnable for now).</p>  <p>Please feel free to use it in any way you want and correct the mistakes.</p>  <p>So <a href="https://gist.github.com/663876">here we go</a>:</p> <script src="https://gist.github.com/663876.js?file=rspec-syntax-cheat-sheet.rb"></script>  </div>
]]></content>
  </entry>
  
</feed>
