<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[A Journal of Technical Matters]]></title><description><![CDATA[by Richard Jones]]></description><link>https://toasterlovin.com/</link><image><url>https://toasterlovin.com/favicon.png</url><title>A Journal of Technical Matters</title><link>https://toasterlovin.com/</link></image><generator>Ghost 3.16</generator><lastBuildDate>Tue, 24 Mar 2026 10:41:36 GMT</lastBuildDate><atom:link href="https://toasterlovin.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Extending rails.vim Navigation Commands with projectionist.vim]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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'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></p>]]></description><link>https://toasterlovin.com/extending-rails-vim-navigation-commands-with-projectionist-vim/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8260</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[Vim]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Wed, 17 Jan 2018 05:35:26 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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'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'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's a sign that you'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't have handy navigation commands for them. But that's okay, because it'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'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's what that file looks like on one of my projects, where it's adding navigation commands for workers and presenters:</p>
<pre><code>{
  &quot;app/workers/*_worker.rb&quot;: {&quot;type&quot;: &quot;worker&quot;},
  &quot;app/presenters/*_presenter.rb&quot;: {&quot;type&quot;: &quot;presenter&quot;}
}
</code></pre>
<p>You can see that it'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'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's it!</p>
<p>Well, I'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'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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Using the PTY Class to Test Interactive CLI Apps in Ruby]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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'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></p>]]></description><link>https://toasterlovin.com/using-the-pty-class-to-test-interactive-cli-apps-in-ruby/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825f</guid><category><![CDATA[Ruby]]></category><category><![CDATA[CLI]]></category><category><![CDATA[Testing]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Wed, 28 Jun 2017 21:58:05 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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'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>
<pre><code>$ rpn_party
&gt; 3 2 +
5.0
&gt; 6 -
-1.0
&gt; q
$
</code></pre>
<p>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 <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'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's <code>stdin</code> and <code>gets</code> to read from it's <code>stdout</code>. You can read the documentation for PTY, but it probably won'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's okay if you don't, though, because using <code>PTY</code> to interact with command line apps is pretty simple:</p>
<pre><code>PTY.spawn('path/to/executable') do |stdout, stdin, pid|
  stdin.puts 'some command'
  stdout.gets

  response = stdout.gets
  assert_equal 'expected response', response
end
</code></pre>
<p>Here's what's going on in this chunk of code:</p>
<ol>
<li>We're calling the <code>spawn</code> class method on the <code>PTY</code> class.</li>
<li>We'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's <code>stdin</code>.</li>
<li>Then we are consuming one line of text from the process's <code>stdout</code>. We have to do this because our input from the previous line is echoed to the process's <code>stdout</code>, so we need to consume that before we can get to the actual response. I'll go into more detail on this down below.</li>
<li>Then, in the next two lines, we are getting the process's response and asserting that it is the value we are expecting.</li>
</ol>
<p>That'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't, the user wouldn't be able to see what they were typing. There are some cases where input doesn't get echoed to <code>stdout</code>, though, like when a user is typing a password.</p>
<p>This isn'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's what that looked like:</p>
<pre><code>def send_command(pty, command)
  pty[1].puts command
  pty[0].gets
end
</code></pre>
<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>
<pre><code>PTY.spawn('path/to/executable') do |stdout, stdin, pid|
  pty = stdout, stdin, pid
end
</code></pre>
<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'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'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>
<pre><code>PTY.spawn('bin/rpn_party') do |output, input, pid|
  stdin.puts 'exit'
  assert PTY.check(pid)
end
</code></pre>
<p>Here we'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'm not a systems programmer, so I will assume that I'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>
<pre><code>PTY.spawn('path/to/executable') do |stdout, stdin, pid|
  # send a command and clear it from stdout
  response = stdout.gets
  assert_equal 'expected response', response
end
</code></pre>
<p>What'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'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>
<pre><code>PTY.spawn('path/to/executable') do |stdout, stdin, pid|
  # send a command and clear it from stdout
  sleep 0.1
  response = stdout.gets
  assert_equal 'expected response', response
end
</code></pre>
<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>
<pre><code>def get_response(stdout)
  start = Time.now
  try_for = 2
  response = nil

  loop do
    response = stdout.gets.chomp
    break if response || Time.now &gt; start + try_for

    sleep 0.1
  end

  response
end
</code></pre>
<p>What'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>
<pre><code>$ rpn_party
&gt; commmand
result
&gt;
</code></pre>
<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's <code>stdout</code> has printed the <code>&gt;</code> after the last command. Say you have a test like this:</p>
<pre><code>PTY.spawn('path/to/executable') do |stdout, stdin, pid|
  stdin.puts 'command1'
  response1 = stdout.gets

  stdin.puts 'command2'
  response2 = stdout.gets
  assert_equal 'response2', response     # fails sometimes
end
</code></pre>
<p>This assertion will sometimes fails in a not so obvious way (because reasoning about async is hard). When it does fail, you'll get a message like:</p>
<pre><code>Expected &quot;response2&quot;
Actual   &quot;&gt; response2&quot;
</code></pre>
<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'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's best to wrap this up in a method, like so:</p>
<pre><code>def wait_for_prompt(stdout)
  start = Time.now
  try_for = 1

  loop do
    prompt = stdout.getc
    break if prompt == '&gt;' || Time.now &gt; start + try_for

    sleep 0.1
  end
end
</code></pre>
<hr>
<p>And there you go. Now you can integration test your CLI apps.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Webcal Links in Rails with the icalendar Gem]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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'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'd would go ahead and</p>]]></description><link>https://toasterlovin.com/rails-webcal-links-with-icalendar-gem/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825e</guid><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Sun, 11 Jun 2017 18:35:36 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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'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'd would go ahead and document that myself.</p>
<p><em>Before I get started, I'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.herokuapp.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>
<p><img src="https://toasterlovin.com/content/images/2017/06/Screen-Shot-2017-06-11-at-09.54.00.png" alt></p>
<p>Then you click <em>Subscribe</em> and, voilà, now that power lunch you have scheduled is in your calendar:</p>
<p><img src="https://toasterlovin.com/content/images/2017/06/Screen-Shot-2017-06-11-at-09.55.11.png" alt></p>
<p>In the future, your calendar app will periodically poll the calendar's URL to check for updates.</p>
<h2 id="controller">Controller</h2>
<p>Here's what your controller should look like:</p>
<pre><code>class CalendarsController &lt; ApplicationController
  def show
    respond_to do |format|
      format.ics do
        cal = Icalendar::Calendar.new
        cal.x_wr_calname = 'Awesome Rails Calendar'
        cal.event do |e|
          e.dtstart     = DateTime.now + 2.hours
          e.dtend       = DateTime.now + 3.hours
          e.summary     = 'Power Lunch'
          e.description = 'Get together and do big things'
        end
        cal.publish
        render plain: cal.to_ical
      end
    end
  end
end
</code></pre>
<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'll highlight the important parts:</p>
<ol>
<li>
<p>Your controller needs to be unauthenticated, or else the user's calendar app won'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'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'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's all standard stuff.</p>
<h1 id="link">Link</h1>
<p>Here's what your subscription link should look like:</p>
<pre><code>&lt;%= link_to 'Subscribe', calendar_url(protocol: :webcal, format: :ics) %&gt;
</code></pre>
<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'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's calendar app won't know the domain. So, in this example, we'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'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's it, you'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.herokuapp.com/calendar">see it in action on Heroku</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Greatest-Per-Group Query in Rails Using a View Backed Model]]></title><description><![CDATA[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><link>https://toasterlovin.com/greatest-per-group-rails-view-backed-model/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825d</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[PostgreSQL]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Sun, 03 Apr 2016 16:48:50 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><em>This is part 4 of 4 in a series on how to use Greatest Per Group queries in Ruby on Rails to avoid the N + 1 query problem:</em></p>
<ol>
<li><em><a href="https://toasterlovin.com/greatest-per-group-postgresql-distinct-on/">When and how to use Greatest Per Group queries (with PostgreSQL)</a></em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/">Rails implementation using custom query methods</a></em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/">Rails implementation using a scoped <code>has_one</code> relation</a></em></li>
<li><em>Rails implementation using a view backed model</em></li>
</ol>
<p><em>Everything has been tested with Rails 4.2 and PostgreSQL. See <a href="http://rails-greatest-per-group.herokuapp.com">demonstration app</a> and <a href="https://github.com/toasterlovin/rails-greatest-per-group">it's source code</a></em></p>
<hr>
<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'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'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't worry if that seems a little fuzzy to you, because we're about to make it more concrete by applying it to our Greatest Per Group problem.</p>
<p>Let'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>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN (SELECT DISTINCT ON (author_id) *
           FROM posts
           ORDER BY author_id, created_at DESC)
           AS newest_posts
ON newest_posts.author_id = authors.id
</code></pre>
<p>Working from the inside out, what we'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's how we create that database view:</p>
<pre><code>CREATE VIEW newest_posts AS
  SELECT DISTINCT ON (author_id) *
  FROM posts
  ORDER BY author_id, created_at DESC
</code></pre>
<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>
<pre><code>SELECT * FROM newest_posts
</code></pre>
<p>And to get the newest post for a specific author, we can do:</p>
<pre><code>SELECT * FROM newest_posts WHERE author_id = 42
</code></pre>
<p>Or, if we want to accomplish our original query from above, we can do:</p>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN newest_posts
ON newest_posts.author_id = authors.id
</code></pre>
<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's fairly easy to hit the edge of how well ActiveRecord maps to what you'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'll create ours in a migration:</p>
<pre><code>class CreateNewestPostsView &lt; ActiveRecord::Migration
  def up
    execute &lt;&lt;-sql
      CREATE VIEW newest_posts AS
        SELECT DISTINCT ON (author_id) *
        FROM posts
        ORDER BY author_id, created_at DESC
    sql
  end

  def down
    execute &lt;&lt;-sql
      DROP VIEW newest_posts
    sql
  end
end
</code></pre>
<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'll get to that in a bit):</p>
<pre><code>class NewestPost &lt; ActiveRecord::Base
end
</code></pre>
<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>
<pre><code>NewestPost.all
</code></pre>
<p>Rails will generate SQL like:</p>
<pre><code>SELECT * FROM newest_posts;
</code></pre>
<p>But PostgreSQL will actually do:</p>
<pre><code>SELECT *
FROM (SELECT DISTINCT ON (author_id) *
      FROM posts
      ORDER BY author_id, created_at DESC)
</code></pre>
<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>
<pre><code>class NewestPost &lt; ActiveRecord::Base
  belongs_to :author
end
</code></pre>
<p>Then we can create the corresponding <code>has_one</code> association in our <code>Author</code> model:</p>
<pre><code>class Author &lt; ActiveRecord::Base
  has_many :posts
  has_one :newest_post
end
</code></pre>
<p>And now we have a normal ActiveRecord association that we can use for eager loading:</p>
<pre><code>@authors = Author.includes(:newest_post)
@authors.each do |author|
  puts &quot;#{author.name}'s latest post: #{author.newest_post.title}&quot;
end
</code></pre>
<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'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>'s handy methods (like <code>create_table</code> or <code>add_index</code>). That's because Rails doesn'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'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't have any database views. Which is probably not what you want if you're trying to use views in your Rails app.</p>
<p>That'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'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'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'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's pretty simple. In <code>config/application.rb</code>, you change this line:</p>
<pre><code>config.active_record.schema_format = :ruby
</code></pre>
<p>to:</p>
<pre><code>config.active_record.schema_format = :sql
</code></pre>
<p>You'll probably want to delete your <code>schema.rb</code> file, too.</p>
<p>And that'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'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're derived from. That's a bit much to digest, so let me explain it with some code.</p>
<p>Let's grab a <code>NewestPost</code>:</p>
<pre><code>@newest_post = NewestPost.first
</code></pre>
<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>
<pre><code>CREATE VIEW newest_posts AS
  SELECT DISTINCT ON (author_id) *
  FROM posts
  ORDER BY author_id, created_at DESC
</code></pre>
<p>The data from those columns is available on instances of <code>NewestPost</code>. So we can do:</p>
<pre><code>@newest_post.title
@newest_post.body
@newest_post.created_at
</code></pre>
<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>
<pre><code>@newest_post.comments
</code></pre>
<p>It will not work.</p>
<p>It's easy to start thinking of instances of <code>NewestPost</code> as instances of <code>Post</code>, since that'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, &quot;Aha, but this is easy to solve. I'll just make <code>NewestPost</code> inherit from <code>Post</code> and then it'll have access to all of the methods and associations defined on <code>Post</code>.&quot;</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'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>
<pre><code>@newest_post.becomes(Post)
</code></pre>
<p>Which is more or less the equivalent of doing:</p>
<pre><code>Post.new(@newest_post.attributes)
</code></pre>
<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>
<pre><code>@newest_post.becomes(Post).comments
</code></pre>
<p>So there you go. It'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's it. Now you know way more than you ever wanted to about this strange little corner of the Rails world.</em></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Greatest-Per-Group Query in Rails Using a Scoped has_one Assocation]]></title><description><![CDATA[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><link>https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825c</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[PostgreSQL]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Wed, 10 Feb 2016 07:29:44 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><em>This is part 3 of 4 in a series on how to use Greatest Per Group queries in Ruby on Rails to avoid the N + 1 query problem:</em></p>
<ol>
<li><em><a href="https://toasterlovin.com/greatest-per-group-postgresql-distinct-on/">When and how to use Greatest Per Group queries (with PostgreSQL)</a></em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/">Rails implementation using custom query methods</a></em></li>
<li><em>Rails implementation using a scoped <code>has_one</code> relation</em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-view-backed-model/">Rails implementation using a view backed model</a></em></li>
</ol>
<p><em>Everything has been tested with Rails 4.2 and PostgreSQL. See <a href="http://rails-greatest-per-group.herokuapp.com">demonstration app</a> and <a href="https://github.com/toasterlovin/rails-greatest-per-group">it's source code</a></em></p>
<hr>
<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'll cover an approach that makes up for those limitations <em>and</em> brings some extra benefits to the table.</p>
<h2 id="ascopedhas_oneassociation">A scoped <code>has_one</code> association</h2>
<p>We'll need our Greatest Per Group query from Part 1 fresh in our heads for this next part, so here it is again:</p>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN (SELECT DISTINCT ON (author_id) *
           FROM posts
           ORDER BY author_id, created_at DESC)
           AS newest_posts
ON newest_posts.author_id = authors.id
</code></pre>
<p>There are three things happening in this query:</p>
<ol>
<li>We're creating a temporary <code>newest_posts</code> table that returns a single post – the newest one – for each author.</li>
<li>Then, we're joining this temporary table to our <code>authors</code> table on <code>authors.id = newest_posts.author_id</code>.</li>
<li>Finally, we're selecting some data from that <code>newest_posts</code> table to return along with our author data.</li>
</ol>
<p>Let's forget about the third item – selecting the data – for now and instead focus on the first two.</p>
<p>We're creating a table that has a single row per author and we'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'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's our subquery again:</p>
<pre><code>SELECT DISTINCT ON (author_id) *
FROM posts
ORDER BY author_id, created_at DESC
</code></pre>
<p>Luckily, Rails allows us to customize – to <em>scope</em> – the query used for a <code>has_one</code> association. Here's how we do that with our subquery:</p>
<pre><code>class Author
  has_many :posts
  has_one :newest_post, -&gt; {
    select(&quot;DISTINCT ON (author_id) *&quot;)
    .order(:author_id, created_at: :desc)
  }, class_name: &quot;Post&quot;
</code></pre>
<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>
<pre><code>@authors = Author.includes(:newest_post).all
@authors.each do |author|
  puts &quot;Newest post for #{author.full_name}: #{author.newest_post.title}&quot;
end
</code></pre>
<p>And it only fires off two queries.</p>
<h2 id="whythisapproachisawesome">Why this approach is awesome</h2>
<p>Let's compare and contrast. Here's how we achieved this with custom query methods:</p>
<pre><code>@authors = Author
  .select(&quot;authors.*,
           newest_posts.title AS newest_post_title&quot;)
  .joins(&quot;LEFT JOIN (SELECT DISTINCT ON (author_id) *
                     FROM posts
                     ORDER BY author_id, created_at DESC)
          AS newest_posts ON newest_posts.author_id = authors.id&quot;)
</code></pre>
<p>And here's what we just did:</p>
<pre><code>class Author
  has_many :posts
  has_one :newest_post, -&gt; {
    select(&quot;DISTINCT ON (author_id) *&quot;)
    .order(:author_id, created_at: :desc)
  }, class_name: &quot;Post&quot;
</code></pre>
<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'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't very composable. If you abstract them away behind named scopes, you can'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's say we also wanted an <code>oldest_post</code> association:</p>
<pre><code>class Author
  has_many :posts
  has_one :newest_post, -&gt; {
    select(&quot;DISTINCT ON (author_id) *&quot;)
    .order(:author_id, created_at: :desc)
  }, class_name: &quot;Post&quot;
  has_one :oldest_post, -&gt; {
    select(&quot;DISTINCT ON (author_id) *&quot;)
    .order(:author_id, created_at: :asc)
  }, class_name: &quot;Post&quot;
</code></pre>
<p>This allows us to do something like this:</p>
<pre><code>@authors = Author.includes(:newest_post, :oldest_post)
@authors.each do |author|
  puts &quot;Newest post for #{author.name}: #{author.newest_post.title}&quot;
  puts &quot;#{author.name} first posted on #{author.oldest_post.date}&quot;
end
</code></pre>
<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'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've set these up as <code>has_one</code> assocations – and that's really what they were all along; an author'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'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's simple. We can use our new <code>has_one</code> relations with <code>joins</code>:</p>
<pre><code>@authors = Author.joins(:newest_post)
@authors.each do |author|
  puts &quot;Newest post for #{author.name}: #{author.newest_post.title}&quot;
end
</code></pre>
<p>And, since these are associations, they'll return full-fledged <code>Post</code> instances. So if we decide that we want to display other attributes of the newest post, there's no need to modify any SQL. We simply call the attribute we need:</p>
<pre><code>&lt;%= pluralize(@author.newest_post.word_count, &quot;word&quot;) %&gt;
</code></pre>
<p>And if we want to have a link to the newest post, that's simple too:</p>
<pre><code>&lt;%= link_to @author.newest_post.title, post_path(@author.newest_post) %&gt;
</code></pre>
<p>Or we can use it in a form builder:</p>
<pre><code>&lt;%= form_for @author.newest_post do |f| %&gt;
  &lt;%= f.text_field :title %&gt;
  &lt;%= f.submit %&gt;
&lt;% end %&gt;
</code></pre>
<p>Or we can access it's assocations:</p>
<pre><code>&lt;%= pluralize(@author.newest_post.comments.count, &quot;comment&quot;) %&gt;
</code></pre>
<p>You get the idea. You can do whatever you want with it, because it'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'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's revisit our original query to return a list of the newest posts for each author:</p>
<pre><code>SELECT DISTINCT ON (author_id) *
FROM posts
ORDER BY author_id, created_at DESC
</code></pre>
<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>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN (SELECT DISTINCT ON (author_id) *
           FROM posts
           ORDER BY author_id, created_at DESC)
           AS newest_posts
ON newest_posts.author_id = authors.id
</code></pre>
<p>In <em>this</em> approach we don'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'll see that it looks remarkably like that original query of ours:</p>
<pre><code>   has_one :newest_post, -&gt; {
    select(&quot;DISTINCT ON (author_id) *&quot;)
    .order(:author_id, created_at: :desc)
  }, class_name: &quot;Post&quot;
</code></pre>
<p>In the last argument, we'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'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'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's intuitive and composable. But it breaks down with more complicated stuff that's at the boundary of how much ActiveRecord &quot;understands&quot; 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's okay, though, because View Backed Models, which we'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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Greatest-Per-Group Query in Rails Using Custom Query Methods]]></title><description><![CDATA[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><link>https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825b</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[PostgreSQL]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Mon, 08 Feb 2016 04:35:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><em>This is part 2 of 4 in a series on how to use Greatest Per Group queries in Ruby on Rails to avoid the N + 1 query problem:</em></p>
<ol>
<li><em><a href="https://toasterlovin.com/greatest-per-group-postgresql-distinct-on/">When and how to use Greatest Per Group queries (with PostgreSQL)</a></em></li>
<li><em>Rails implementation using custom query methods</em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/">Rails implementation using a scoped <code>has_one</code> association</a></em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-view-backed-model/">Rails implementation using a view backed model</a></em></li>
</ol>
<p><em>Everything has been tested with Rails 4.2 and PostgreSQL. See <a href="http://rails-greatest-per-group.herokuapp.com">demonstration app</a> and <a href="https://github.com/toasterlovin/rails-greatest-per-group">it's source code</a></em></p>
<hr>
<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's <code>DISTINCT ON</code> feature</a>. Here we'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'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'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'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'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'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="https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/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's that query again:</p>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN (SELECT DISTINCT ON (author_id) *
           FROM posts
           ORDER BY author_id, created_at DESC)
           AS newest_posts
ON newest_posts.author_id = authors.id
</code></pre>
<p>Part of the magic of Rails is that it'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's how we get Rails to execute that query:</p>
<pre><code>@authors = Author
  .select(&quot;authors.*,
           newest_posts.title AS newest_post_title&quot;)
  .joins(&quot;LEFT JOIN (SELECT DISTINCT ON (author_id) *
                     FROM posts
                     ORDER BY author_id, created_at DESC)
          AS newest_posts ON newest_posts.author_id = authors.id&quot;)
</code></pre>
<p>It's actually incredibly straightforward. We'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'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>
<pre><code>@authors.each do |author|
  puts &quot;Newest post for #{author.name}: #{author.newest_post_title}&quot;
end
</code></pre>
<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'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'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>
<pre><code>scope :with_newest_post_title, -&gt; {
  .select(&quot;authors.*,
           newest_posts.title AS newest_post_title&quot;)
  .joins(&quot;LEFT JOIN (SELECT DISTINCT ON (author_id) *
                     FROM posts
                     ORDER BY author_id, created_at DESC)
          AS newest_posts ON newest_posts.author_id = authors.id&quot;)
}
</code></pre>
<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'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's <em>oldest</em> post as well as the <em>title</em> of each author's <em>newest</em> post. You could create another named scope for the date of the author's first post:</p>
<pre><code>scope :with_oldest_post_date, -&gt; {
  select(&quot;authors.*,
          oldest_posts.date AS oldest_post_title&quot;)
  .joins(&quot;LEFT JOIN (SELECT DISTINCT ON (author_id) *
                     FROM posts
                     ORDER BY author_id, created_at ASC)
          AS oldest_posts ON oldest_posts.author_id = authors.id&quot;)
}
</code></pre>
<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>
<pre><code>Author.with_newest_post_title.with_oldest_post_date
</code></pre>
<p>It won't work. That'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>
<pre><code>scope :with_newest_post_title_and_oldest_post_date, -&gt; {
  select(&quot;authors.*,
          newest_posts.title AS newest_post_title,
          oldest_posts.date AS oldest_post_title&quot;)
  .joins(&quot;LEFT JOIN (SELECT DISTINCT ON (author_id) *
                     FROM posts
                     ORDER BY author_id, created_at DESC)
          AS newest_posts ON newest_posts.author_id = authors.id&quot;)
  .joins(&quot;LEFT JOIN (SELECT DISTINCT ON (author_id) *
                     FROM posts
                     ORDER BY author_id, created_at ASC)
          AS oldest_posts ON oldest_posts.author_id = authors.id&quot;)
}
</code></pre>
<p>Does that look like a hot mess to you? Because it looks like a hot mess to me. We'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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Greatest-Per-Group Query in PostgreSQL Using DISTINCT ON]]></title><description><![CDATA[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><link>https://toasterlovin.com/greatest-per-group-postgresql-distinct-on/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8259</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[PostgreSQL]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Sun, 07 Feb 2016 21:23:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><em>This is part 1 of 4 in a series on how to use Greatest Per Group queries in Ruby on Rails to avoid the N + 1 query problem:</em></p>
<ol>
<li><em>When and how to use Greatest Per Group queries (with PostgreSQL)</em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-custom-query-methods/">Rails implementation using custom query methods</a></em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-scoped-has-one/">Rails implementation using a scoped <code>has_one</code> association</a></em></li>
<li><em><a href="https://toasterlovin.com/greatest-per-group-rails-view-backed-model/">Rails implementation using a view backed model</a></em></li>
</ol>
<p><em>Everything has been tested with Rails 4.2 and PostgreSQL. See <a href="http://rails-greatest-per-group.herokuapp.com">demonstration app</a> and <a href="https://github.com/toasterlovin/rails-greatest-per-group">it's source code</a></em></p>
<hr>
<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'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's most recent post when I'm displaying other information about the author.</p>
<p>If I'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>
<pre><code>@post = @author.posts.order(created_at: :desc).first
@post.title
</code></pre>
<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'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'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's useful, let's figure out how they work.</p>
<h2 id="howgreatestpergroupquerieswork">How Greatest Per Group queries work</h2>
<p>The good news is that SQL'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>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN newest_posts ON newest_posts.author_id = authors.id
</code></pre>
<p>That's a fairly straightforward join. In this case we'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't have a <code>newest_posts</code> table. So how are we going to join a table that doesn'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'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't work for our purposes here because – in Postgres, at least – it limits what columns you can select to the column(s) you'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>
<pre><code>SELECT posts.*
FROM posts
GROUP BY author_id
ORDER BY created_at DESC
</code></pre>
<p>The best we can do with <code>GROUP BY</code> is something like this:</p>
<pre><code>SELECT author_id, MAX(created_at) AS newest_post
FROM posts
GROUP BY author_id
</code></pre>
<p>That will return a result that looks like this:</p>
<pre><code>author_id | newest_post
----------+------------
        1 | 2015-08-07
        2 | 2015-11-15
        3 | 2014-04-23
        4 | 2015-01-18
</code></pre>
<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's, so this isn'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's how we get a list of each of the most recent posts per author using <code>DISTINCT ON</code>:</p>
<pre><code>SELECT DISTINCT ON (author_id) *
FROM posts
ORDER BY author_id, created_at DESC
</code></pre>
<p>That's it. Fairly simple when it'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'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'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's an implementation detail leaking out, but it'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's put it all together now. So, we have our overall query:</p>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN newest_posts ON newest_posts.author_id = authors.id
</code></pre>
<p>And we know that the <code>newest_posts</code> table that we're joining to the <code>authors</code> table is actually going to be a temporary table that we generate with this query:</p>
<pre><code>SELECT DISTINCT ON (author_id) *
FROM posts
ORDER BY author_id, created_at DESC
</code></pre>
<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's what that looks like:</p>
<pre><code>SELECT authors.*, newest_posts.title AS newest_post_title
FROM authors
LEFT JOIN (SELECT DISTINCT ON (author_id) *
           FROM posts
           ORDER BY author_id, created_at DESC)
           AS newest_posts
ON newest_posts.author_id = authors.id
</code></pre>
<p>This will return a result that looks like this:</p>
<pre><code>author_id | first_name | last_name | newest_post_title
----------+------------+-----------+------------------
        1 | Jane       | Austen    | Persuasion
        2 | Charles    | Dickens   | Oliver Twist
        3 | J.D.       | Salinger  | Nine Stories
</code></pre>
<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'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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[How I Record Programming Talks]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I usually record the talks at the <a href="http://pdxruby.org/">Portland Ruby Brigade'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's because it's just not that much work to make the</p>]]></description><link>https://toasterlovin.com/how-i-record-programming-talks/</link><guid isPermaLink="false">5ec364f60e3ac71687ab825a</guid><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Mon, 11 Jan 2016 18:09:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I usually record the talks at the <a href="http://pdxruby.org/">Portland Ruby Brigade'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'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).</p>
<p>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), <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'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'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'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 &quot;pro&quot; 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't tell unless you'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'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'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't know what the trade name is for these things, but they'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's microphone jack. So, you'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'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'll need AAA batteries for the wireless microphone system. I like Sanyo's Eneloop rechargeables. Here'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'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's better to just be prepared for this eventuality.</p>
<h6 id="telephotolensifyouneedit">Telephoto Lens (if you need it)</h6>
<p>I'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'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't recommend it, per se, since I haven'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'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's happening. So I recently switched to using Apple'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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Rails: Static Pages Using the Controller Route Macro]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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</p>]]></description><link>https://toasterlovin.com/rails-static-pages-using-the-controller-route-macro/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8257</guid><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Fri, 26 Jun 2015 23:13:19 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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's what it all looks like.</p>
<p>In your <code>config/routes.rb</code>:</p>
<pre><code>App::Application.routes.draw do
  root to: &quot;pages#index&quot;
  get :contact, to: &quot;pages#contact&quot;
  get :about, to: &quot;pages#contact&quot;
end
</code></pre>
<p>In your <code>app/controllers/pages_controller.rb</code>:</p>
<pre><code>class PagesController &lt; ApplicationController
  def index
  end

  def contact
  end

  def about
  end
end
</code></pre>
<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>
<pre><code>App::Application.routes.draw do
  controller :pages do
    root to: :index
    get :contact
    get :about
  end
end
</code></pre>
<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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Rails: Organizing Controllers with Modules]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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</p>]]></description><link>https://toasterlovin.com/rails-organizing-controllers-with-modules/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8255</guid><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Tue, 05 May 2015 03:41:23 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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'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>
<pre><code>resources :companies do
  resources :addresses
end
</code></pre>
<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>
<pre><code>resources :companies do
  resources :addresses
  resources :people
  resources :orders
end

resources :products
resources :industries
resources :salespeople
</code></pre>
<p>Now, when you look in your controllers directory, it will look like this:</p>
<pre><code># ls app/controllers
addresses_controller.rb
companies_controller.rb
industries_controller.rb
orders_controller.rb
people_controller.rb
products_controller.rb
salespeople_controller.rb
</code></pre>
<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's routes, which are hierarchical in nature, have been flattened into a single level of hierarchy. Okay, maybe you don't think it'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's how you tell the router that a set of routes should be directed to controllers namespaced under a certain module:</p>
<pre><code>resources :companies do
  scope module: &quot;companies&quot; do
    resources :addresses
    resources :people
    resources :orders
  end
end

resources :products
resources :industries
resources :salespeople
</code></pre>
<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>
<pre><code># ls app/controllers
companies_controller.rb
companies/
industries_controller.rb
products_controller.rb
salespeople_controller.rb
</code></pre>
<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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Rails: Organizing Models by Attribute]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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'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</p>]]></description><link>https://toasterlovin.com/rails-organizing-models-by-attribute/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8254</guid><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Sun, 19 Apr 2015 20:12:55 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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'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'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.</p>
<p>In all the Rails tutorials, you will see models organized something like this:</p>
<pre><code>class Company &lt; ActiveRecord::Base
  attr_accessible :name, :billing_address_id, :shipping_address_id,
    :industry_id, :salesperson_id, :price_level_id

  validates :name, :billing_address, :shipping_address,
    :industry, :salesperson, :price_level, presence: true

  validates :name, uniqueness: true

  belongs_to :billing_address, class: &quot;Address&quot;

  # And so on
end
</code></pre>
<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's easy to miss something. You can get away with this when a model is small, but it's simply unworkable as a model grows larger than the height of your screen. Here's how I would rewrite this model:</p>
<pre><code>class Company &lt; ActiveRecord::Base
  attr_accessible :name
  validates :name, presence: true, uniqueness: true

  attr_accessible :status
  validates :status, presence: true

  attr_accessible :billing_address_id
  belongs_to :billing_address, class: &quot;Address&quot;
  validates :billing_address

  # And so on
end
</code></pre>
<p>This is functionally equivalent to the first example, but it's easy to immediately grasp everything there is to know about the <code>name</code> attribute – because it'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's what the first approach is.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Rails: Testing for Insecure Admin Routes]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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</p>]]></description><link>https://toasterlovin.com/rails-testing-for-insecure-admin-routes/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8252</guid><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Sat, 02 Nov 2013 19:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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'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'm just a human -- and I frequently use generators to create my controllers -- so I'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>
<pre><code class="language-ruby">
require 'test_helper'

class Admin::InsecureRoutesTest &lt; ActionDispatch::IntegrationTest
  ROUTES = Rails.application.routes.routes.map do |route|
    # Turn the route path spec into a string:
    # - Remove the &quot;(.:format)&quot; bit at the end
    # - Use &quot;1&quot; for all params
    path = route.path.spec.to_s.gsub(/\(\.:format\)/, &quot;&quot;).gsub(/:[a-zA-Z_]+/, &quot;1&quot;)
    # Route verbs are stored as regular expressions; convert them to symbols
    verb = %W{ GET POST PUT PATCH DELETE }.grep(route.verb).first.downcase.to_sym
    # Return a hash with two keys: the route path and it's verb
    { path: path, verb: verb }
  end

  test &quot;admin routes should redirect to admin login page&quot; do
    admin_routes = ROUTES.select { |route| route[:path].starts_with? &quot;/admin&quot; }
    insecure_routes = []

    admin_routes.each do |route|
      begin
        reset!
        # Use the route's verb to access the route's path
        request_via_redirect(route[:verb], route[:path])
        
        # If we aren't redirected to the admin login, the route is insecure
        unless path == admin_login_path
          insecure_routes &lt;&lt; &quot;#{route[:verb]} #{route[:path]}&quot;
        end

        rescue ActiveRecord::RecordNotFound
        # Since we are blindly submitting &quot;1&quot; for all route params,
        # this error can pop up. If it does, it means that the request
        # got past the `before_filter` and to the code in the controller
        # where it attempts to locate the record in the database. That
        # means this is an insecure route.
        unless path == admin_login_path
          insecure_routes &lt;&lt; &quot;#{route[:verb]} #{route[:path]}&quot;
        end

        rescue AbstractController::ActionNotFound
        # This error means the route doesn't connect to a controller
        # action. This is a problem if it happens, but this is a separate
        # concern and should be tested elsewhere. See my previous post
        # about testing for orphaned routes.
      end
    end

    # Fail if we have insecure routes.
    assert insecure_routes.empty?, &quot;The following routes are not secure: \n\t#{insecure_routes.uniq.join(&quot;\n\t&quot;)}&quot;
  end
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Rails: Testing for Orphaned Routes]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>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</p>]]></description><link>https://toasterlovin.com/rails-testing-for-orphaned-routes/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8251</guid><category><![CDATA[Ruby on Rails]]></category><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Wed, 30 Oct 2013 19:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>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.</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't feel like I could be <em>sure</em> that everything was copacetic. And I've learned the hard way that this means it's time for some tests...</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 -- 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's that test.</p>
<pre><code>
require 'test_helper'

class OrphanedRoutesTest &lt; ActionDispatch::IntegrationTest
  ROUTES = Rails.application.routes.routes.map do |route|
    # Turn the route path spec into a string:
    # - Remove the &quot;(.:format)&quot; bit at the end
    # - Use &quot;1&quot; for all params
    path = route.path.spec.to_s.gsub(/\(\.:format\)/, &quot;&quot;).gsub(/:[a-zA-Z_]+/, &quot;1&quot;)
    # Route verbs are stored as regular expressions; convert them to symbols
    verb = %W{ GET POST PUT PATCH DELETE }.grep(route.verb).first.downcase.to_sym
    # Return a hash with two keys: the route path and it's verb
    { path: path, verb: verb }
  end

  test &quot;no orphaned routes exist&quot; do
    orphaned_routes = []

    ROUTES.each do |route|
      begin
        reset!
        # Use the route's verb to access the route's path
        request_via_redirect(route[:verb], route[:path])
      rescue ActionController::RoutingError, AbstractController::ActionNotFound
        # ActionController::RoutingError means the controller doesn't exist
        # AbstractController::ActionNotFound means the action doesn't exist
        orphaned_routes &lt;&lt; &quot;#{route[:verb]} #{route[:path]}&quot;
      rescue ActiveRecord::RecordNotFound
        # This error means the controller couldn't locate the specified record.
        # This happens because we are using 1 for all the route params
        # But, it means that the route points to a valid controller action,
        # so we ignore it
      end
    end

    # Fail if we have any orphaned routes
    assert orphaned_routes.empty?, &quot;The following routes lead to nowhere: \n\t#{orphaned_routes.uniq.join(&quot;\n\t&quot;)}&quot;
  end
end
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Leveling Up Revisited]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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 -- the kind of</p>]]></description><link>https://toasterlovin.com/leveling-up-revisited/</link><guid isPermaLink="false">5ec364f60e3ac71687ab8250</guid><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Fri, 19 Apr 2013 18:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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 -- 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.</p>
<p>Instead, I'm looking to make a list that I will revisit every few weeks or so. For something like that, I find it'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'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>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Leveling Up]]></title><description><![CDATA[<!--kg-card-begin: markdown--><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.</li></ol></blockquote>]]></description><link>https://toasterlovin.com/leveling-up/</link><guid isPermaLink="false">5ec364f60e3ac71687ab824f</guid><dc:creator><![CDATA[Richard Jones]]></dc:creator><pubDate>Mon, 29 Oct 2012 19:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><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'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><s>Contribute to an open source project</s> (<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>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>