<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>A Journal of Technical Matters</title><link>https://toasterlovin.com/</link><description>Notes on Ruby on Rails, PostgreSQL, Ruby and Vim by Richard Jones.</description><language>en-US</language><lastBuildDate>Tue, 19 May 2020 04:51:16 +0000</lastBuildDate><atom:link href="https://toasterlovin.com/rss/" rel="self" type="application/rss+xml"/><item><title>Extending rails.vim Navigation Commands with projectionist.vim</title><link>https://toasterlovin.com/extending-rails-vim-navigation-commands-with-projectionist-vim/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8260</guid><pubDate>Wed, 17 Jan 2018 05:35:26 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><category>Vim</category><description>One of my favorite Vim plugins is rails.vim by Tim Pope. And the reason it’s one of my favorite Vim plugins is all of the navigation commands that it gives you for working with Ruby on Rails projects. So, rather than having to do :e app/models/product.rb to navigate to a model in your Rails app, you can just do :Emodel product instead. It also has commands for navigating to controllers, views, layouts, migrations, mailers, etc. And if you want to open something in a vertical split, you just use the V version of the navigation commands (:Vmodel product).</description><content:encoded><![CDATA[<p>One of my favorite <a href="http://www.vim.org">Vim</a> plugins is <a href="https://github.com/tpope/vim-rails">rails.vim</a> by <a href="https://github.com/tpope">Tim Pope</a>. And the reason it&rsquo;s one of my favorite Vim plugins is all of the navigation commands that it gives you for working with <a href="http://rubyonrails.org">Ruby on Rails</a> projects. So, rather than having to do <code>:e app/models/product.rb</code> to navigate to a model in your Rails app, you can just do <code>:Emodel product</code> instead. It also has commands for navigating to controllers, views, layouts, migrations, mailers, etc. And if you want to open something in a vertical split, you just use the <code>V</code> version of the navigation commands (<code>:Vmodel product</code>).</p>
<p>It&rsquo;s pretty great.</p>
<p>But something that happens as you get more experienced with Rails is you start adding folders to your <code>app/</code> folder. So, in addition to the standard <code>models</code>, <code>views</code>, <code>controllers</code>, and <code>mailers</code> directories, you might add a <code>presenters</code>, <code>workers</code>, or <code>serializers</code> directory. This is actually a big step toward leveling up as a Rails developer; it&rsquo;s a sign that you&rsquo;re comfortable decomposing your app into more than just models, views, and controllers.</p>
<p>One of the downsides of doing this, though, is that it feels painful to work with these new types of classes, because <code>rails.vim</code> doesn&rsquo;t have handy navigation commands for them. But that&rsquo;s okay, because it&rsquo;s actually really easy to add those navigation commands. In addition to <code>rails.vim</code>, Tim Pope also makes <a href="https://github.com/tpope/vim-projectionist">projectionist.vim</a>, which allows you to create custom Vim commands via a simple configuration file. And it&rsquo;s not limited to Ruby or Rails; it can be used for any kind of project.</p>
<p>To get started, you put a <code>.projections.json</code> file in your project root directory. Here&rsquo;s what that file looks like on one of my projects, where it&rsquo;s adding navigation commands for workers and presenters:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;app/workers/*_worker.rb&#34;</span><span class="p">:</span> <span class="p">{</span><span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;worker&#34;</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;app/presenters/*_presenter.rb&#34;</span><span class="p">:</span> <span class="p">{</span><span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;presenter&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You can see that it&rsquo;s pretty simple. You specify a pattern that matches certain types of files in your project, then you specify some options for files which match that pattern. In this case, the only option I&rsquo;m specifying is <code>&quot;type&quot;</code>, which is what creates the navigation commands. So, that first line creates the <code>:Eworker</code> and <code>:Vworker</code> commands (and some others, but those are the only ones I actually use) and then specifies that they will open files in the <code>app/workers</code> directory which have filenames ending in <code>_worker.rb</code>.</p>
<p>And that&rsquo;s it!</p>
<p>Well, I&rsquo;ll mention one more thing: I specified the <code>&quot;type&quot;</code> option in the configuration file above, but there are other options that you can specify as well, such as a <code>&quot;template&quot;</code> for creating new files or an <code>&quot;alternate&quot;</code> for navigating to related files. I&rsquo;ll leave you to peruse <a href="https://github.com/tpope/vim-projectionist">the documentation</a> if you want to learn more about those, though.</p>
]]></content:encoded></item><item><title>Using the PTY Class to Test Interactive CLI Apps in Ruby</title><link>https://toasterlovin.com/using-the-pty-class-to-test-interactive-cli-apps-in-ruby/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825f</guid><pubDate>Wed, 28 Jun 2017 21:58:05 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby</category><category>CLI</category><category>Testing</category><description>I recently created a command line Reverse Polish notation calculator as a programming exercise. It’s interactive, so a user runs the executable and then they are presented with a REPL that they can use to evaluate Reverse Polish notation expressions. When the user is done, they type q or CTRL-D to exit. It might look something like this:
$ rpn_party &gt; 3 2 + 5.0 &gt; 6 - -1.0 &gt; q $ Naturally, I wanted to write tests that verified that it behaved as expected. But I’m a big believer in integration tests, so I wanted my tests to actually interact with the calculator as if they were a user. That is, I wanted them to run the executable, then send commands to the REPL over stdin, and, finally, verify the results by reading them from stdout. Essentially, use the app exactly as a human would.</description><content:encoded><![CDATA[<p>I recently created a <a href="https://github.com/toasterlovin/rpn_party">command line Reverse Polish notation calculator</a> as a programming exercise. It&rsquo;s interactive, so a user runs the executable and then they are presented with a <a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">REPL</a> that they can use to evaluate <a href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse Polish notation</a> expressions. When the user is done, they type <code>q</code> or <code>CTRL-D</code> to exit. It might look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> rpn_party
</span></span><span class="line"><span class="cl"><span class="gp">&gt;</span> <span class="m">3</span> <span class="m">2</span> +
</span></span><span class="line"><span class="cl"><span class="go">5.0
</span></span></span><span class="line"><span class="cl"><span class="gp">&gt;</span> <span class="m">6</span> -
</span></span><span class="line"><span class="cl"><span class="go">-1.0
</span></span></span><span class="line"><span class="cl"><span class="gp">&gt;</span> q
</span></span><span class="line"><span class="cl"><span class="gp">$</span>
</span></span></code></pre></div><p>Naturally, I wanted to write tests that verified that it behaved as expected. But I&rsquo;m a big believer in integration tests, so I wanted my tests to actually interact with the calculator as if they were a user. That is, I wanted them to run the executable, then send commands to the REPL over <code>stdin</code>, and, finally, verify the results by reading them from <code>stdout</code>. Essentially, use the app exactly as a human would.</p>
<h2 id="thesolution">The Solution</h2>
<p>The solution can be found in a <a href="https://ruby-doc.org/stdlib-2.4.1/libdoc/pty/rdoc/PTY.html">class from Ruby&rsquo;s standard library  called <code>PTY</code></a>. <code>PTY</code> allows you to spawn an external process and then interact with that process by using <code>puts</code> to write to it&rsquo;s <code>stdin</code> and <code>gets</code> to read from it&rsquo;s <code>stdout</code>. You can read the documentation for PTY, but it probably won&rsquo;t make much sense unless you have a pretty good understanding of how <a href="https://en.wikipedia.org/wiki/Pseudoterminal">pseudoterminals</a> work (PTY is an unixism for pseudoterminal). It&rsquo;s okay if you don&rsquo;t, though, because using <code>PTY</code> to interact with command line apps is pretty simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">PTY</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;path/to/executable&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">pid</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="n">stdin</span><span class="o">.</span><span class="n">puts</span> <span class="s1">&#39;some command&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="n">stdout</span><span class="o">.</span><span class="n">gets</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">response</span> <span class="o">=</span> <span class="n">stdout</span><span class="o">.</span><span class="n">gets</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert_equal</span> <span class="s1">&#39;expected response&#39;</span><span class="p">,</span> <span class="n">response</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Here&rsquo;s what&rsquo;s going on in this chunk of code:</p>
<ol>
<li>We&rsquo;re calling the <code>spawn</code> class method on the <code>PTY</code> class.</li>
<li>We&rsquo;re passing the path to our executable as the first argument</li>
<li>Our second argument is a block which is where we specify how we want to interact with the process.</li>
<li>The block takes three arguments: two IO objects representing the <code>stdout</code> and <code>stdin</code> of the spawned process and then the <a href="https://en.wikipedia.org/wiki/Process_identifier">pid</a> of the spawned process, which will be useful later on.</li>
<li>In the first line of the block, we are interacting with the spawned process by writing text to it&rsquo;s <code>stdin</code>.</li>
<li>Then we are consuming one line of text from the process&rsquo;s <code>stdout</code>. We have to do this because our input from the previous line is echoed to the process&rsquo;s <code>stdout</code>, so we need to consume that before we can get to the actual response. I&rsquo;ll go into more detail on this down below.</li>
<li>Then, in the next two lines, we are getting the process&rsquo;s response and asserting that it is the value we are expecting.</li>
</ol>
<p>That&rsquo;s basically it, other than a few tips and gotchas, which I will dive into below.</p>
<h4 id="echoedinputonstdout">Echoed Input on <code>stdout</code></h4>
<p>The first gotcha to be aware of is that, for many command line apps, everything that is typed on <code>stdin</code> is echoed back to <code>stdout</code>. If you think about it, this actually makes a lot of sense. If it wasn&rsquo;t, the user wouldn&rsquo;t be able to see what they were typing. There are some cases where input doesn&rsquo;t get echoed to <code>stdout</code>, though, like when a user is typing a password.</p>
<p>This isn&rsquo;t a big deal, more just something to keep in mind. I dealt with this in my tests by creating a method that would send a command to my process and then immediately consume a line of output from <code>stdout</code>. This made my tests easier to comprehend. Here&rsquo;s what that looked like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">send_command</span><span class="p">(</span><span class="n">pty</span><span class="p">,</span> <span class="n">command</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">pty</span><span class="o">[</span><span class="mi">1</span><span class="o">].</span><span class="n">puts</span> <span class="n">command</span>
</span></span><span class="line"><span class="cl">  <span class="n">pty</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="n">gets</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>This is a little tricky because for this method to do what it needs to do, it needs access to both <code>stdin</code> (to send the command) and <code>stdout</code> (to consume the line containing the command). So at the beginning of each of my blocks, I put all three of the block arguments into an array which would be less cumbersome to pass around:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">PTY</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;path/to/executable&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">pid</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="n">pty</span> <span class="o">=</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">pid</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And that <code>pty</code> variable is what gets passed as the first argument to the <code>send_command</code> method.</p>
<h4 id="processtermination">Process Termination</h4>
<p>If you&rsquo;ve come this far in pursuit of integration testing your command line app, you want to go all the way. And that means you want to verify that your program exits correctly. You <em>could</em> have your app print an exit message and then verify in your test that this message gets printed to <code>stdout</code> when you input the command to exit. The problem is that you don&rsquo;t actually <em>know</em> that your CLI app exited. It could have printed the exit message and kept running.</p>
<p>Better to actually verify that your process is no longer running. This is where the <code>pid</code> argument to the block from up above comes into the picture:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">PTY</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;bin/rpn_party&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">output</span><span class="p">,</span> <span class="n">input</span><span class="p">,</span> <span class="n">pid</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="n">stdin</span><span class="o">.</span><span class="n">puts</span> <span class="s1">&#39;exit&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="no">PTY</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">pid</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Here we&rsquo;re sending the <code>exit</code> command to our process, then using the <code>check</code> class method on <code>PTY</code> to assert that the process is no longer running. The semantics of <code>check</code> are the opposite of what I, personally, would expect, but I&rsquo;m not a systems programmer, so I will assume that I&rsquo;m wrong on this one. Anyway, <code>check</code> returns <code>nil</code> if the process <em>is</em> running and a truthy value if the process <em>is not</em> running, so you want to assert that <code>PTY.check(pid)</code> returns true to verify that your process has exited.</p>
<h4 id="resultsracecondition">Results Race Condition</h4>
<p>Another gotcha you need to be aware of is that, when you spawn another process with <code>PTY</code> like this, you now have two separate processes, which means that you can run into timing issues when making assertions about the output from your spawned process. So this assertion can fail sometimes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">PTY</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;path/to/executable&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">pid</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># send a command and clear it from stdout</span>
</span></span><span class="line"><span class="cl">  <span class="n">response</span> <span class="o">=</span> <span class="n">stdout</span><span class="o">.</span><span class="n">gets</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert_equal</span> <span class="s1">&#39;expected response&#39;</span><span class="p">,</span> <span class="n">response</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>What&rsquo;s going on is that your test process has sent a command to your spawned process, then instantaneously tries to read the response from <code>stdout</code>. But if your spawned process has a small delay in writing to it&rsquo;s <code>stdout</code> (for whatever reason; the delay only needs to be miniscule), then the response your test gets will be blank and the assertion will fail. You can get around this by having your test process <code>sleep</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">PTY</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;path/to/executable&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">pid</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># send a command and clear it from stdout</span>
</span></span><span class="line"><span class="cl">  <span class="nb">sleep</span> <span class="mi">0</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">  <span class="n">response</span> <span class="o">=</span> <span class="n">stdout</span><span class="o">.</span><span class="n">gets</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert_equal</span> <span class="s1">&#39;expected response&#39;</span><span class="p">,</span> <span class="n">response</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Having your test process <code>sleep</code> before getting every response is not really optimal, though. With a large enough test suite, tenths of a second start to add up. What you really want is a method that tries getting the response for a certain amount of time before giving up. Something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_response</span><span class="p">(</span><span class="n">stdout</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">start</span> <span class="o">=</span> <span class="no">Time</span><span class="o">.</span><span class="n">now</span>
</span></span><span class="line"><span class="cl">  <span class="n">try_for</span> <span class="o">=</span> <span class="mi">2</span>
</span></span><span class="line"><span class="cl">  <span class="n">response</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kp">loop</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">stdout</span><span class="o">.</span><span class="n">gets</span><span class="o">.</span><span class="n">chomp</span>
</span></span><span class="line"><span class="cl">    <span class="k">break</span> <span class="k">if</span> <span class="n">response</span> <span class="o">||</span> <span class="no">Time</span><span class="o">.</span><span class="n">now</span> <span class="o">&gt;</span> <span class="n">start</span> <span class="o">+</span> <span class="n">try_for</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">sleep</span> <span class="mi">0</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">response</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>What&rsquo;s going on there is that, in each iteration of the loop, we try to get a response. If we get a response, or if we have exceeded the total amount of time we are going to try for, then we break out of the loop. Otherwise, we sleep for 0.1 seconds, after which point the loop runs again.</p>
<h4 id="promptracecondition">Prompt Race Condition</h4>
<p>Another race condition issue can pop up if your CLI app shows the user a prompt, like this (the <code>&gt;</code> is the prompt):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">$</span> rpn_party
</span></span><span class="line"><span class="cl"><span class="gp">&gt;</span> commmand
</span></span><span class="line"><span class="cl"><span class="go">result
</span></span></span><span class="line"><span class="cl"><span class="gp">&gt;</span>
</span></span></code></pre></div><p>What can happen is that, because the test is running at computer speed, rather than human speed, the test can send the next command in the sequence before the CLI app&rsquo;s <code>stdout</code> has printed the <code>&gt;</code> after the last command. Say you have a test like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">PTY</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">&#39;path/to/executable&#39;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdout</span><span class="p">,</span> <span class="n">stdin</span><span class="p">,</span> <span class="n">pid</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="n">stdin</span><span class="o">.</span><span class="n">puts</span> <span class="s1">&#39;command1&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="n">response1</span> <span class="o">=</span> <span class="n">stdout</span><span class="o">.</span><span class="n">gets</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">stdin</span><span class="o">.</span><span class="n">puts</span> <span class="s1">&#39;command2&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="n">response2</span> <span class="o">=</span> <span class="n">stdout</span><span class="o">.</span><span class="n">gets</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert_equal</span> <span class="s1">&#39;response2&#39;</span><span class="p">,</span> <span class="n">response</span>     <span class="c1"># fails sometimes</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>This assertion will sometimes fails in a not so obvious way (because reasoning about async is hard). When it does fail, you&rsquo;ll get a message like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Expected &#34;response2&#34;
</span></span><span class="line"><span class="cl">Actual   &#34;&gt; response2&#34;
</span></span></code></pre></div><p>The reason it fails like this is because what you think is happening is this sequence of events:</p>
<ol>
<li>Command 1 is sent</li>
<li>Response 1 is received</li>
<li>Prompt 1 is printed to screen</li>
<li>Command 2 is sent</li>
<li>Response 2 is received</li>
<li>Prompt 2 is printed to screen</li>
</ol>
<p>But what actually happens sometimes is this:</p>
<ol>
<li>Command 1 is sent</li>
<li>Response 1 is received</li>
<li>Command 2 is sent before the prompt has been printed</li>
<li>Prompt + Response 2 are then received together</li>
</ol>
<p>That&rsquo;s how a response like <code>&gt; response</code> happens instead of <code>response</code>.</p>
<p>To resolve this, we need to wait until the prompt is printed before we send a request. I think it&rsquo;s best to wrap this up in a method, like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">wait_for_prompt</span><span class="p">(</span><span class="n">stdout</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">start</span> <span class="o">=</span> <span class="no">Time</span><span class="o">.</span><span class="n">now</span>
</span></span><span class="line"><span class="cl">  <span class="n">try_for</span> <span class="o">=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kp">loop</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="n">prompt</span> <span class="o">=</span> <span class="n">stdout</span><span class="o">.</span><span class="n">getc</span>
</span></span><span class="line"><span class="cl">    <span class="k">break</span> <span class="k">if</span> <span class="n">prompt</span> <span class="o">==</span> <span class="s1">&#39;&gt;&#39;</span> <span class="o">||</span> <span class="no">Time</span><span class="o">.</span><span class="n">now</span> <span class="o">&gt;</span> <span class="n">start</span> <span class="o">+</span> <span class="n">try_for</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">sleep</span> <span class="mi">0</span><span class="o">.</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><hr>
<p>And there you go. Now you can integration test your CLI apps.</p>
]]></content:encoded></item><item><title>Webcal Links in Rails with the icalendar Gem</title><link>https://toasterlovin.com/rails-webcal-links-with-icalendar-gem/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825e</guid><pubDate>Sun, 11 Jun 2017 18:35:36 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>The icalendar gem is a useful way to generate iCalendar files for use with various calendar applications. One thing I couldn’t find good documentation on, though, is how to use it to create a Webcal link in a Ruby on Rails app, so I figured I’d would go ahead and document that myself.
Before I get started, I’ll just mention that all of the code examples in this post are from the demo app, which you can find on Github. Also, the demo app is live, so you can see everything in action.</description><content:encoded><![CDATA[<p>The <a href="https://github.com/icalendar/icalendar">icalendar gem</a> is a useful way to generate <a href="https://en.wikipedia.org/wiki/ICalendar">iCalendar files</a> for use with various calendar applications. One thing I couldn&rsquo;t find good documentation on, though, is how to use it to create a <a href="https://en.wikipedia.org/wiki/Webcal">Webcal</a> link in a Ruby on Rails app, so I figured I&rsquo;d would go ahead and document that myself.</p>
<p><em>Before I get started, I&rsquo;ll just mention that all of the code examples in this post are from the demo app, <a href="https://github.com/toasterlovin/rails-icalendar-webcal">which you can find on Github</a>. Also, the demo app is live, so you can <a href="https://rails-icalendar-webcal.toasterlovin.com/calendar">see everything in action</a>.</em></p>
<h2 id="webcal">Webcal</h2>
<p><a href="https://en.wikipedia.org/wiki/Webcal">Webcal</a> is what allows a user to click on a link in their browser to subscribe to a calendar in their calendar app.</p>
<p>So, you click on a link in your browser, then a dialog window pops up in your calendar app to subscribe to the calendar:</p>
<!-- Image lost before the move off Ghost: ![](/content/images/2017/06/Screen-Shot-2017-06-11-at-09.54.00.png) -->
<p>Then you click <em>Subscribe</em> and, voilà, now that power lunch you have scheduled is in your calendar:</p>
<!-- Image lost before the move off Ghost: ![](/content/images/2017/06/Screen-Shot-2017-06-11-at-09.55.11.png) -->
<p>In the future, your calendar app will periodically poll the calendar&rsquo;s URL to check for updates.</p>
<h2 id="controller">Controller</h2>
<p>Here&rsquo;s what your controller should look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CalendarsController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">show</span>
</span></span><span class="line"><span class="cl">    <span class="n">respond_to</span> <span class="k">do</span> <span class="o">|</span><span class="nb">format</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">      <span class="nb">format</span><span class="o">.</span><span class="n">ics</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">        <span class="n">cal</span> <span class="o">=</span> <span class="no">Icalendar</span><span class="o">::</span><span class="no">Calendar</span><span class="o">.</span><span class="n">new</span>
</span></span><span class="line"><span class="cl">        <span class="n">cal</span><span class="o">.</span><span class="n">x_wr_calname</span> <span class="o">=</span> <span class="s1">&#39;Awesome Rails Calendar&#39;</span>
</span></span><span class="line"><span class="cl">        <span class="n">cal</span><span class="o">.</span><span class="n">event</span> <span class="k">do</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">          <span class="n">e</span><span class="o">.</span><span class="n">dtstart</span>     <span class="o">=</span> <span class="no">DateTime</span><span class="o">.</span><span class="n">now</span> <span class="o">+</span> <span class="mi">2</span><span class="o">.</span><span class="n">hours</span>
</span></span><span class="line"><span class="cl">          <span class="n">e</span><span class="o">.</span><span class="n">dtend</span>       <span class="o">=</span> <span class="no">DateTime</span><span class="o">.</span><span class="n">now</span> <span class="o">+</span> <span class="mi">3</span><span class="o">.</span><span class="n">hours</span>
</span></span><span class="line"><span class="cl">          <span class="n">e</span><span class="o">.</span><span class="n">summary</span>     <span class="o">=</span> <span class="s1">&#39;Power Lunch&#39;</span>
</span></span><span class="line"><span class="cl">          <span class="n">e</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="s1">&#39;Get together and do big things&#39;</span>
</span></span><span class="line"><span class="cl">        <span class="k">end</span>
</span></span><span class="line"><span class="cl">        <span class="n">cal</span><span class="o">.</span><span class="n">publish</span>
</span></span><span class="line"><span class="cl">        <span class="n">render</span> <span class="ss">plain</span><span class="p">:</span> <span class="n">cal</span><span class="o">.</span><span class="n">to_ical</span>
</span></span><span class="line"><span class="cl">      <span class="k">end</span>
</span></span><span class="line"><span class="cl">    <span class="k">end</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p><em><a href="https://github.com/toasterlovin/rails-icalendar-webcal/blob/master/app/controllers/calendars_controller.rb">View code on Github</a></em></p>
<p>I&rsquo;ll highlight the important parts:</p>
<ol>
<li>
<p>Your controller needs to be unauthenticated, or else the user&rsquo;s calendar app won&rsquo;t be able to access the calendar. So, if your <code>ApplicationController</code> is authenticated, your <code>CalendarsController</code> will probably need to inherit directly from <code>ActionController::Base</code> to avoid authentication.</p>
</li>
<li>
<p>If your calendar contains sensitive data that should only be available to a specific user, you will need to use a strategy similar to password reset links so that you aren&rsquo;t leaking sensitive data. So, your calendar should be available at a path like <code>/calendar/u/:some_long_random_string</code>, instead of <code>/calendar/u/:user_id</code>.</p>
</li>
<li>
<p>You <code>respond_to</code> the <code>ics</code> format.</p>
</li>
<li>
<p>You set <code>cal.x_wr_calname</code> to specify the default calendar name that will be displayed in the user&rsquo;s calendar app.</p>
</li>
<li>
<p>You use <code>render plain: cal.to_ical</code> to actually render the calendar. In older versions of Rails you would specify <code>text</code> instead of <code>plain</code>.</p>
</li>
</ol>
<p>You can learn about everything else going on in this controller by reading the <code>icalendar</code> gem documentation. It&rsquo;s all standard stuff.</p>
<h1 id="link">Link</h1>
<p>Here&rsquo;s what your subscription link should look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s1">&#39;Subscribe&#39;</span><span class="p">,</span> <span class="n">calendar_url</span><span class="p">(</span><span class="ss">protocol</span><span class="p">:</span> <span class="ss">:webcal</span><span class="p">,</span> <span class="nb">format</span><span class="p">:</span> <span class="ss">:ics</span><span class="p">)</span> <span class="cp">%&gt;</span>
</span></span></code></pre></div><p><em><a href="https://github.com/toasterlovin/rails-icalendar-webcal/blob/master/app/views/calendars/show.html.erb">View code on Github</a></em></p>
<p>I&rsquo;ll highlight the important parts:</p>
<ol>
<li>
<p>You have to use a full URL, not just a path. The reason for this is the same as for Rails mailers: unlike the browser, the user&rsquo;s calendar app won&rsquo;t know the domain. So, in this example, we&rsquo;re using <code>calendar_url</code> instead of <code>calendar_path</code>.</p>
</li>
<li>
<p>You specify the <code>webcal</code> protocol. This will create a link that starts with <code>webcal://</code>, instead of <code>http://</code>, which is what tells the browser to hand the link off to the user&rsquo;s calendar app.</p>
</li>
<li>
<p>You specify the <code>ics</code> format. This will create a link that ends in <code>/calendar.ics</code>, instead of just <code>/calendar</code>, which is what tells Rails to handle the request with the <code>format.ics</code> block in the controller.</p>
</li>
</ol>
<hr>
<p>That&rsquo;s it, you&rsquo;re done!</p>
<p>Just a reminder that you can <a href="https://github.com/toasterlovin/rails-icalendar-webcal">find the demo app on Github</a>, or <a href="https://rails-icalendar-webcal.toasterlovin.com/calendar">see it in action on Heroku</a>.</p>
]]></content:encoded></item><item><title>Greatest-Per-Group Query in Rails Using a View Backed Model</title><link>https://toasterlovin.com/greatest-per-group-rails-view-backed-model/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825d</guid><pubDate>Sun, 03 Apr 2016 16:48:50 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><category>PostgreSQL</category><description>In Rails, each model is backed by a table in the underlying database. A view backed model is a model that is backed by a database view, instead of by a normal table.</description><content:encoded><![CDATA[<p>In Part 3 of this series, we covered <a href="https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/">how to implement a Greatest Per Group query in Rails using a scoped <code>has_one</code> relation</a> – my preferred method – but we left off with the caveat that there are some cases where that approach will not work. Here we&rsquo;ll cover an approach that requires a bit more setup, but <em>always</em> works: using a View Backed Model.</p>
<h2 id="aviewbackedmodel">A View Backed Model</h2>
<p>Let&rsquo;s start by unpacking the term View Backed Model. In Rails, each model is backed by a table in the underlying database. So, our <code>Author</code> model is backed by the <code>authors</code> table and our <code>Post</code> model is backed by the <code>posts</code> table. A view backed model is a model that is backed by a database view, instead of by a normal table.</p>
<p>Great, so what exactly is a database view? Well, you could go <a href="http://www.postgresql.org/docs/9.0/static/tutorial-views.html">read the Postgres documentation on views</a>, but the short version is that views allow you to encapsulate a query behind a table interface. Basically, a database view lets you assign a name to a query and then interact with the result that query generates as if it were any other table in your database (filter it, join to it, etc.). Don&rsquo;t worry if that seems a little fuzzy to you, because we&rsquo;re about to make it more concrete by applying it to our Greatest Per Group problem.</p>
<p>Let&rsquo;s start by looking at the query we came up with back in <a href="https://toasterlovin.com/greatest-per-group-postgresql-distinct-on/">Part 1</a> of this series:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>Working from the inside out, what we&rsquo;re doing in this query is:</p>
<ol>
<li>Using a subquery to creating a temporary table.</li>
<li>Naming the temporary table <code>newest_posts</code>.</li>
<li>And then joining it to the <code>authors</code> table.</li>
</ol>
<p>A database view allows us to encapsulate the subquery that makes up our temporary <code>newest_posts</code> table and make it permanently available throughout our database. Here&rsquo;s how we create that database view:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">VIEW</span><span class="w"> </span><span class="n">newest_posts</span><span class="w"> </span><span class="k">AS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span></code></pre></div><p>As you can see, it looks remarkably similar to our subquery from above, just rearranged a little bit. Now we have a view called <code>newest_posts</code> that we can treat like a table. And every time we refer to it, PostgreSQL will run this query and treat the results as a table.</p>
<p>So if we want the newest post for each author, we can do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">newest_posts</span><span class="w">
</span></span></span></code></pre></div><p>And to get the newest post for a specific author, we can do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">newest_posts</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span></code></pre></div><p>Or, if we want to accomplish our original query from above, we can do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="n">newest_posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>As you can see, our view is a drop in replacement for the original subquery. Which makes sense, because PostgreSQL is literally running the exact same query in the spot where it says <code>newest_posts</code>.</p>
<p>Database views are a powerful way to encapsulate commonly used or complicated queries. And they can be an incredibly useful tool in a Rails app, because it&rsquo;s fairly easy to hit the edge of how well ActiveRecord maps to what you&rsquo;re trying to accomplish with a query. But ActiveRecord understands tables pretty well and, since a database view acts like a table, they are a powerful way to force ActiveRecord to just do what you need it to do.</p>
<p>Great, so how do we use database views in a Rails app?</p>
<h2 id="databaseviewsinrails">Database Views in Rails</h2>
<p>Since a database view is something that exists in the database, we&rsquo;ll create ours in a migration:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CreateNewestPostsView</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Migration</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">up</span>
</span></span><span class="line"><span class="cl">    <span class="n">execute</span> <span class="s">&lt;&lt;-sql
</span></span></span><span class="line"><span class="cl">      <span class="no">CREATE</span> <span class="no">VIEW</span> <span class="n">newest_posts</span> <span class="no">AS</span>
</span></span><span class="line"><span class="cl">        <span class="no">SELECT</span> <span class="no">DISTINCT</span> <span class="no">ON</span> <span class="p">(</span><span class="n">author_id</span><span class="p">)</span> <span class="o">*</span>
</span></span><span class="line"><span class="cl">        <span class="no">FROM</span> <span class="n">posts</span>
</span></span><span class="line"><span class="cl">        <span class="no">ORDER</span> <span class="no">BY</span> <span class="n">author_id</span><span class="p">,</span> <span class="n">created_at</span> <span class="no">DESC</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">down</span>
</span></span><span class="line"><span class="cl">    <span class="n">execute</span> <span class="s">&lt;&lt;-sql
</span></span></span><span class="line"><span class="cl">      <span class="no">DROP</span> <span class="no">VIEW</span> <span class="n">newest_posts</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And since a database view behaves like a table, all we need to do is create a model that follows the Rails naming conventions and things will just work (well, mostly, but we&rsquo;ll get to that in a bit):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">NewestPost</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Of course, Rails has no idea that the <code>newest_posts</code> table that it expects to back the <code>NewestPost</code> model is not actually a table at all, but is instead a dynamic query result comprised of rows from the <code>posts</code> table. PostgreSQL takes care of all of that behind the scenes. All Rails knows is that there is a table-like thing called <code>newest_posts</code> which returns one row per <code>Author</code> and has an <code>author_id</code> column that it can use to join to the <code>authors</code> table. So, if we do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">NewestPost</span><span class="o">.</span><span class="n">all</span>
</span></span></code></pre></div><p>Rails will generate SQL like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p>But PostgreSQL will actually do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>This allows us to use use our View Backed Model just like any other model in our app. For instance, we can set up associations:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">NewestPost</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="n">belongs_to</span> <span class="ss">:author</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Then we can create the corresponding <code>has_one</code> association in our <code>Author</code> model:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Author</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_many</span> <span class="ss">:posts</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_one</span> <span class="ss">:newest_post</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And now we have a normal ActiveRecord association that we can use for eager loading:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@authors</span> <span class="o">=</span> <span class="no">Author</span><span class="o">.</span><span class="n">includes</span><span class="p">(</span><span class="ss">:newest_post</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="vi">@authors</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">author</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">&#39;s latest post: </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">newest_post</span><span class="o">.</span><span class="n">title</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And Rails only generates two queries: one to load the authors and another to load the newest posts.</p>
<h2 id="afewthingstobeawareof">A few things to be aware of</h2>
<p>If you&rsquo;ll recall, we created our database view in a Rails migration, which is all fine and dandy. Except that we had to execute raw SQL instead of using one of <code>ActiveRecord::Migration</code>&rsquo;s handy methods (like <code>create_table</code> or <code>add_index</code>). That&rsquo;s because Rails doesn&rsquo;t really know what views are. And a side effect of this is that, if you take a look at your <code>schema.rb</code> after creating a view, you won&rsquo;t see your view in there.</p>
<p>So if somebody tries to get their development environment up and running with <code>rake db:create</code>, they won&rsquo;t have any database views. Which is probably not what you want if you&rsquo;re trying to use views in your Rails app.</p>
<p>That&rsquo;s okay, though, because there are two ways around this.</p>
<p>The first option is to configure your app to use SQL instead of Ruby for schema dumps. By default, Rails is configured to do Ruby schema dumps. That&rsquo;s why <code>schema.rb</code> ends in <code>.rb</code> and consists of a series of <code>ActiveRecord::Migration</code> methods designed to recreate your schema from scratch.</p>
<p>But you can configure Rails to do SQL schema dumps instead. In which case you&rsquo;ll get a <code>structure.sql</code> file filled with a bunch of SQL statements that look like the output of <a href="http://www.postgresql.org/docs/9.5/static/app-pgdump.html"><code>pg_dump</code></a>. Critically, this type of schema dump will include statements to recreate any database views (and <a href="http://www.postgresql.org/docs/9.5/static/sql-createextension.html">extensions</a>) you&rsquo;ve created.</p>
<p>You can read <a href="http://edgeguides.rubyonrails.org/active_record_migrations.html#schema-dumping-and-you">the documentation on how to do this</a>, but it&rsquo;s pretty simple. In <code>config/application.rb</code>, you change this line:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">config</span><span class="o">.</span><span class="n">active_record</span><span class="o">.</span><span class="n">schema_format</span> <span class="o">=</span> <span class="ss">:ruby</span>
</span></span></code></pre></div><p>to:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">config</span><span class="o">.</span><span class="n">active_record</span><span class="o">.</span><span class="n">schema_format</span> <span class="o">=</span> <span class="ss">:sql</span>
</span></span></code></pre></div><p>You&rsquo;ll probably want to delete your <code>schema.rb</code> file, too.</p>
<p>And that&rsquo;s all there is to it.</p>
<p>There is another, more comprehensive approach to solving the schema dump problem, which is to use the <a href="https://github.com/thoughtbot/scenic">Scenic gem</a>. Scenic actually adds <code>ActiveRecord::Migration</code> methods which allow you to avoid using SQL formatted schema dumps. Plus it has a bunch of other convenient tools for working with database views in your Rails app. I haven&rsquo;t used it, personally, but I plan to.</p>
<p>The other major consideration with View Backed Models is a little bit more subtle. And it is that instances of a View Backed Model are not instances of the model that is backed by the table they&rsquo;re derived from. That&rsquo;s a bit much to digest, so let me explain it with some code.</p>
<p>Let&rsquo;s grab a <code>NewestPost</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@newest_post</span> <span class="o">=</span> <span class="no">NewestPost</span><span class="o">.</span><span class="n">first</span>
</span></span></code></pre></div><p>Because the <code>newest_posts</code> database view selects all of the columns from the <code>posts</code> table that it is derived from (that little <code>*</code> at the end of the second line of our view):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">VIEW</span><span class="w"> </span><span class="n">newest_posts</span><span class="w"> </span><span class="k">AS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span></code></pre></div><p>The data from those columns is available on instances of <code>NewestPost</code>. So we can do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@newest_post</span><span class="o">.</span><span class="n">title</span>
</span></span><span class="line"><span class="cl"><span class="vi">@newest_post</span><span class="o">.</span><span class="n">body</span>
</span></span><span class="line"><span class="cl"><span class="vi">@newest_post</span><span class="o">.</span><span class="n">created_at</span>
</span></span></code></pre></div><p>And they all work as we would expect them to. But any methods or associations defined on <code>Post</code> <em>will not work</em>. So if <code>Post</code> <code>has_many :comments</code> and you try to do something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@newest_post</span><span class="o">.</span><span class="n">comments</span>
</span></span></code></pre></div><p>It will not work.</p>
<p>It&rsquo;s easy to start thinking of instances of <code>NewestPost</code> as instances of <code>Post</code>, since that&rsquo;s what they are in a logical sense, but to the dumb machine, <code>NewestPost</code> and <code>Post</code> are just two completely unrelated model classes.</p>
<p>So, around now you might be thinking to yourself, &ldquo;Aha, but this is easy to solve. I&rsquo;ll just make <code>NewestPost</code> inherit from <code>Post</code> and then it&rsquo;ll have access to all of the methods and associations defined on <code>Post</code>.&rdquo;</p>
<p>In a sane world, that would be a perfectly reasonable way to proceed. But, unfortunately, we exist in a world where Rails has <a href="http://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html">Single Table Inheritance (STI)</a>. I&rsquo;ll spare you a deep dive on STI, but the gist of it is that, for descendants of <code>ActiveRecord::Base</code>, Rails stomps all over your ability to have one class inherit from another in a way that would be useful to us here.</p>
<p>But, as STI taketh away, so STI giveth.</p>
<p>Because STI is such a convoluted mess, it necessitates the existence of the very tool that will allow us to escape the conundrum that it has created for us. And that tool is the <code>becomes</code> method. You can read <a href="http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-becomes">the API docs</a>, but <code>becomes</code> uses the attributes of the object you call it on to create an instance of the class you pass to it. Yet another thing that is easier understood with code. Here it is in action:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@newest_post</span><span class="o">.</span><span class="n">becomes</span><span class="p">(</span><span class="no">Post</span><span class="p">)</span>
</span></span></code></pre></div><p>Which is more or less the equivalent of doing:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">Post</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="vi">@newest_post</span><span class="o">.</span><span class="n">attributes</span><span class="p">)</span>
</span></span></code></pre></div><p>And since we now have an instance of <code>Post</code>, we can use all of the methods and associations defined on <code>Post</code> without having to redefine them. Which allows us to stuff like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@newest_post</span><span class="o">.</span><span class="n">becomes</span><span class="p">(</span><span class="no">Post</span><span class="p">)</span><span class="o">.</span><span class="n">comments</span>
</span></span></code></pre></div><p>So there you go. It&rsquo;s a bit of a kludge and I wish it were more elegant, but it works. And, in my opinion, the power and utility of View Backed Models are worth a modest sacrifice in elegance.</p>
<hr>
<p><em>And that&rsquo;s it. Now you know way more than you ever wanted to about this strange little corner of the Rails world.</em></p>
]]></content:encoded></item><item><title>Greatest-Per-Group Query in Rails Using a Scoped has_one Assocation</title><link>https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825c</guid><pubDate>Wed, 10 Feb 2016 07:29:44 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><category>PostgreSQL</category><description>We're creating a table that has a single row per author and then joining it to the authors table, which might sound an awful lot like a has_one association.</description><content:encoded><![CDATA[<p>In Part 2 of this series, we covered <a href="https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/">how to use a Greatest Per Group query in Rails using custom query methods</a>, as well as some of the limitations of that approach. Here we&rsquo;ll cover an approach that makes up for those limitations <em>and</em> brings some extra benefits to the table.</p>
<h2 id="ascopedhasoneassociation">A scoped <code>has_one</code> association</h2>
<p>We&rsquo;ll need our Greatest Per Group query from Part 1 fresh in our heads for this next part, so here it is again:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>There are three things happening in this query:</p>
<ol>
<li>We&rsquo;re creating a temporary <code>newest_posts</code> table that returns a single post – the newest one – for each author.</li>
<li>Then, we&rsquo;re joining this temporary table to our <code>authors</code> table on <code>authors.id = newest_posts.author_id</code>.</li>
<li>Finally, we&rsquo;re selecting some data from that <code>newest_posts</code> table to return along with our author data.</li>
</ol>
<p>Let&rsquo;s forget about the third item – selecting the data – for now and instead focus on the first two.</p>
<p>We&rsquo;re creating a table that has a single row per author and we&rsquo;re joining it to the <code>authors</code> table on the <code>author_id</code> foreign key. If that feels eerily familiar to you, it&rsquo;s because this is essentially <em>exactly what happens when we have a <code>has_one</code> association defined on a model</em>. What we need to do is somehow get Rails to use our subquery for a <code>has_one</code> we define. Here&rsquo;s our subquery again:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span></code></pre></div><p>Luckily, Rails allows us to customize – to <em>scope</em> – the query used for a <code>has_one</code> association. Here&rsquo;s how we do that with our subquery:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Author</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_many</span> <span class="ss">:posts</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_one</span> <span class="ss">:newest_post</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nb">select</span><span class="p">(</span><span class="s2">&#34;DISTINCT ON (author_id) *&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="ss">:author_id</span><span class="p">,</span> <span class="ss">created_at</span><span class="p">:</span> <span class="ss">:desc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="ss">class_name</span><span class="p">:</span> <span class="s2">&#34;Post&#34;</span>
</span></span></code></pre></div><p>This basically tells Rails that 1) we have a <code>has_one</code> called <code>newest_post</code>, 2) it is essentially a <code>Post</code>, and 3) to use <code>.select(&quot;SELECT DISTINCT ON (author_id) *&quot;).order(:author_id, created_at: :desc)</code> when generating the query. And because it is just like any other <code>has_one</code> association, you can eager load it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@authors</span> <span class="o">=</span> <span class="no">Author</span><span class="o">.</span><span class="n">includes</span><span class="p">(</span><span class="ss">:newest_post</span><span class="p">)</span><span class="o">.</span><span class="n">all</span>
</span></span><span class="line"><span class="cl"><span class="vi">@authors</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">author</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;Newest post for </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">full_name</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">newest_post</span><span class="o">.</span><span class="n">title</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And it only fires off two queries.</p>
<h2 id="whythisapproachisawesome">Why this approach is awesome</h2>
<p>Let&rsquo;s compare and contrast. Here&rsquo;s how we achieved this with custom query methods:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@authors</span> <span class="o">=</span> <span class="no">Author</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&#34;authors.*,
</span></span></span><span class="line"><span class="cl"><span class="s2">           newest_posts.title AS newest_post_title&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">joins</span><span class="p">(</span><span class="s2">&#34;LEFT JOIN (SELECT DISTINCT ON (author_id) *
</span></span></span><span class="line"><span class="cl"><span class="s2">                     FROM posts
</span></span></span><span class="line"><span class="cl"><span class="s2">                     ORDER BY author_id, created_at DESC)
</span></span></span><span class="line"><span class="cl"><span class="s2">          AS newest_posts ON newest_posts.author_id = authors.id&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p>And here&rsquo;s what we just did:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Author</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_many</span> <span class="ss">:posts</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_one</span> <span class="ss">:newest_post</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nb">select</span><span class="p">(</span><span class="s2">&#34;DISTINCT ON (author_id) *&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="ss">:author_id</span><span class="p">,</span> <span class="ss">created_at</span><span class="p">:</span> <span class="ss">:desc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="ss">class_name</span><span class="p">:</span> <span class="s2">&#34;Post&#34;</span>
</span></span></code></pre></div><p>Already this feels like a big improvement. It eliminates a lot of the inline SQL of the customer query methods, it succinctly describes – <code>has_one :newest_post</code> – what is going on, and it&rsquo;s just more intuitive. The idea that an author has a newest post makes sense. It is easy idea to hold in your head. All that SQL stuffed inline into your Ruby code is not easy to hold in your head.</p>
<p>But there are other benefits to this approach as well.</p>
<p>One of the problems we identified with using custom query methods is that they aren&rsquo;t very composable. If you abstract them away behind named scopes, you can&rsquo;t combine the named scopes because the <code>SELECT</code> clauses interfere with each other. But scoped <code>has_one</code> associations are as composable as you can get.</p>
<p>Let&rsquo;s say we also wanted an <code>oldest_post</code> association:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Author</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_many</span> <span class="ss">:posts</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_one</span> <span class="ss">:newest_post</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nb">select</span><span class="p">(</span><span class="s2">&#34;DISTINCT ON (author_id) *&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="ss">:author_id</span><span class="p">,</span> <span class="ss">created_at</span><span class="p">:</span> <span class="ss">:desc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="ss">class_name</span><span class="p">:</span> <span class="s2">&#34;Post&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="n">has_one</span> <span class="ss">:oldest_post</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nb">select</span><span class="p">(</span><span class="s2">&#34;DISTINCT ON (author_id) *&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="ss">:author_id</span><span class="p">,</span> <span class="ss">created_at</span><span class="p">:</span> <span class="ss">:asc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="ss">class_name</span><span class="p">:</span> <span class="s2">&#34;Post&#34;</span>
</span></span></code></pre></div><p>This allows us to do something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@authors</span> <span class="o">=</span> <span class="no">Author</span><span class="o">.</span><span class="n">includes</span><span class="p">(</span><span class="ss">:newest_post</span><span class="p">,</span> <span class="ss">:oldest_post</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="vi">@authors</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">author</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;Newest post for </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">newest_post</span><span class="o">.</span><span class="n">title</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2"> first posted on </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">oldest_post</span><span class="o">.</span><span class="n">date</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Compared to the mess of SQL and named scopes that we would need if we were using custom query methods, this is a breath of fresh air. Not only is it composable, it&rsquo;s <em>way</em> less code. And it works the way Rails <em>wants</em> to work. What do I mean by that? Well, because we&rsquo;ve set these up as <code>has_one</code> assocations – and that&rsquo;s really what they were all along; an author&rsquo;s newest or oldest post is a single post that is related to the author – we get a bunch of stuff for free.</p>
<p>For instance, let&rsquo;s say we want to show a list of authors with the title of their newest post, but not include any authors who have not posted yet. Now that&rsquo;s simple. We can use our new <code>has_one</code> relations with <code>joins</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@authors</span> <span class="o">=</span> <span class="no">Author</span><span class="o">.</span><span class="n">joins</span><span class="p">(</span><span class="ss">:newest_post</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="vi">@authors</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">author</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;Newest post for </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">newest_post</span><span class="o">.</span><span class="n">title</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And, since these are associations, they&rsquo;ll return full-fledged <code>Post</code> instances. So if we decide that we want to display other attributes of the newest post, there&rsquo;s no need to modify any SQL. We simply call the attribute we need:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="cp">&lt;%=</span> <span class="n">pluralize</span><span class="p">(</span><span class="vi">@author</span><span class="o">.</span><span class="n">newest_post</span><span class="o">.</span><span class="n">word_count</span><span class="p">,</span> <span class="s2">&#34;word&#34;</span><span class="p">)</span> <span class="cp">%&gt;</span>
</span></span></code></pre></div><p>And if we want to have a link to the newest post, that&rsquo;s simple too:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="vi">@author</span><span class="o">.</span><span class="n">newest_post</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="n">post_path</span><span class="p">(</span><span class="vi">@author</span><span class="o">.</span><span class="n">newest_post</span><span class="p">)</span> <span class="cp">%&gt;</span>
</span></span></code></pre></div><p>Or we can use it in a form builder:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="cp">&lt;%=</span> <span class="n">form_for</span> <span class="vi">@author</span><span class="o">.</span><span class="n">newest_post</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="cp">%&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="cp">&lt;%=</span> <span class="n">f</span><span class="o">.</span><span class="n">text_field</span> <span class="ss">:title</span> <span class="cp">%&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="cp">&lt;%=</span> <span class="n">f</span><span class="o">.</span><span class="n">submit</span> <span class="cp">%&gt;</span>
</span></span><span class="line"><span class="cl"><span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">%&gt;</span>
</span></span></code></pre></div><p>Or we can access it&rsquo;s assocations:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="cp">&lt;%=</span> <span class="n">pluralize</span><span class="p">(</span><span class="vi">@author</span><span class="o">.</span><span class="n">newest_post</span><span class="o">.</span><span class="n">comments</span><span class="o">.</span><span class="n">count</span><span class="p">,</span> <span class="s2">&#34;comment&#34;</span><span class="p">)</span> <span class="cp">%&gt;</span>
</span></span></code></pre></div><p>You get the idea. You can do whatever you want with it, because it&rsquo;s an instance of one of your models. But each one of these would have required different custom SQL if we were just using custom query methods to add attributes to our <code>Author</code> instances.</p>
<h2 id="howthisapproachworks">How this approach works</h2>
<p>So that covers why this approach is better, but I want to dive into how this approach works because, even though it might not look like it, we&rsquo;re getting ActiveRecord to use pretty much the same SQL query in both approaches. The main difference is in where we put the parts of that query.</p>
<p>Let&rsquo;s revisit our original query to return a list of the newest posts for each author:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span></code></pre></div><p>In the first approach, we put this into a subquery, joined the result of that subquery to our <code>authors</code> table, then selected the column we needed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>In <em>this</em> approach we don&rsquo;t have to do all of that because Rails already understands how to join <code>has_one</code> relations. Instead, all we have to do is create a <code>has_one</code> relation that executes our query and then Rails will know what to do with it. And if you take a closer look at the <code>has_one</code> we defined above, you&rsquo;ll see that it looks remarkably like that original query of ours:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl">   <span class="n">has_one</span> <span class="ss">:newest_post</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nb">select</span><span class="p">(</span><span class="s2">&#34;DISTINCT ON (author_id) *&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="ss">:author_id</span><span class="p">,</span> <span class="ss">created_at</span><span class="p">:</span> <span class="ss">:desc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="ss">class_name</span><span class="p">:</span> <span class="s2">&#34;Post&#34;</span>
</span></span></code></pre></div><p>In the last argument, we&rsquo;re telling Rails that this <code>has_one</code> relation should return an instance of a <code>Post</code>. Normally, Rails will figure this out automatically based on the name we give our <code>has_one</code> relation, but that won&rsquo;t work in this case, so we have to specify the model class. And Rails knows that the table for the <code>Post</code> class is <code>posts</code>. Then, in the lambda passed as the second argument, we&rsquo;re specifying the <code>SELECT DISTINCT ON</code> and <code>ORDER</code> clauses that we want Rails to use when querying the <code>posts</code> table.</p>
<p>And the rest, as they say, is magic.</p>
<h2 id="wellalmost">Well, almost</h2>
<p>In my opinion, the approach we covered here – using a scoped <code>has_one</code> association – really hits the sweet spot for implementing Greatest Per Group queries in Rails. It works for most use cases and, because it does things in a Rails-y way, it&rsquo;s intuitive and composable. But it breaks down with more complicated stuff that&rsquo;s at the boundary of how much ActiveRecord &ldquo;understands&rdquo; SQL. Like, for instance, if you try to use joins in the custom scope on the <code>has_one</code> relation, or in more complicated uses of the <code>has_one</code> relation when doing eager loading.</p>
<p>That&rsquo;s okay, though, because View Backed Models, which we&rsquo;ll cover in <a href="https://toasterlovin.com/greatest-per-group-rails-view-backed-model/">Part 4</a>, are the knife that cuts through any knot.</p>
]]></content:encoded></item><item><title>Greatest-Per-Group Query in Rails Using Custom Query Methods</title><link>https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825b</guid><pubDate>Mon, 08 Feb 2016 04:35:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><category>PostgreSQL</category><description>Because Rails dynamically creates attributes on our model for any columns returned by the database, all we have to do is get Rails to execute our modified query when loading our collection.</description><content:encoded><![CDATA[<p>In <a href="https://toasterlovin.com/greatest-per-group-postgresql-distinct-on/">Part 1</a> of this series, we covered when Greatest Per Group queries can help avoid the <a href="http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations">N + 1 query</a> problem and how to create them with <a href="http://www.postgresql.org/docs/9.5/static/sql-select.html#SQL-DISTINCT">PostgreSQL&rsquo;s <code>DISTINCT ON</code> feature</a>. Here we&rsquo;ll learn how to take our Greatest Per Group query and fit it into our Rails app using custom query methods.</p>
<h2 id="takingadvantageofactiverecordsdynamicmodelattributebehavior">Taking advantage of ActiveRecord&rsquo;s dynamic model attribute behavior</h2>
<p>One of the things about <a href="http://rubyonrails.org">Ruby on Rails</a> that I found most confusing when I first got started is the way that you don&rsquo;t have to define the attributes of your models <em>in</em> your models. Instead, you just add columns to the underlying database table – usually with migrations, but it doesn&rsquo;t actually matter how they get there – and ActiveRecord will automatically add those attributes to your model instances and create accessors for them.</p>
<p>Though this confused me when I was newer to Rails, I have come to appreciate it as I&rsquo;ve gained experience. It strikes a nice balance between having an easy default and allowing you to roll up your sleeves and get your hands dirty when necessary. And getting our hands dirty is exactly what we&rsquo;ll do here.</p>
<p>Because Rails dynamically creates attributes on our model for any columns returned by the database, all we have to do is get Rails to execute our query from <a href="postgresql-greatest-per-group-queries-using-distinct-on/">part 1</a> when loading our collection of authors. Then each author will have an attribute called <code>newest_post_title</code> with the title of the newest post.</p>
<p>Here&rsquo;s that query again:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>Part of the magic of Rails is that it&rsquo;s intelligent naming defaults allow us to avoid writing SQL most of the time. But the tools to get our hands dirty with SQL are right there, waiting for us when we need them. Here&rsquo;s how we get Rails to execute that query:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@authors</span> <span class="o">=</span> <span class="no">Author</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&#34;authors.*,
</span></span></span><span class="line"><span class="cl"><span class="s2">           newest_posts.title AS newest_post_title&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">joins</span><span class="p">(</span><span class="s2">&#34;LEFT JOIN (SELECT DISTINCT ON (author_id) *
</span></span></span><span class="line"><span class="cl"><span class="s2">                     FROM posts
</span></span></span><span class="line"><span class="cl"><span class="s2">                     ORDER BY author_id, created_at DESC)
</span></span></span><span class="line"><span class="cl"><span class="s2">          AS newest_posts ON newest_posts.author_id = authors.id&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p>It&rsquo;s actually incredibly straightforward. We&rsquo;re using the <code>select</code> method to specify the <code>SELECT</code> statement and then chaining on the <code>joins</code> method to specify the <code>LEFT JOIN</code>. If you do this in a Rails console, you&rsquo;ll see that ActiveRecord executes the exact SQL query we want.</p>
<p>Now, we can access the <code>newest_post_title</code> when we iterate over our list of authors like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@authors</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">author</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;Newest post for </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">author</span><span class="o">.</span><span class="n">newest_post_title</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And it only generates a single query, rather than the N + 1 queries we would generate otherwise.</p>
<p>Taking advantage of the way ActiveRecord dynamically creates an attribute for every column present in the query result is an incredibly powerful technique. It allows us to essentially add <em>any</em> attribute we need to <em>any</em> model, all on the fly, without having to set anything up in our model class ahead of time.</p>
<p>All we have to do is craft the right SQL statement.</p>
<h2 id="someshortcomingswiththisapproach">Some shortcomings with this approach</h2>
<p>The most obvious shortcoming with this approach is that it is rather verbose and ugly. You&rsquo;ve got a lot of SQL inside those chained <code>select</code> and <code>joins</code> methods and, unless you wrote the code yourself, it takes a bit of puzzling to figure out what&rsquo;s going on. This shortcoming is easy to overcome, though. We can encapsulate all that logic in a <a href="http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope">named scope</a>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">scope</span> <span class="ss">:with_newest_post_title</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&#34;authors.*,
</span></span></span><span class="line"><span class="cl"><span class="s2">           newest_posts.title AS newest_post_title&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">joins</span><span class="p">(</span><span class="s2">&#34;LEFT JOIN (SELECT DISTINCT ON (author_id) *
</span></span></span><span class="line"><span class="cl"><span class="s2">                     FROM posts
</span></span></span><span class="line"><span class="cl"><span class="s2">                     ORDER BY author_id, created_at DESC)
</span></span></span><span class="line"><span class="cl"><span class="s2">          AS newest_posts ON newest_posts.author_id = authors.id&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This named scope allows you to just do <code>Author.with_newest_post_title</code> instead of typing that huge long thing out each time, which is definitely a win.</p>
<p>A less obvious shortcoming with this approach is that it is not composable. Let&rsquo;s say you also want to display how long each author has been writing for the site. Now you need the <em>date</em> of each author&rsquo;s <em>oldest</em> post as well as the <em>title</em> of each author&rsquo;s <em>newest</em> post. You could create another named scope for the date of the author&rsquo;s first post:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">scope</span> <span class="ss">:with_oldest_post_date</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">select</span><span class="p">(</span><span class="s2">&#34;authors.*,
</span></span></span><span class="line"><span class="cl"><span class="s2">          oldest_posts.date AS oldest_post_title&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">joins</span><span class="p">(</span><span class="s2">&#34;LEFT JOIN (SELECT DISTINCT ON (author_id) *
</span></span></span><span class="line"><span class="cl"><span class="s2">                     FROM posts
</span></span></span><span class="line"><span class="cl"><span class="s2">                     ORDER BY author_id, created_at ASC)
</span></span></span><span class="line"><span class="cl"><span class="s2">          AS oldest_posts ON oldest_posts.author_id = authors.id&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>But when you try to chain the two named scopes together – that is, when you try to <em>compose</em> them – with something like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">Author</span><span class="o">.</span><span class="n">with_newest_post_title</span><span class="o">.</span><span class="n">with_oldest_post_date</span>
</span></span></code></pre></div><p>It won&rsquo;t work. That&rsquo;s because the <code>SELECT</code> statements from each named scope conflict with each other. Instead, you would need a <em>third</em> named scope that combines the two:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">scope</span> <span class="ss">:with_newest_post_title_and_oldest_post_date</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">select</span><span class="p">(</span><span class="s2">&#34;authors.*,
</span></span></span><span class="line"><span class="cl"><span class="s2">          newest_posts.title AS newest_post_title,
</span></span></span><span class="line"><span class="cl"><span class="s2">          oldest_posts.date AS oldest_post_title&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">joins</span><span class="p">(</span><span class="s2">&#34;LEFT JOIN (SELECT DISTINCT ON (author_id) *
</span></span></span><span class="line"><span class="cl"><span class="s2">                     FROM posts
</span></span></span><span class="line"><span class="cl"><span class="s2">                     ORDER BY author_id, created_at DESC)
</span></span></span><span class="line"><span class="cl"><span class="s2">          AS newest_posts ON newest_posts.author_id = authors.id&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="n">joins</span><span class="p">(</span><span class="s2">&#34;LEFT JOIN (SELECT DISTINCT ON (author_id) *
</span></span></span><span class="line"><span class="cl"><span class="s2">                     FROM posts
</span></span></span><span class="line"><span class="cl"><span class="s2">                     ORDER BY author_id, created_at ASC)
</span></span></span><span class="line"><span class="cl"><span class="s2">          AS oldest_posts ON oldest_posts.author_id = authors.id&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Does that look like a hot mess to you? Because it looks like a hot mess to me. We&rsquo;ve got <em>three</em> named scopes to account for all the possible combinations of the <em>two</em> attributes we might want to include in our query. That is literally the definition of <a href="https://en.wikipedia.org/wiki/Combinatorial_explosion">combinatorial explosion</a>. And anyway, who wants big blocks of SQL mixed in with their Ruby?</p>
<p>But this approach is a pretty handy tool to have in your back pocket when you know exactly how to achieve what you want in SQL and you just need to get it done fast. The next two parts will cover approaches that improve on the shortcomings of this approach, <em>plus</em> bring other benefits to the table:</p>
<ol>
<li><a href="https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/">Using a scoped <code>has_one</code> association</a> (clean and elegant)</li>
<li><a href="https://toasterlovin.com/greatest-per-group-rails-view-backed-model/">Using a view backed model</a> (when all else fails)</li>
</ol>
]]></content:encoded></item><item><title>Greatest-Per-Group Query in PostgreSQL Using DISTINCT ON</title><link>https://toasterlovin.com/greatest-per-group-postgresql-distinct-on/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8259</guid><pubDate>Sun, 07 Feb 2016 21:23:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><category>PostgreSQL</category><description>In my Rails apps, I often need to get the largest/smallest/newest/oldest/whateverest element in a model's `has_many` association. Here's how I do that.</description><content:encoded><![CDATA[<h2 id="whentousegreatestpergroupqueries">When to use Greatest Per Group queries</h2>
<p>Something that I find myself needing to do frequently in my <a href="http://rubyonrails.org">Ruby on Rails</a> apps is to get the largest/smallest/newest/oldest/whateverest element in a model&rsquo;s <code>has_many</code> association. So, if my app has a <code>Author</code> model which <code>has_many :posts</code>, I might want to show the title of an author&rsquo;s most recent post when I&rsquo;m displaying other information about the author.</p>
<p>If I&rsquo;m only showing a <em>single</em> author in my view, this is easy to do without encountering a performance problem. I would just do something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="vi">@post</span> <span class="o">=</span> <span class="vi">@author</span><span class="o">.</span><span class="n">posts</span><span class="o">.</span><span class="n">order</span><span class="p">(</span><span class="ss">created_at</span><span class="p">:</span> <span class="ss">:desc</span><span class="p">)</span><span class="o">.</span><span class="n">first</span>
</span></span><span class="line"><span class="cl"><span class="vi">@post</span><span class="o">.</span><span class="n">title</span>
</span></span></code></pre></div><p>That generates two queries: one to load the author and another to load the most recent post. Pretty simple.</p>
<p>But if I want to show a <em>list</em> of authors along with the title of each author&rsquo;s most recent post, then we have to do something different. If we try the same approach, we can generate a lot of queries: one to load the list authors and then another N queries as we loop over each author and load their most recent post. This is the dreaded <a href="http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations">N + 1 query</a> problem.</p>
<p>We really only want to fire off two queries: one to load the authors and then one more to load just their most recent posts. I am calling this a Greatest Per Group query because it is a special case of a <a href="http://stackoverflow.com/questions/tagged/greatest-n-per-group">Greatest N Per Group</a> query, where N = 1. And it doesn&rsquo;t have to be the <em>greatest</em> per group, it could be the largest, smallest, newest, oldest, or whatever-est per group. The point is that you are trying to rank the records on the many side of a <a href="http://guides.rubyonrails.org/association_basics.html#the-has-many-association">one-to-many relationship</a> and only return a single record.</p>
<p>Okay, now that we know what a Greatest Per Group query is and where it&rsquo;s useful, let&rsquo;s figure out how they work.</p>
<h2 id="howgreatestpergroupquerieswork">How Greatest Per Group queries work</h2>
<p>The good news is that SQL&rsquo;s reason for existence is to enable exactly this kind of thing. What we want to do is <code>JOIN</code> our <code>authors</code> table to a table of <code>posts</code> which only has one post for each author: the most recent post. So we know the overall structure will look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="n">newest_posts</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>That&rsquo;s a fairly straightforward join. In this case we&rsquo;re using a <code>LEFT JOIN</code> since we want to list all authors, even if they have never written a post. What we glossed over, though, was that <code>newest_posts</code> table. The problem is that we don&rsquo;t have a <code>newest_posts</code> table. So how are we going to join a table that doesn&rsquo;t exist?</p>
<p>One of the great things about SQL is that it allows you to use the results of a query as a temporary table that you can join to. So, we&rsquo;re going to create a temporary <code>newest_posts</code> table and then join it to our <code>authors</code> table. First, though, we need to figure out how to generate a table that only has the most recent post for each author.</p>
<p>Your first thought might be that this is a perfect place to use <code>GROUP BY</code>. That was my first thought, too. But <code>GROUP BY</code> won&rsquo;t work for our purposes here because – in Postgres, at least – it limits what columns you can select to the column(s) you&rsquo;re grouping by and columns created by aggregate functions like <code>MIN</code>, <code>MAX</code>, <code>AVG</code>, <code>SUM</code>, and <code>COUNT</code>. So a query like this will return an error:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">posts</span><span class="p">.</span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span></code></pre></div><p>The best we can do with <code>GROUP BY</code> is something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="k">MAX</span><span class="p">(</span><span class="n">created_at</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="w">
</span></span></span></code></pre></div><p>That will return a result that looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">author_id | newest_post
</span></span><span class="line"><span class="cl">----------+------------
</span></span><span class="line"><span class="cl">        1 | 2015-08-07
</span></span><span class="line"><span class="cl">        2 | 2015-11-15
</span></span><span class="line"><span class="cl">        3 | 2014-04-23
</span></span><span class="line"><span class="cl">        4 | 2015-01-18
</span></span></code></pre></div><p>This could be useful if all we want to do is show <em>when</em> the last post was created. But we want to show the <em>title</em> of the newest post&rsquo;s, so this isn&rsquo;t very useful to us. That means <code>GROUP BY</code> is out as an option, at least in Postgres. So, what are our options?</p>
<p>Well, Postgres has this marvelous thing called <code>DISTINCT ON</code>. You can go <a href="http://www.postgresql.org/docs/9.5/static/sql-select.html#SQL-DISTINCT">read the documentation</a> for the full run down, but the short description is this: <code>DISTINCT ON</code> will only return the first row for each group of rows that share a unique combination of your distinct column(s). So you can use <code>ORDER BY</code> to sort your results and that will determine which row <code>DISTINCT ON</code> returns. This allows you to get only the newest, oldest, largest, smallest, etc. records for an association. Plus, unlike <code>GROUP BY</code>, it allows you to <code>SELECT</code> any and all columns that you desire.</p>
<p>Here&rsquo;s how we get a list of each of the most recent posts per author using <code>DISTINCT ON</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span></code></pre></div><p>That&rsquo;s it. Fairly simple when it&rsquo;s all said and done. There are a couple of things which tripped me up the first time I used <code>DISTINCT ON</code>, though, so I&rsquo;ll list them here:</p>
<ul>
<li>There is no comma directly after the <code>DISTINCT ON (author_id)</code> part of the <code>SELECT</code> statement. But there are commas after that if you&rsquo;re selecting more than one column.</li>
<li>The first (leftmost) column in the <code>ORDER BY</code> clause has to be the distinct column – <code>author_id</code> in our case. This is kinda goofy, since I think it&rsquo;s an implementation detail leaking out, but it&rsquo;s a thing that Postgres will make you do.</li>
<li>The remaining items in the <code>ORDER BY</code> clause work as you normally expect and are what determine whether you get the newest, oldest, largest, smallest, or whateverest record, so pay attention to them.</li>
</ul>
<p>Okay, let&rsquo;s put it all together now. So, we have our overall query:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="n">newest_posts</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>And we know that the <code>newest_posts</code> table that we&rsquo;re joining to the <code>authors</code> table is actually going to be a temporary table that we generate with this query:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span></code></pre></div><p>But how do we actually do that? Well, we wrap the query in parentheses, which makes it a subquery, then we give it a name with <code>AS newest_posts</code>, and then we join it. Here&rsquo;s what that looks like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">title</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_post_title</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="n">authors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="k">DISTINCT</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="p">(</span><span class="n">author_id</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">author_id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">           </span><span class="k">AS</span><span class="w"> </span><span class="n">newest_posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">ON</span><span class="w"> </span><span class="n">newest_posts</span><span class="p">.</span><span class="n">author_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">authors</span><span class="p">.</span><span class="n">id</span><span class="w">
</span></span></span></code></pre></div><p>This will return a result that looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">author_id | first_name | last_name | newest_post_title
</span></span><span class="line"><span class="cl">----------+------------+-----------+------------------
</span></span><span class="line"><span class="cl">        1 | Jane       | Austen    | Persuasion
</span></span><span class="line"><span class="cl">        2 | Charles    | Dickens   | Oliver Twist
</span></span><span class="line"><span class="cl">        3 | J.D.       | Salinger  | Nine Stories
</span></span></code></pre></div><p>Okay, now we know what our SQL should look like. But how do we put that into our Rails app in a way that&rsquo;s useful? Well, there are three approaches that I will cover:</p>
<ol>
<li><a href="https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/">Using custom query methods</a> (quick and dirty)</li>
<li><a href="https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/">Using a scoped <code>has_one</code> association</a> (clean and elegant)</li>
<li><a href="https://toasterlovin.com/greatest-per-group-rails-view-backed-model/">Using a view backed model</a> (when all else fails)</li>
</ol>
]]></content:encoded></item><item><title>How I Record Programming Talks</title><link>https://toasterlovin.com/how-i-record-programming-talks/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825a</guid><pubDate>Mon, 11 Jan 2016 18:09:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><description>I usually record the talks at the Portland Ruby Brigade’s monthly meetings. In part this is because it feels like a shame to have the knowledge contained in the talks not be available to the wider world. But also it’s because it’s just not that much work to make the recordings and get them up on Youtube (it usually takes me about an hour and a half per meeting).
So far I’ve been happy with how this has turned out. For very little work on my part (and with some help from others), our YouTube channel now has 70 videos, 69 subscribers, and ~4,800 views. Considering that we typically get 70-80 attendees at each meeting, this has greatly expanded the reach of our merry little band of Ruby programmers.</description><content:encoded><![CDATA[<p>I usually record the talks at the <a href="http://pdxruby.org/">Portland Ruby Brigade&rsquo;s</a> monthly meetings. In part this is because it feels like a shame to have the knowledge contained in the talks not be available to the wider world. But also it&rsquo;s because it&rsquo;s just not that much work to make the recordings and get them up on Youtube (it usually takes me about an hour and a half per meeting).</p>
<p>So far I&rsquo;ve been happy with how this has turned out. For very little work on my part (and with some help from others), <a href="https://www.youtube.com/channel/UCgEEluMvb1Fp3FExqh-YZmw">our YouTube channel</a> now has 70 videos, 69 subscribers, and ~4,800 views. Considering that we typically get 70-80 attendees at each meeting, this has greatly expanded the reach of our merry little band of Ruby programmers.</p>
<p>In this post I&rsquo;m going to run through the gear and software I use to make these recordings.</p>
<h6 id="camera">Camera</h6>
<p>I use an iPhone 6+. Any recent model will do, though. I recommend having at least 10gb of free space on whatever iPhone you use. If you plan on using your personal phone, this will probably mean having at least a 32gb model.</p>
<h6 id="tripod">Tripod</h6>
<p>Any cheap tripod will do. I&rsquo;m using an <a href="http://www.amazon.com/gp/product/B005KP473Q?psc=1&amp;redirect=true&amp;ref_=oh_aui_detailpage_o01_s00">Amazon Basics 60&quot; Lightweight Tripod w/ Bag</a> ($24).</p>
<h6 id="iphonetripodmount">iPhone Tripod Mount</h6>
<p>There are a bazillion iPhone tripod mounts out there. I&rsquo;m using the <a href="http://www.amazon.com/gp/product/B00HQO5VJ8?psc=1&amp;redirect=true&amp;ref_=oh_aui_detailpage_o04_s00">Glif Adjustable Tripod Mount for Smartphones</a> ($30). It works well enough, but there are probably better and/or less expensive options.</p>
<h6 id="wirelessmicrophone">Wireless Microphone</h6>
<p>You can spend a <em>lot</em> of money on microphones. And it can be tempting to do so, since having a wireless <a href="https://en.wikipedia.org/wiki/Lavalier_microphone">lavalier microphone</a> is critical to capturing high-quality audio of the speaker. But, as far as I can tell, the &ldquo;pro&rdquo; options all cost at least $600, which is way outside of my price range.</p>
<p>Thanks to a suggestion from my friend, <a href="http://chuckvose.com/">Chuck Lauer Vose</a>, I learned that there is a segment of the microphone market that is oriented toward teachers, instead of audio/video professionals. And since teachers and schools are not typically flush with cash, these options tend to be much more affordable. The wireless microphone that I settled on is the <a href="http://www.amazon.com/gp/product/B00KLFJZ6Y?psc=1&amp;redirect=true&amp;ref_=oh_aui_detailpage_o09_s00">Movo WMIC50 2.4GHz Wireless Lavalier Microphone System</a> ($115).</p>
<p>Technically speaking, there is a tiny bit of lag with this microphone. In practice, though, you can&rsquo;t tell unless you&rsquo;re looking for it. They operate on AAA batteries and there is essentially zero setup; they just work.</p>
<h6 id="microphonemount">Microphone Mount</h6>
<p>You&rsquo;ll need a way to mount the wireless mic receiver to your tripod, since it needs to plug into your phone and, thus, be near it. I&rsquo;m using a <a href="http://www.amazon.com/gp/product/B00JKDMG96?psc=1&amp;redirect=true&amp;ref_=oh_aui_detailpage_o04_s01">generic clip on mount</a> ($10). I actually don&rsquo;t know what the trade name is for these things, but they&rsquo;re essentially a clip with a 1/4&quot; threaded mount where you can screw on the mic receiver (or other gear, from what I gather).</p>
<h6 id="microphoneadapter">Microphone Adapter</h6>
<p>I have no idea why, but the output from battery powered microphones, including the one I linked to above, is not compatible with the iPhone&rsquo;s microphone jack. So, you&rsquo;ll need an adapter, like <a href="http://www.kvconnection.com/product-p/km-iphone-mic.htm">this one from kVconnection</a> ($25) that I found after Googling about this for a while. You can probably find this elsewhere, but I just cargo-culted this product from somebody else&rsquo;s blog post and it works, which is far enough down the rabbit hole for my tastes.</p>
<h6 id="batteriespower">Batteries &amp; Power</h6>
<p>You&rsquo;ll need AAA batteries for the wireless microphone system. I like Sanyo&rsquo;s Eneloop rechargeables. Here&rsquo;s an <a href="http://www.amazon.com/gp/product/B00JHKSMIG?psc=1&amp;redirect=true&amp;ref_=oh_aui_detailpage_o04_s00">8-pack of AAA Eneloops</a> ($16) and the <a href="http://www.amazon.com/Panasonic-BQ-CC17SBA-Advanced-Individual-Indicator/dp/B00JHKSLM8/ref=sr_1_4?s=electronics&amp;ie=UTF8&amp;qid=1452534259&amp;sr=1-4&amp;keywords=eneloop+charger">Eneloop charger</a> ($21).</p>
<p>You&rsquo;ll also want to bring an extension cord, power strip, and the power adapter for your phone. Just trust me on this. Your mic batteries will run out. Your phone battery will run out. It&rsquo;s better to just be prepared for this eventuality.</p>
<h6 id="telephotolensifyouneedit">Telephoto Lens (if you need it)</h6>
<p>I&rsquo;m lucky enough to be able to set my phone &amp; tripod up nice and close to the speakers at the Portland Ruby Brigade monthly meetings, but distance to the speaker is largely dictated by the venue. You may run into a situation where you need some sort of optical zoom (you don&rsquo;t want to use digital zoom). There are <a href="http://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&amp;field-keywords=iphone+telephoto+lens">a bunch of iPhone compatible telephoto lenses</a>. I bought the <a href="http://www.amazon.com/gp/product/B00T9S9NV6?psc=1&amp;redirect=true&amp;ref_=oh_aui_detailpage_o02_s01">Olloclip Telephoto Lens</a> ($100), but can&rsquo;t recommend it, per se, since I haven&rsquo;t actually needed to use it.</p>
<h6 id="software">Software</h6>
<p>I originally used the built-in camera app on the iPhone, but videos made with that app get automatically synced to Apple&rsquo;s photo cloud service if you have syncing turned on (I do), and that syncing process takes forever and destroys my home Internet connection while it&rsquo;s happening. So I recently switched to using Apple&rsquo;s <a href="http://www.apple.com/ios/imovie/">iMovie app</a> ($5). This keeps the videos from being synced to the cloud and provides some useful editing options (and, for videos under a certain length, you can upload directly to YouTube from within the app). My videos are usually too large to upload directly to YouTube, though, so I Airdrop the finished videos to my Mac, then upload to YouTube from there.</p>
]]></content:encoded></item><item><title>Rails: Static Pages Using the Controller Route Macro</title><link>https://toasterlovin.com/rails-static-pages-using-the-controller-route-macro/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8257</guid><pubDate>Fri, 26 Jun 2015 23:13:19 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>One of my Rails apps recently took responsibility for serving the home page and marketing pages from an installation of Wordpress, mainly to allow for a site-wide nav bar which shows login status. Doing this in Rails is not rocket science, but after experimenting with a few different approaches this is the approach I think works best, along with an improvement to the status quo.
The idea is to put all the static pages in a PagesController which has a single action and corresponding view for each static page. So your homepage would have an index action and a corresponding index.html.erb view file. And your About Us page might be an about action with an about.html.erb view. And so on. Here’s what it all looks like.</description><content:encoded><![CDATA[<p>One of my Rails apps recently took responsibility for serving the home page and marketing pages from an installation of Wordpress, mainly to allow for a site-wide nav bar which shows login status. Doing this in Rails is not rocket science, but after experimenting with a few different approaches this is the approach I think works best, along with an improvement to the status quo.</p>
<p>The idea is to put all the static pages in a <code>PagesController</code> which has a single action and corresponding view for each static page. So your homepage would have an <code>index</code> action and a corresponding <code>index.html.erb</code> view file. And your About Us page might be an <code>about</code> action with an <code>about.html.erb</code> view. And so on. Here&rsquo;s what it all looks like.</p>
<p>In your <code>config/routes.rb</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">App</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">root</span> <span class="ss">to</span><span class="p">:</span> <span class="s2">&#34;pages#index&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="n">get</span> <span class="ss">:contact</span><span class="p">,</span> <span class="ss">to</span><span class="p">:</span> <span class="s2">&#34;pages#contact&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="n">get</span> <span class="ss">:about</span><span class="p">,</span> <span class="ss">to</span><span class="p">:</span> <span class="s2">&#34;pages#contact&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>In your <code>app/controllers/pages_controller.rb</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">PagesController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">index</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">contact</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">about</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>And then you just have a single view to match each action in <code>app/views/pages/</code>.</p>
<p>This is all fine and straightforward, but those route declarations really bothered me. They strike me as very repetitious, especially as you add more and more static pages, so I went digging through the Rails documentation and came across the <a href="http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-controller">controller route macro</a>. It essentially scopes a bunch of routes to a specific controller. In other words, exactly what I was looking for.</p>
<p>Now your routes look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">App</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">controller</span> <span class="ss">:pages</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="n">root</span> <span class="ss">to</span><span class="p">:</span> <span class="ss">:index</span>
</span></span><span class="line"><span class="cl">    <span class="n">get</span> <span class="ss">:contact</span>
</span></span><span class="line"><span class="cl">    <span class="n">get</span> <span class="ss">:about</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>This solution is two lines longer, yet so much more concise. It nicely groups together a set of routes that are related to each other. I think the <a href="http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html">Rails route scoping documentation</a> is worth a read if you find yourself repetitively adding the same <code>controller</code> value to a bunch of different routes.</p>
]]></content:encoded></item><item><title>Rails: Organizing Controllers with Modules</title><link>https://toasterlovin.com/rails-organizing-controllers-with-modules/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8255</guid><pubDate>Tue, 05 May 2015 03:41:23 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>One of my Ruby on Rails apps has lots of models and a few models that each have lots of has_many associations. For instance, the Company model has 27 has_many associations. Naturally, I have routes and controllers for most of these associations, so it can be pretty overwhelming when you do an ls in the app/controllers directory. Unless you’re intimately familiar with how all the models relate to each other, nothing will clue you in to the fact that a bunch of the controllers are for managing relations of Company and that incoming requests reach those controllers via nested routes. This is because the default behavior of the Rails router is to point nested routes to a non-namespaced controller.</description><content:encoded><![CDATA[<p>One of my <a href="http://rubyonrails.org/">Ruby on Rails</a> apps has <em>lots</em> of models and a few models that each have <em>lots</em> of <code>has_many</code> associations. For instance, the <code>Company</code> model has 27 <code>has_many</code> associations. Naturally, I have routes and controllers for most of these associations, so it can be pretty overwhelming when you do an <code>ls</code> in the <code>app/controllers</code> directory. Unless you&rsquo;re intimately familiar with how all the models relate to each other, nothing will clue you in to the fact that a bunch of the controllers are for managing relations of <code>Company</code> and that incoming requests reach those controllers via <a href="http://guides.rubyonrails.org/routing.html#nested-resources">nested routes</a>. This is because the default behavior of the Rails router is to point nested routes to a non-namespaced controller.</p>
<p>So, if you have routes defined like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:companies</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">resources</span> <span class="ss">:addresses</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>The route <code>/companies/1/address/2</code> will point to the <code>AddressesController</code>, instead of, say, the <code>Companies::AddressesController</code>. To me, this is confusing and unintuitive, but it is not a huge problem for smaller apps. It gets to be difficult once a routes file starts to look more like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:companies</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">resources</span> <span class="ss">:addresses</span>
</span></span><span class="line"><span class="cl">  <span class="n">resources</span> <span class="ss">:people</span>
</span></span><span class="line"><span class="cl">  <span class="n">resources</span> <span class="ss">:orders</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:products</span>
</span></span><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:industries</span>
</span></span><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:salespeople</span>
</span></span></code></pre></div><p>Now, when you look in your controllers directory, it will look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">#</span> ls app/controllers
</span></span><span class="line"><span class="cl"><span class="go">addresses_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">companies_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">industries_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">orders_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">people_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">products_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">salespeople_controller.rb
</span></span></span></code></pre></div><p>To figure out that the <code>AddressesController</code>, <code>PeopleController</code>, and <code>OrdersController</code> all handle nested routes requires either 1) opening each one up and reading it, or 2) perusing the routes file. Essentially, the app&rsquo;s routes, which are hierarchical in nature, have been flattened into a single level of hierarchy. Okay, maybe you don&rsquo;t think it&rsquo;s that big of a deal, but imagine trying to make sense of this when you have dozens of controllers and many of them handle nested routes. Luckily, Rails has some tools to help organize your controllers.</p>
<p>What we really want to do is namespace all the controllers that handle nested routes for <code>Company</code> associations in a module called <code>Companies</code>. So, the <code>AddressesController</code> from above would become the <code>Companies::AddressesController</code> and so on. When we do this, because of the way Rails looks for classes we have defined in our app, we will end up with a <code>companies</code> directory in <code>app/controllers</code> that neatly contains all of our namespaced controllers.</p>
<p>Some code will explain this better. Here&rsquo;s how you tell the router that a set of routes should be directed to controllers namespaced under a certain module:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:companies</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">scope</span> <span class="ss">module</span><span class="p">:</span> <span class="s2">&#34;companies&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="n">resources</span> <span class="ss">:addresses</span>
</span></span><span class="line"><span class="cl">    <span class="n">resources</span> <span class="ss">:people</span>
</span></span><span class="line"><span class="cl">    <span class="n">resources</span> <span class="ss">:orders</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:products</span>
</span></span><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:industries</span>
</span></span><span class="line"><span class="cl"><span class="n">resources</span> <span class="ss">:salespeople</span>
</span></span></code></pre></div><p>And now, when you look in your controllers directory, it should look like this (with the <code>companies</code> directory containing the namespaced controllers):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-console" data-lang="console"><span class="line"><span class="cl"><span class="gp">#</span> ls app/controllers
</span></span><span class="line"><span class="cl"><span class="go">companies_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">companies/
</span></span></span><span class="line"><span class="cl"><span class="go">industries_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">products_controller.rb
</span></span></span><span class="line"><span class="cl"><span class="go">salespeople_controller.rb
</span></span></span></code></pre></div><p>This is much more comprehensible. You know that all the controllers you see in the root controllers directory stand on their own, so to speak. And all the controllers in the <code>companies</code> directory are for handling nested <code>Company</code> routes (just remember to prefix the all of the controller class names with <code>Companies::</code> when you define them). Plus, now there is a shared hierarchy between your routes file, the names of your controller classes, and the names and layout of the files on disk.</p>
]]></content:encoded></item><item><title>Rails: Organizing Models by Attribute</title><link>https://toasterlovin.com/rails-organizing-models-by-attribute/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8254</guid><pubDate>Sun, 19 Apr 2015 20:12:55 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>One of the Ruby on Rails apps that I work on has a few models that have lots of stuff in them. The Company model in this app is 311 lines long. Now, I know that won’t break any records – theUser model in Discourse is 906 lines long – but it’s long enough to keep you from holding the whole thing in your head at once. As a result, I’ve changed the way I organize all the attribute logic in my models.</description><content:encoded><![CDATA[<p>One of the <a href="http://rubyonrails.org/">Ruby on Rails</a> apps that I work on has a few models that have <em>lots</em> of stuff in them. The <code>Company</code> model in this app is 311 lines long. Now, I know that won&rsquo;t break any records – the<code>User</code> model in <a href="http://www.discourse.org/">Discourse</a> <a href="https://github.com/discourse/discourse/blob/master/app/models/user.rb">is 906 lines long</a> – but it&rsquo;s long enough to keep you from holding the whole thing in your head at once. As a result, I&rsquo;ve changed the way I organize all the attribute logic in my models.</p>
<p>In all the Rails tutorials, you will see models organized something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Company</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="n">attr_accessible</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:billing_address_id</span><span class="p">,</span> <span class="ss">:shipping_address_id</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="ss">:industry_id</span><span class="p">,</span> <span class="ss">:salesperson_id</span><span class="p">,</span> <span class="ss">:price_level_id</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:billing_address</span><span class="p">,</span> <span class="ss">:shipping_address</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="ss">:industry</span><span class="p">,</span> <span class="ss">:salesperson</span><span class="p">,</span> <span class="ss">:price_level</span><span class="p">,</span> <span class="ss">presence</span><span class="p">:</span> <span class="kp">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">uniqueness</span><span class="p">:</span> <span class="kp">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">belongs_to</span> <span class="ss">:billing_address</span><span class="p">,</span> <span class="ss">class</span><span class="p">:</span> <span class="s2">&#34;Address&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># And so on</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>I think this is just wrong.</p>
<p>All the logic related to a single attribute is spread out across the entire model. If you want to know what the <code>name</code> attribute is all about, you have to look in three different places, which means it&rsquo;s easy to miss something. You can get away with this when a model is small, but it&rsquo;s simply unworkable as a model grows larger than the height of your screen. Here&rsquo;s how I would rewrite this model:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Company</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="n">attr_accessible</span> <span class="ss">:name</span>
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">presence</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">uniqueness</span><span class="p">:</span> <span class="kp">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">attr_accessible</span> <span class="ss">:status</span>
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:status</span><span class="p">,</span> <span class="ss">presence</span><span class="p">:</span> <span class="kp">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">attr_accessible</span> <span class="ss">:billing_address_id</span>
</span></span><span class="line"><span class="cl">  <span class="n">belongs_to</span> <span class="ss">:billing_address</span><span class="p">,</span> <span class="ss">class</span><span class="p">:</span> <span class="s2">&#34;Address&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:billing_address</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1"># And so on</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>This is functionally equivalent to the first example, but it&rsquo;s easy to immediately grasp everything there is to know about the <code>name</code> attribute – because it&rsquo;s all there on those first two lines and nowhere else. The only drawback is that this approach results in <em>even longer</em> model files (since each <code>attr_accessible</code> and <code>validates_presence_of</code> macro gets its own line), but so what?</p>
<p>Do you really want to be reading the scribblings of a madman? Because that&rsquo;s what the first approach is.</p>
]]></content:encoded></item><item><title>Rails: Testing for Insecure Admin Routes</title><link>https://toasterlovin.com/rails-testing-for-insecure-admin-routes/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8252</guid><pubDate>Sat, 02 Nov 2013 19:00:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>I have a Ruby on Rails app with an admin section, as is common for a lot of apps. The admin section is namespaced, so all of the controllers are named something like Admin::WidgetsController and the routes all start with /admin.
Now, there is no reason, ever, for a non-admin user to do anything in the admin section, so I created an Admin::ApplicationController and put a before_filter in it to redirect requests from non-admin users to the admin login page. Then, I had all of my Admin:: controllers inherit from it.</description><content:encoded><![CDATA[<p>I have a Ruby on Rails app with an admin section, as is common for a lot of apps. The admin section is namespaced, so all of the controllers are named something like <code>Admin::WidgetsController</code> and the routes all start with <code>/admin</code>.</p>
<p>Now, there is no reason, ever, for a non-admin user to do anything in the admin section, so I created an <code>Admin::ApplicationController</code> and put a <code>before_filter</code> in it to redirect requests from non-admin users to the admin login page. Then, I had all of my <code>Admin::</code> controllers inherit from it.</p>
<p>So I&rsquo;m all set, right?</p>
<p>Of course, the weak link in this chain is that I have to remember to make my <code>Admin::</code> controllers inherit from <code>Admin::ApplicationController</code>. But I&rsquo;m just a human &ndash; and I frequently use generators to create my controllers &ndash; so I&rsquo;m always forgetting to do this.</p>
<p>But this is a huge sercurity problem. And, now that I know how to <a href="https://toasterlovin.com/rails-testing-for-orphaned-routes/">test for orphaned routes</a>, testing that all of my <code>/admin</code> routes are secure is a piece of cake.</p>
<p>In fact, this test caught me forgetting to inherit from <code>Admin::ApplicationController</code> not more than 3 hours ago. Enjoy!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;test_helper&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Admin</span><span class="o">::</span><span class="no">InsecureRoutesTest</span> <span class="o">&lt;</span> <span class="no">ActionDispatch</span><span class="o">::</span><span class="no">IntegrationTest</span>
</span></span><span class="line"><span class="cl">  <span class="no">ROUTES</span> <span class="o">=</span> <span class="no">Rails</span><span class="o">.</span><span class="n">application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">route</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Turn the route path spec into a string:</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># - Remove the &#34;(.:format)&#34; bit at the end</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># - Use &#34;1&#34; for all params</span>
</span></span><span class="line"><span class="cl">    <span class="n">path</span> <span class="o">=</span> <span class="n">route</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">spec</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/\(\.:format\)/</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/:[a-zA-Z_]+/</span><span class="p">,</span> <span class="s2">&#34;1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Route verbs are stored as regular expressions; convert them to symbols</span>
</span></span><span class="line"><span class="cl">    <span class="n">verb</span> <span class="o">=</span> <span class="sx">%W{ GET POST PUT PATCH DELETE }</span><span class="o">.</span><span class="n">grep</span><span class="p">(</span><span class="n">route</span><span class="o">.</span><span class="n">verb</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">downcase</span><span class="o">.</span><span class="n">to_sym</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Return a hash with two keys: the route path and it&#39;s verb</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="ss">path</span><span class="p">:</span> <span class="n">path</span><span class="p">,</span> <span class="ss">verb</span><span class="p">:</span> <span class="n">verb</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nb">test</span> <span class="s2">&#34;admin routes should redirect to admin login page&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="n">admin_routes</span> <span class="o">=</span> <span class="no">ROUTES</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span> <span class="o">|</span><span class="n">route</span><span class="o">|</span> <span class="n">route</span><span class="o">[</span><span class="ss">:path</span><span class="o">].</span><span class="n">starts_with?</span> <span class="s2">&#34;/admin&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">insecure_routes</span> <span class="o">=</span> <span class="o">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">admin_routes</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">route</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">      <span class="k">begin</span>
</span></span><span class="line"><span class="cl">        <span class="n">reset!</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Use the route&#39;s verb to access the route&#39;s path</span>
</span></span><span class="line"><span class="cl">        <span class="n">request_via_redirect</span><span class="p">(</span><span class="n">route</span><span class="o">[</span><span class="ss">:verb</span><span class="o">]</span><span class="p">,</span> <span class="n">route</span><span class="o">[</span><span class="ss">:path</span><span class="o">]</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="c1"># If we aren&#39;t redirected to the admin login, the route is insecure</span>
</span></span><span class="line"><span class="cl">        <span class="k">unless</span> <span class="n">path</span> <span class="o">==</span> <span class="n">admin_login_path</span>
</span></span><span class="line"><span class="cl">          <span class="n">insecure_routes</span> <span class="o">&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="n">route</span><span class="o">[</span><span class="ss">:verb</span><span class="o">]</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">route</span><span class="o">[</span><span class="ss">:path</span><span class="o">]</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">rescue</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">RecordNotFound</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Since we are blindly submitting &#34;1&#34; for all route params,</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># this error can pop up. If it does, it means that the request</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># got past the `before_filter` and to the code in the controller</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># where it attempts to locate the record in the database. That</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># means this is an insecure route.</span>
</span></span><span class="line"><span class="cl">        <span class="k">unless</span> <span class="n">path</span> <span class="o">==</span> <span class="n">admin_login_path</span>
</span></span><span class="line"><span class="cl">          <span class="n">insecure_routes</span> <span class="o">&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="n">route</span><span class="o">[</span><span class="ss">:verb</span><span class="o">]</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">route</span><span class="o">[</span><span class="ss">:path</span><span class="o">]</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">rescue</span> <span class="no">AbstractController</span><span class="o">::</span><span class="no">ActionNotFound</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># This error means the route doesn&#39;t connect to a controller</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># action. This is a problem if it happens, but this is a separate</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># concern and should be tested elsewhere. See my previous post</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># about testing for orphaned routes.</span>
</span></span><span class="line"><span class="cl">      <span class="k">end</span>
</span></span><span class="line"><span class="cl">    <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Fail if we have insecure routes.</span>
</span></span><span class="line"><span class="cl">    <span class="n">assert</span> <span class="n">insecure_routes</span><span class="o">.</span><span class="n">empty?</span><span class="p">,</span> <span class="s2">&#34;The following routes are not secure: </span><span class="se">\n\t</span><span class="si">#{</span><span class="n">insecure_routes</span><span class="o">.</span><span class="n">uniq</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n\t</span><span class="s2">&#34;</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span></code></pre></div>]]></content:encoded></item><item><title>Rails: Testing for Orphaned Routes</title><link>https://toasterlovin.com/rails-testing-for-orphaned-routes/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8251</guid><pubDate>Wed, 30 Oct 2013 19:00:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>Over time, one of my large Ruby on Rails apps has accumulated a lot of cruft in it’s routes file. In addition to the normal entropy that accumulates in any large app, I didn’t really have a solid grasp of how routes worked when I started on this app, so it was looking pretty bad.
Well, I recently went through routes.rb and did some major housekeeping. But this app has a bunch of models, with controllers for most of them in both the default namespace and an admin namespace.</description><content:encoded><![CDATA[<p>Over time, one of my large Ruby on Rails apps has accumulated a lot of cruft in it&rsquo;s routes file. In addition to the normal entropy that accumulates in any large app, I didn&rsquo;t really have a solid grasp of how routes worked when I started on this app, so it was looking pretty bad.</p>
<p>Well, I recently went through <code>routes.rb</code> and did some major housekeeping. But this app has a bunch of models, with controllers for most of them in both the default namespace and an admin namespace.</p>
<p>So, even after I had spent the better part of a day cleaning house, my spidey-sense was still tingling. I just didn&rsquo;t feel like I could be <em>sure</em> that everything was copacetic. And I&rsquo;ve learned the hard way that this means it&rsquo;s time for some tests&hellip;</p>
<p>Since routes are the first interface to a web app, I figured a good place to start would be to make sure there were no orphaned routes &ndash; routes that do not lead to a controller action. Also, I wanted a <em>single</em> test that would test <em>all</em> of my routes, so there would be no forgetting to add tests down the road.</p>
<p>Here&rsquo;s that test.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;test_helper&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">OrphanedRoutesTest</span> <span class="o">&lt;</span> <span class="no">ActionDispatch</span><span class="o">::</span><span class="no">IntegrationTest</span>
</span></span><span class="line"><span class="cl">  <span class="no">ROUTES</span> <span class="o">=</span> <span class="no">Rails</span><span class="o">.</span><span class="n">application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">route</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Turn the route path spec into a string:</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># - Remove the &#34;(.:format)&#34; bit at the end</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># - Use &#34;1&#34; for all params</span>
</span></span><span class="line"><span class="cl">    <span class="n">path</span> <span class="o">=</span> <span class="n">route</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">spec</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/\(\.:format\)/</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/:[a-zA-Z_]+/</span><span class="p">,</span> <span class="s2">&#34;1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Route verbs are stored as regular expressions; convert them to symbols</span>
</span></span><span class="line"><span class="cl">    <span class="n">verb</span> <span class="o">=</span> <span class="sx">%W{ GET POST PUT PATCH DELETE }</span><span class="o">.</span><span class="n">grep</span><span class="p">(</span><span class="n">route</span><span class="o">.</span><span class="n">verb</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">downcase</span><span class="o">.</span><span class="n">to_sym</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Return a hash with two keys: the route path and it&#39;s verb</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="ss">path</span><span class="p">:</span> <span class="n">path</span><span class="p">,</span> <span class="ss">verb</span><span class="p">:</span> <span class="n">verb</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nb">test</span> <span class="s2">&#34;no orphaned routes exist&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="n">orphaned_routes</span> <span class="o">=</span> <span class="o">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="no">ROUTES</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">route</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">      <span class="k">begin</span>
</span></span><span class="line"><span class="cl">        <span class="n">reset!</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># Use the route&#39;s verb to access the route&#39;s path</span>
</span></span><span class="line"><span class="cl">        <span class="n">request_via_redirect</span><span class="p">(</span><span class="n">route</span><span class="o">[</span><span class="ss">:verb</span><span class="o">]</span><span class="p">,</span> <span class="n">route</span><span class="o">[</span><span class="ss">:path</span><span class="o">]</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="k">rescue</span> <span class="no">ActionController</span><span class="o">::</span><span class="no">RoutingError</span><span class="p">,</span> <span class="no">AbstractController</span><span class="o">::</span><span class="no">ActionNotFound</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># ActionController::RoutingError means the controller doesn&#39;t exist</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># AbstractController::ActionNotFound means the action doesn&#39;t exist</span>
</span></span><span class="line"><span class="cl">        <span class="n">orphaned_routes</span> <span class="o">&lt;&lt;</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="n">route</span><span class="o">[</span><span class="ss">:verb</span><span class="o">]</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">route</span><span class="o">[</span><span class="ss">:path</span><span class="o">]</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="k">rescue</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">RecordNotFound</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># This error means the controller couldn&#39;t locate the specified record.</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># This happens because we are using 1 for all the route params</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># But, it means that the route points to a valid controller action,</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># so we ignore it</span>
</span></span><span class="line"><span class="cl">      <span class="k">end</span>
</span></span><span class="line"><span class="cl">    <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Fail if we have any orphaned routes</span>
</span></span><span class="line"><span class="cl">    <span class="n">assert</span> <span class="n">orphaned_routes</span><span class="o">.</span><span class="n">empty?</span><span class="p">,</span> <span class="s2">&#34;The following routes lead to nowhere: </span><span class="se">\n\t</span><span class="si">#{</span><span class="n">orphaned_routes</span><span class="o">.</span><span class="n">uniq</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n\t</span><span class="s2">&#34;</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div>]]></content:encoded></item><item><title>Leveling Up Revisited</title><link>https://toasterlovin.com/leveling-up-revisited/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8250</guid><pubDate>Fri, 19 Apr 2013 18:00:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><description>I previously wrote about leveling up as a programmer. At the time, I had forked a list of programming achievements originally belonging to Jason Rudolph and left his list mostly intact.
That was a mistake on my part.
Most of his achievements are pretty high level – the kind of stuff you achieve over the span of an entire career. While it’s vitally important to poke your head above ground every once in a while and make sure you’re headed in the right direction, it turns out that’s not really what I need at the moment.</description><content:encoded><![CDATA[<p>I <a href="https://toasterlovin.com/leveling-up/">previously wrote</a> about leveling up as a programmer. At the time, I had forked a <a href="https://gist.github.com/1133830#file_programming_achievements.md">list of programming achievements</a> originally belonging to <a href="http://jasonrudolph.com/">Jason Rudolph</a> and left his list mostly intact.</p>
<p>That was a mistake on my part.</p>
<p>Most of his achievements are pretty high level &ndash; the kind of stuff you achieve over the span of an entire career. While it&rsquo;s vitally important to poke your head above ground every once in a while and make sure you&rsquo;re headed in the right direction, it turns out that&rsquo;s not really what I need at the moment.</p>
<p>Instead, I&rsquo;m looking to make a list that I will revisit every few weeks or so. For something like that, I find it&rsquo;s more useful to look at things I want to accomplish within a horizon of six months to a year.</p>
<p>So, with that all said, here&rsquo;s what <a href="https://gist.github.com/3974161#file_programming_achievements.md">my list</a> looks like at the time of writing. I removed most of the high level stuff and added in a bunch of skills related to <a href="http://www.ruby-lang.org/">Ruby</a> and <a href="http://rubyonrails.org/">Ruby on Rails</a>.</p>
<h4 id="becomemorefluentinruby">Become more fluent in Ruby</h4>
<ul>
<li>Commit the <a href="http://www.ruby-lang.org/">Ruby</a> syntax to memory</li>
<li>Commit significant standard libraries to memory</li>
<li>Utilize a metaprogramming technique in an app</li>
</ul>
<h4 id="becomemorefluentinrubyonrails">Become more fluent in Ruby on Rails</h4>
<ul>
<li>Use <a href="http://haml.info/">Haml</a> in an app</li>
<li>Use JavaScript in an app <a href="http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html">the Rails way</a></li>
<li>Use <a href="http://coffeescript.org/">Coffeescript</a> in an app</li>
<li>Deploy an app with <a href="http://capistranorb.com/">Capistrano</a></li>
<li>Implement background jobs in an app</li>
<li>Commit form helpers API to memory</li>
<li>Commit ActiveRecord::Migration API to memory</li>
<li>Commit ActiveRecord validation API to memory</li>
</ul>
<h4 id="learnbyteachingothers">Learn by teaching others:</h4>
<ul>
<li>Present at a local user group</li>
<li>Teach at a <a href="http://workshops.railsbridge.org/">RailsBridge</a> workshop</li>
<li>Mentor a new <a href="http://rubyonrails.org/">Rails</a> programmer</li>
</ul>
]]></content:encoded></item><item><title>Leveling Up</title><link>https://toasterlovin.com/leveling-up/</link><guid isPermaLink="false">5ec364f60e3ac71687ab824f</guid><pubDate>Mon, 29 Oct 2012 19:00:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><description>I recently read a blog post by Jason Rudolph about leveling up as a software developer. To paraphrase him, the idea is to:
Identify the experiences that advance a person as a developer. Select a particular experience to pursue. Pursue that experience to completion. (Achievement unlocked!) Reflect on that experience. Really soak it in. Return to Step 2, this time selecting a new experience. This was along a common vein with some things I had been doing, and generally seemed like a good fit for me, since I’m fairly new to programming, so I forked his list and modified it to suit my circumstances:</description><content:encoded><![CDATA[<p>I recently read a blog post by <a href="http://jasonrudolph.com/">Jason Rudolph</a> about <a href="http://jasonrudolph.com/blog/2011/08/09/programming-achievements-how-to-level-up-as-a-developer/">leveling up as a software developer</a>. To paraphrase him, the idea is to:</p>
<blockquote>
<ol>
<li>Identify the experiences that advance a person as a developer.</li>
<li>Select a particular experience to pursue.</li>
<li>Pursue that experience to completion. (Achievement unlocked!)</li>
<li>Reflect on that experience. Really soak it in.</li>
<li>Return to Step 2, this time selecting a new experience.</li>
</ol>
</blockquote>
<p>This was along a common vein with some things I had been doing, and generally seemed like a good fit for me, since <a href="https://toasterlovin.com/returning-to-computation/">I&rsquo;m fairly new to programming</a>, so I forked <a href="https://gist.github.com/1133830#file_programming_achievements.md">his list</a> and <a href="https://gist.github.com/3974161#file_programming_achievements.md">modified it</a> to suit my circumstances:</p>
<h4 id="programinavarietyofdifferentprogrammingparadigms">Program in a variety of different <a href="http://en.wikipedia.org/wiki/Programming_paradigm" title="Programming paradigm - Wikipedia">programming paradigms</a></h4>
<ul>
<li>Write an application in a functional language</li>
<li>Write an application in an object-oriented language</li>
<li>Write an application in a prototype-based language</li>
<li>Write an application in a logic programming language</li>
<li>Write an application using the Actor model</li>
<li>Write an application in Forth</li>
</ul>
<h4 id="programfordifferentplatforms">Program for different platforms:</h4>
<ul>
<li>Write a nontrivial web app</li>
<li>Write a nontrivial desktop app</li>
<li>Write a nontrivial mobile app</li>
</ul>
<h4 id="enhancemyunderstandingofthebuildingblocks">Enhance my understanding of the building blocks:</h4>
<ul>
<li>Use machine learning to solve a problem</li>
<li>Write a networking client (e.g., HTTP, FTP)</li>
<li>Write a B-tree database</li>
<li>Wrap an existing library to provide a better user experience</li>
<li>Write an application or framework that provides a plugin model</li>
<li>Write a testing framework</li>
<li>Write a lexer &amp; parser</li>
</ul>
<h4 id="enlightenmyself">Enlighten myself:</h4>
<ul>
<li>Complete five <a href="http://en.wikipedia.org/wiki/Kata_(programming)" title="Kata (programming) - Wikipedia">code katas</a></li>
<li>Complete the <a href="http://sett.ociweb.com/sett/settJan2011.html" title="Learning Programming Languages with Koans - Object Computing, Inc.">programming koans</a> for a language that you want to learn</li>
<li>Attend a <a href="http://coderetreat.com/" title="Code Retreat with Corey Haines">code retreat</a></li>
<li>Read <a href="http://mitpress.mit.edu/sicp/" title="SICP web site">SICP</a> and complete all the exercises</li>
</ul>
<h4 id="programintheopen">Program in the open:</h4>
<ul>
<li><del>Contribute to an open source project</del> (<a href="https://github.com/sproutcore/guides/pull/122">Added three words of documentation</a>. Ha!)</li>
<li>Have a patch accepted at an open source project</li>
<li>Earn commit rights on a significant open source project</li>
<li>Publish an open source project</li>
<li>Perform a <a href="http://thinkrelevance.com/blog/2007/04/03/twir.html" title="Refactotum">Refactotum</a> of an open source project</li>
</ul>
<h4 id="learnbyteachingothers">Learn by teaching others:</h4>
<ul>
<li>Present a lightning talk</li>
<li>Present at a local user group</li>
<li>Present at a conference</li>
<li>Publish a tutorial</li>
<li>Publish a constructive code review of an open source project</li>
</ul>
<p>EDIT: I have since <a href="https://toasterlovin.com/leveling-up-revisited/">updated this list</a>.</p>
]]></content:encoded></item><item><title>Rails: Is the Attribute Actually Optional?</title><link>https://toasterlovin.com/rails-is-the-attribute-actually-optional/</link><guid isPermaLink="false">5ec364f60e3ac71687ab824e</guid><pubDate>Sat, 01 Sep 2012 18:00:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>Ruby on Rails model attributes are optional by default. That is, unless you specify otherwise, an attribute is not required for a model instance to be valid. I like to test that this is, in fact, the case.
test "weight is not required" do assert @product.valid?, "product should be valid to begin with" @product.weight = nil assert @product.valid?, "product should still be valid" end This might seem too trivial to test, or like we’re testing core Rails functionality, but an optional attribute is a feature of your application. In other words, it’s easy for parts of your app to depend on an attribute being optional, which means it’s easy to break something by making that attribute required down the road.</description><content:encoded><![CDATA[<p>Ruby on Rails model attributes are optional by default. That is, unless you specify otherwise, an attribute is <em>not</em> required for a model instance to be valid. I like to test that this is, in fact, the case.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="nb">test</span> <span class="s2">&#34;weight is not required&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="vi">@product</span><span class="o">.</span><span class="n">valid?</span><span class="p">,</span> <span class="s2">&#34;product should be valid to begin with&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@product</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="vi">@product</span><span class="o">.</span><span class="n">valid?</span><span class="p">,</span> <span class="s2">&#34;product should still be valid&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>This might seem too trivial to test, or like we&rsquo;re testing core Rails functionality, but <strong>an optional attribute is a feature of your application</strong>. In other words, it&rsquo;s easy for parts of your app to depend on an attribute being <em>optional</em>, which means it&rsquo;s easy to break something by making that attribute <em>required</em> down the road.</p>
<!-- more -->
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CreateProducts</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Migration</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">change</span>
</span></span><span class="line"><span class="cl">    <span class="n">create_table</span> <span class="ss">:products</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">      <span class="n">t</span><span class="o">.</span><span class="n">text</span> <span class="ss">:name</span>
</span></span><span class="line"><span class="cl">      <span class="n">t</span><span class="o">.</span><span class="n">decimal</span> <span class="ss">:weight</span>
</span></span><span class="line"><span class="cl">    <span class="k">end</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ProductTest</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">TestCase</span>
</span></span><span class="line"><span class="cl">  <span class="nb">test</span> <span class="s2">&#34;name is required&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="vi">@product</span> <span class="o">=</span> <span class="n">products</span><span class="p">(</span><span class="ss">:one</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="vi">@product</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">    <span class="n">assert</span> <span class="o">!</span><span class="vi">@product</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Product</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">presence</span><span class="p">:</span> <span class="kp">true</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Here we have a model with two attributes: <code>name</code>, which is required, and <code>weight</code>, which is optional. We also have a test to make sure that <code>name</code> is required. Now we decide that the <code>weight</code> attribute shouldn&rsquo;t accept negative numbers, so we add a test and modify the model.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ProductTest</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># more tests</span>
</span></span><span class="line"><span class="cl">  <span class="nb">test</span> <span class="s2">&#34;weight should not be negative&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="vi">@product</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="o">-</span><span class="mi">5</span><span class="o">.</span><span class="mi">4</span>
</span></span><span class="line"><span class="cl">    <span class="n">assert</span> <span class="o">!</span><span class="vi">@product</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Product</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">presence</span><span class="p">:</span> <span class="kp">true</span>
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:weight</span><span class="p">,</span> <span class="ss">numericality</span><span class="p">:</span> <span class="p">{</span> <span class="ss">greater_than_or_equal_to</span><span class="p">:</span> <span class="mi">0</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Easy enough, right? Nope! We just make a small but insidious mistake.</p>
<p>First, because we didn&rsquo;t add <code>allow_nil: true</code> to the <code>numericality</code> validation, <code>weight</code> is now required, but that&rsquo;s not what we wanted to do. We just need to make sure <code>weight</code> isn&rsquo;t a negative number; it should still be optional.</p>
<p>Okay, that&rsquo;s not too bad; we might have caught it if it broke some of our other tests. Something else is much more diconcerting; if we&rsquo;re using a fixture without the <code>weight</code> attribute set, the <code>&quot;name is required&quot;</code> test <strong>isn&rsquo;t actually testing anything</strong>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">one</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Cat 5e</span><span class="w">
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Product</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># validates :name, presence: true</span>
</span></span><span class="line"><span class="cl">  <span class="n">validates</span> <span class="ss">:weight</span><span class="p">,</span> <span class="ss">numericality</span><span class="p">:</span> <span class="p">{</span> <span class="ss">greater_than_or_equal_to</span><span class="p">:</span> <span class="mi">0</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Boom! Both of our tests still pass, but we&rsquo;re clearly not validating that <code>name</code> is required. This should strike fear into your heart; we have a reasonable looking situation that completely fails to do what we expect. In other words, we have built our app on top of quicksand. Maybe it&rsquo;s time to tweak our testing methodology.</p>
<p>There are two ways we could have caught this bug. First, we could have <a href="https://toasterlovin.com/are-the-fixtures-valid/">validated our fixtures</a>, which is good hygiene but kind of a separate issue. Second, we could have tested that our optional attribute was actually optional. We&rsquo;ll focus on this second one.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="nb">test</span> <span class="s2">&#34;weight is not required&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="vi">@product</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@product</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="vi">@product</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Look familiar? This test is how we got this whole blog post started. More importantly, it will start a chain of failing tests that, as we cause them to pass, lead us back to code which does what we expect it to do.</p>
<p>It&rsquo;s kinda wordy for my taste though, and will result in egregious violation of the Don&rsquo;t Repeat Yourself (DRY) principle, especially if we have <em>a bunch</em> of optional attributes. Why not create a helper method so we can test <em>all</em> of our optional attributes in one fell swoop?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ActiveSupport</span><span class="o">::</span><span class="no">TestCase</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># some other stuff</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">test_optional_attribute</span><span class="p">(</span><span class="n">fixture_name</span><span class="p">,</span> <span class="o">*</span><span class="n">attrs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">attrs</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="kp">attr</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">      <span class="nb">test</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="kp">attr</span><span class="si">}</span><span class="s2"> is optional&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">        <span class="n">fixture</span> <span class="o">=</span> <span class="nb">instance_variable_get</span><span class="p">(</span><span class="s2">&#34;@</span><span class="si">#{</span><span class="n">fixture_name</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">assert</span> <span class="n">fixture</span><span class="o">.</span><span class="n">valid?</span><span class="p">,</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="n">fixture</span><span class="si">}</span><span class="s2"> isn&#39;t a valid fixture&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">fixture</span><span class="o">.</span><span class="n">send</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="kp">attr</span><span class="si">}</span><span class="s2">=&#34;</span><span class="p">,</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">        <span class="n">assert</span> <span class="n">fixture</span><span class="o">.</span><span class="n">valid?</span><span class="p">,</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="kp">attr</span><span class="si">}</span><span class="s2"> should be optional&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="k">end</span>
</span></span><span class="line"><span class="cl">    <span class="k">end</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Now we have a nice, succinct way to test all of our optional attributes in a single line of code.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ProductTest</span> <span class="o">&lt;</span> <span class="no">ActiveSupport</span><span class="o">::</span><span class="no">TestCase</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># other tests</span>
</span></span><span class="line"><span class="cl">  <span class="n">test_optional_attribute</span> <span class="ss">:product</span><span class="p">,</span> <span class="ss">:weight</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Maybe this all sounds like paranoia to you, but mistakes like this one are shockingly easy to make. Indeed, this is the reason we do any testing at all; we humans, with our inconsistency and tendency toward errors, and computers, with their unforgiving precision, are like oil and water; we don&rsquo;t mix.</p>
<p>And yet, here we are anyway, trying to master computation. Rather than pretend that humans and computers aren&rsquo;t fundamentally incompatible, embrace it. Go all the way. <strong>Test every single assumption.</strong> Just be smart about it; make it easy and succint. Make it joyful.</p>
]]></content:encoded></item><item><title>Rails: Are the Fixtures Valid?</title><link>https://toasterlovin.com/rails-are-the-fixtures-valid/</link><guid isPermaLink="false">5ec364f60e3ac71687ab824d</guid><pubDate>Sat, 18 Aug 2012 18:00:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><category>Ruby on Rails</category><description>A common pattern in my Ruby on Rails unit tests is to start with a valid instance of a model, make a change to the attribute I’m testing, then assert that the model instance is no longer valid.
test "weight is required" do @prod_one = products(:one) @prod_one.weight = nil assert !@prod_one.valid? end Simple enough; I don’t think we’re treading new ground here. The problem is that this test assumes the fixture is valid. If the fixture isn’t valid, the test will still pass, but it won’t actually be testing anything. Yikes! Better to assert that the fixture is valid.</description><content:encoded><![CDATA[<p>A common pattern in my Ruby on Rails unit tests is to start with a valid instance of a model, make a change to the attribute I&rsquo;m testing, then assert that the model instance is no longer valid.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="nb">test</span> <span class="s2">&#34;weight is required&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@prod_one</span> <span class="o">=</span> <span class="n">products</span><span class="p">(</span><span class="ss">:one</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@prod_one</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="o">!</span><span class="vi">@prod_one</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Simple enough; I don&rsquo;t think we&rsquo;re treading new ground here. The problem is that this test assumes the fixture is valid. <strong>If the fixture isn&rsquo;t valid, the test will still pass, but it won&rsquo;t actually be testing anything</strong>. Yikes! Better to assert that the fixture is valid.</p>
<!-- more -->
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="nb">test</span> <span class="s2">&#34;weight is required&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@prod_one</span> <span class="o">=</span> <span class="n">products</span><span class="p">(</span><span class="ss">:one</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="vi">@prod_one</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@prod_one</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="o">!</span><span class="vi">@prod_one</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>That&rsquo;s definitely better, but we&rsquo;ve got a bunch of tests to write; it&rsquo;s going to be tiresome (and error-prone) to have to assert the validity of our fixtures in each test. Plus, we want to keep our tests laser focused on what they&rsquo;re actually testing. Why not just get it all out of the way at once?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">setup</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@prod_one</span> <span class="o">=</span> <span class="n">products</span><span class="p">(</span><span class="ss">:one</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">test</span> <span class="s2">&#34;fixtures are valid&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="vi">@prod_one</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">test</span> <span class="s2">&#34;weight is required&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="vi">@prod_one</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">  <span class="n">assert</span> <span class="o">!</span><span class="vi">@prod_one</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Look at how tight that test is. There&rsquo;s nothing in there to distract you from immediately comprehending what&rsquo;s being tested. Truly a thing of beauty. There <em>is</em> still one thing that&rsquo;s bothering me though&hellip;</p>
<p>We&rsquo;re going to be testing our fixtures this way a lot &ndash; at least once for each unit and functional test class. It&rsquo;s tiresome to actually have to write an entire test each time we want to do this. Why not just write a helper method so we can turn this into a one liner?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ActiveSupport</span><span class="o">::</span><span class="no">TestCase</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># some other stuff</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">test_valid_fixture</span><span class="p">(</span><span class="o">*</span><span class="n">fixts</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">fixts</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">fixture</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">      <span class="nb">test</span> <span class="s2">&#34;@</span><span class="si">#{</span><span class="n">fixture</span><span class="si">}</span><span class="s2"> fixture is valid&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">        <span class="n">fixture</span> <span class="o">=</span> <span class="nb">instance_variable_get</span><span class="p">(</span><span class="s2">&#34;@</span><span class="si">#{</span><span class="n">fixture</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">assert</span> <span class="n">fixture</span><span class="o">.</span><span class="n">valid?</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;Fixture is invalid: </span><span class="si">#{</span><span class="n">fixture</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">full_messages</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="k">end</span>
</span></span><span class="line"><span class="cl">    <span class="k">end</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Now we can be concise and expressive in our test class, which allows us to conserve our brainpower for where it&rsquo;s really needed.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ProductTest</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">TestCase</span>
</span></span><span class="line"><span class="cl">  <span class="n">setup</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="vi">@prod_one</span> <span class="o">=</span> <span class="n">products</span><span class="p">(</span><span class="ss">:one</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="vi">@prod_two</span> <span class="o">=</span> <span class="n">products</span><span class="p">(</span><span class="ss">:two</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">test_valid_fixture</span> <span class="ss">:prod_one</span><span class="p">,</span> <span class="ss">:prod_two</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nb">test</span> <span class="s2">&#34;weight is required&#34;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    <span class="vi">@prod_one</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">    <span class="n">assert</span> <span class="o">!</span><span class="vi">@prod_one</span><span class="o">.</span><span class="n">valid?</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div>]]></content:encoded></item><item><title>Returning to Computation</title><link>https://toasterlovin.com/returning-to-computation/</link><guid isPermaLink="false">5ec364f60e3ac71687ab824c</guid><pubDate>Wed, 11 Jul 2012 18:00:00 +0000</pubDate><dc:creator>Richard Jones</dc:creator><description>Way back in the day, when I was in college, I took a class on basic programming with C++. I only did okay in that class, but the concepts really stuck. There was something about decomposing work into it’s fundamental units – variables, conditionals and loops – that struck me as true.
It was one of those things, a Fundamental Truth About The Universe, like that genes, not organisms, are the basic units of reproduction; or that evolution, not the id, is what explains human behaviour. One of those “Aha!” moments when the haze of confusion is swept away and suddenly everything makes sense.</description><content:encoded><![CDATA[<p>Way back in the day, when I was in college, I took a class on basic programming with C++. I only did <em>okay</em> in that class, but the concepts really stuck. There was something about decomposing work into it&rsquo;s fundamental units &ndash; variables, conditionals and loops &ndash; that struck me as <em>true</em>.</p>
<p>It was one of those things, a Fundamental Truth About The Universe, like that <a href="http://en.wikipedia.org/wiki/The_Selfish_Gene" title="The Selfish Gene">genes, not organisms, are the basic units of reproduction</a>; or that <a href="http://en.wikipedia.org/wiki/Evolutionary_psychology" title="Evolutionary Psychology">evolution, not the id, is what explains human behaviour</a>. One of those &ldquo;Aha!&rdquo; moments when the haze of confusion is swept away and suddenly <em>everything makes sense</em>.</p>
<p>And so my eyes were opened a little wider.</p>
<h3 id="wanderingoffintothewilderness">Wandering off into the wilderness</h3>
<p>Anybody else, coming across a subject which they found so compelling, and which also offered lucrative career opportunities, would have made an immediate course change. But I was missing a couple of crucial skills:</p>
<ol>
<li>Setting goals for myself</li>
<li>Making plans to achieve those goals</li>
<li>Executing said plans</li>
</ol>
<p>So this beautiful, golden opportunity floated right past me while I was busy taking the path of least resistance.</p>
<p>Soon, though, it became apparent to me that I needed to learn how to accomplish things, and so began the multiyear process of pulling myself up by the bootstraps: learning how to set goals, make plans and execute on those plans by setting a goal, making a plan and executing on that plan.</p>
<h3 id="findingmywayback">Finding my way back</h3>
<p>And once I was started in a different direction, the momentum of life kept me going in that direction for a good long while. All told, it took 8 years for programming to find it&rsquo;s way back into my life.</p>
<p>It started off so innocuously. We needed a better way to manage ordering from our overseas factories. We had an Excel spreadsheet listing all of our current products.</p>
<hr>
<p>&ldquo;Yo Bossman, check this out,&rdquo; says Rico. &ldquo;I added our current inventory and monthly sales numbers to the product spreadsheet, then wrote a simple formula to calculate how much of each product we need to buy.&rdquo;</p>
<p>&ldquo;Sweet, that should save us a bunch of time,&rdquo; replies The Bossman, &ldquo;but it&rsquo;s kinda confusing. Is there a way to only show a quantity for the products we <em>do</em> need to order and leave the others blank?&rdquo;</p>
<p>&ldquo;Yeah, I&rsquo;m sure Excel can do that,&rdquo; says Rico as he Googles around a bit. &ldquo;Hmmm, this should work: <code>IF(QuantityToBuy=0, &quot;&quot;, QuantityToBuy)</code>.&rdquo;</p>
<hr>
<p>Woah! A conditional. It&rsquo;s kind of a weird one &ndash; <code>if</code> <a href="https://support.office.com/en-us/article/IF-function-69aed7c9-4e8a-4755-a9bc-aa8bbff73be2">looks like a call to a function</a>, instead of <a href="http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Companion/cxx_crib/if_arglist.html">how I remember it</a> &ndash; but it&rsquo;s a conditional nonetheless.</p>
<h3 id="buildingahomeformyself">Building a home for myself</h3>
<p>Making software with Excel turned out to be alternately deeply strange and downright blissful, but it marked the beginning of my return to Computation. The next big step was converting my company&rsquo;s <code>&lt;table&gt;</code> &amp; <code>&lt;img&gt;</code> based website to an HTML &amp; CSS based design.</p>
<p>This is the point where things really start to go fractal. It starts with selector specificity. Then it&rsquo;s the CSS box model. Then semantic markup. Soon I realize that I need something to handle templating for the website. Now it&rsquo;s Wordpress and writing little snippets of PHP. Oh, and JQuery happened somewhere in there too.</p>
<p>The thing is, it just doesn&rsquo;t stop. Soon I&rsquo;m making command line utilites and Coda plugins in Perl. Somewhere along the way I start using MacVim. And Git. Then command line Vim + tmux. And regular expressions, object oriented programming, recursion and Big O notation.</p>
<p>Then I get started with Ruby on Rails, so it&rsquo;s models, views, controllers, migrations, ActiveRecord, partials, REST, routes, HAML, SASS, YAML, unit testing, integration testing, Rake, Capistrano.</p>
<p>It&rsquo;s insane how much stuff you need to cram into your brain to be a decent web developer, and yet web development is just one tiny facet of the whole of Computation; a facet which <em>isn&rsquo;t even that interesting</em>.</p>
<p>Where things get really interesting is when you begin to realize that <a href="http://en.wikipedia.org/wiki/Digital_physics" title="Digital Physics - Wikipedia.org">computation is every where</a>, that there are other, <a href="http://edge.org/conversation/ants-have-algorithms" title="Ants Have Algorithms - Iain Couzin at Edge.org (video &amp; transcript)">very different forms of computation</a>, and that some of those are <a href="http://groups.csail.mit.edu/mac/users/gjs/6.945/readings/robust-systems.pdf" title="Building Robust Systems - Gerald Jay Sussman">way better at certain tasks than what we have now</a>.</p>
<p>Thinking about all these things to learn, I can&rsquo;t help but remark to myself, &ldquo;There&rsquo;s a whole lifetime of work in there for me.&rdquo;</p>
<p>What a thought!</p>
]]></content:encoded></item></channel></rss>