<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Herold</title>
    <description>The latest articles on DEV Community by Michael Herold (@michaelherold).</description>
    <link>https://dev.to/michaelherold</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92227%2F8751675c-0708-4620-85f0-933f683a9bbe.jpeg</url>
      <title>DEV Community: Michael Herold</title>
      <link>https://dev.to/michaelherold</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michaelherold"/>
    <language>en</language>
    <item>
      <title>Grouped pagination in ActiveRecord</title>
      <dc:creator>Michael Herold</dc:creator>
      <pubDate>Sat, 18 Aug 2018 14:00:49 +0000</pubDate>
      <link>https://dev.to/michaelherold/grouped-pagination-in-activerecord-14l8</link>
      <guid>https://dev.to/michaelherold/grouped-pagination-in-activerecord-14l8</guid>
      <description>&lt;p&gt;Sometimes, designers will mock-up an extremely usable page that they’ve thought about and tested. Once they’re done and they bring it to you to implement, you look at it and think, “how on Earth can I do that efficiently?” One such case happened at work recently.&lt;/p&gt;

&lt;p&gt;We were working on a “command center” of sorts where we show our customers a list of upgrades in various states. The design called for what looked like three different lists of records with each table consisting of records in a state. Since a customer can have potentially dozens of these records, we knew we wanted to paginate the page. The wrinkle in setup was that the pagination should consider the full list of records as the dataset, not each list individually. This caused us to wonder how we can efficiently implement grouped pagination in ActiveRecord.&lt;/p&gt;

&lt;h2&gt;
  
  
  Naive implementation
&lt;/h2&gt;

&lt;p&gt;When presented with a mock, it’s sometimes difficult to fully understand the intended behavior. For example, take the following abstract mock. The blue represents “draft” posts, the green are “unpublished” posts, and the red are “published” posts&lt;sup id="fn-domain-return"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2FSortedQuery1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2FSortedQuery1.png" alt="Three groups of records, grouped by status"&gt;&lt;/a&gt;Three groups of records, grouped by status&lt;/p&gt;

&lt;p&gt;Upon first inspection, my pair and I saw three lists of records, each grouped by a headline that corresponds to a status. Arguably, the natural understanding of the pagination behavior on this mock is to paginate each set individually. When we translated that to controller logic, the naïve implementation looked something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@drafts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:dp&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="vi"&gt;@unpublished&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unpublished&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:up&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="vi"&gt;@published&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;published&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:pp&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We questioned whether we understood the mock correctly since that seemed like it would be a challenging user experience. To make sure we understood it, we did our due diligence and reached out to the designer. It turned out that we should paginate the &lt;em&gt;whole&lt;/em&gt; dataset, not each piece individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  One dataset
&lt;/h2&gt;

&lt;p&gt;We took the mock back for further review with our newfound understanding. A few minutes later, we sketched the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2FSortedQuery2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2FSortedQuery2.png" alt="The intended pagination scheme for the three groups"&gt;&lt;/a&gt;The intended pagination scheme for the three groups&lt;/p&gt;

&lt;p&gt;By treating the list as a single dataset, it was clear that each page can have multiple groups on it. However, it wasn’t necessarily true that each page has every group on it. Some might have all three, depending on the size of the query, but others might have only two of the statuses, or one!&lt;/p&gt;

&lt;p&gt;Complicating things even further, we knew that the order was primarily dependent on the status of the post and we should sort each set of posts (grouped by status) by title. Clearly, we should run a single query and paginate off of that, like the following mock:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2FSortedQuery3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2FSortedQuery3.png" alt="The resulting set of paged records"&gt;&lt;/a&gt;The resulting set of paged records, as shown on each page. Notice the complications due to the ordering and grouping.&lt;/p&gt;

&lt;p&gt;We were initially stumped. How could we do this efficiently?&lt;/p&gt;

&lt;h2&gt;
  
  
  First attempts
&lt;/h2&gt;

&lt;p&gt;Our first attempt to do this was in the database using the &lt;code&gt;GROUP BY&lt;/code&gt; clause in SQL. &lt;code&gt;GROUP BY&lt;/code&gt; is great for when you need to aggregate information for groups of records. However, we needed to treat the set as a single source so that we could paginate it. That’s not possible using &lt;code&gt;GROUP BY&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After that, we tried to step back from doing anything fancy and use an &lt;code&gt;ORDER BY&lt;/code&gt; clause. However, we thought back to the requirements: we must show the &lt;em&gt;draft&lt;/em&gt; posts first, the &lt;em&gt;unpublished&lt;/em&gt; posts second, and the &lt;em&gt;published&lt;/em&gt; posts third. Since those three terms alphabetically sort in the order, “draft”, “published”, “unpublished,” we knew it wasn’t a straightforward query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grouped pagination
&lt;/h2&gt;

&lt;p&gt;We thought a little harder about the problem. If we could somehow change the “status” field to a number, we could easily order the posts by that. With this thought, we reached for the &lt;a href="https://www.postgresql.org/docs/current/static/functions-conditional.html#FUNCTIONS-CASE" rel="noopener noreferrer"&gt;&lt;code&gt;CASE&lt;/code&gt; conditional expression&lt;/a&gt; to transform the status field into something we could use. Transforming the post status and ordering them by that calculated field using a SQL fragment looks the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order_by_status&lt;/span&gt;
    &lt;span class="n"&gt;clause&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="no"&gt;Arel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;~&lt;/span&gt;&lt;span class="no"&gt;SQL&lt;/span&gt;&lt;span class="sh"&gt;
        CASE "posts"."status"
        WHEN 'draft' THEN 0
        WHEN 'unpublished' THEN 1
        WHEN 'published' THEN 2
        ELSE 3
        END
&lt;/span&gt;&lt;span class="no"&gt;      SQL&lt;/span&gt;

    &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I prefer to use Arel nodes for this purpose to give me better error messages if something breaks, so we refactored to this form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order_by_status&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="no"&gt;Arel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Nodes&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Case&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arel_table&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:status&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'draft'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'unpublished'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'published'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;else&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! We had our posts grouped and ordered appropriately with a call to &lt;code&gt;.order(:title)&lt;/code&gt;. We could then plug it into the controller for viewing&lt;sup id="fn-simple-return"&gt;2&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@drafts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:draft?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@unpublished&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:unpublished?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@published&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:published?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;posts&lt;/span&gt;
    &lt;span class="vi"&gt;@posts&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt;
      &lt;span class="no"&gt;Post&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order_by_status&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:page&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single query&lt;sup id="fn-selects-return"&gt;3&lt;/sup&gt; was able to do what we needed it to do: grouped pagination. It gave us a unified dataset to paginate over, grouped by status, in the correct order for each group. The confusing logic was easily isolated behind the &lt;code&gt;Post.order_by_status&lt;/code&gt; method and we test it in isolation to make sure future Rails upgrades don’t break the syntax or logic.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://michaeljherold.com/2018/08/18/grouped-pagination-in-activerecord/" rel="noopener noreferrer"&gt;Grouped pagination in ActiveRecord&lt;/a&gt; appeared first on &lt;a href="https://michaeljherold.com" rel="noopener noreferrer"&gt;Michael Herold&lt;/a&gt;.&lt;/p&gt;




&lt;ol&gt;
&lt;li&gt;
&lt;span id="fn-domain"&gt;&lt;/span&gt;In the interest of not complicating this post with the intimate details of our domain, I decided to show the example using blog posts as the domain of understanding. All you need to know about that is that posts have a “title” and we store statuses as strings. ↩︎
&lt;/li&gt;
&lt;li&gt;
&lt;span id="fn-simple"&gt;&lt;/span&gt;In reality, we didn’t stop here. We extracted the result into a model using &lt;code&gt;SimpleDelegator&lt;/code&gt;. This let us remove the grouping logic from the controller and the view. However, that’s not germane to this post, so I’m ignoring it. ↩︎
&lt;/li&gt;
&lt;li&gt;
&lt;span id="fn-selects"&gt;&lt;/span&gt;The use of &lt;code&gt;select&lt;/code&gt; might have caught your eye. Since we needed to show the records on the page, it’s not a performance concern to select from the relation. Also, using &lt;code&gt;#where&lt;/code&gt; has two problems. First, it removes the pagination. Second, it runs three queries instead of one. ↩︎
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>activerecord</category>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Using the double-splat operator in Ruby</title>
      <dc:creator>Michael Herold</dc:creator>
      <pubDate>Fri, 17 Aug 2018 14:00:23 +0000</pubDate>
      <link>https://dev.to/michaelherold/using-the-double-splat-operator-in-ruby-dp5</link>
      <guid>https://dev.to/michaelherold/using-the-double-splat-operator-in-ruby-dp5</guid>
      <description>&lt;p&gt;The double-splat operator is one of my favorite additions in Ruby 2.0. For some reason, the two little asterisks together make me happier than an optional &lt;code&gt;Hash&lt;/code&gt; parameter in a method. Even so, outside of method definitions, I didn’t realize there was a use for the double-splat operator until I dug into a &lt;a href="https://github.com/intridea/hashie/issues/353"&gt;bug in Hashie&lt;/a&gt;. I liked the result enough that I wanted to take a quick minute and share what I found.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related behavior in JavaScript
&lt;/h2&gt;

&lt;p&gt;If you write any modern JavaScript, you might have seen the following pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;todoApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;SET_VISIBILITY_FILTER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;visibilityFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;...&lt;/code&gt; spread operator is really nice for creating new objects from others without modifying the originals. I really liked this when I built my first Redux-based JavaScript application because it removes a lot of the ceremony around &lt;code&gt;Object.assign&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sometimes you don’t yet have enough information to create an object. When that happens Hash is a great proxy for an object until you understand your domain a little better. I wanted the same behavior in Ruby for building up Hashes in these cases. For a while, I relied on &lt;code&gt;Hash#merge&lt;/code&gt;, but then I saw this bug on Hashie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Double-splat operator
&lt;/h2&gt;

&lt;p&gt;To solve this problem, you can use the double-splat operator in a different way. Check out the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;todo_app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;initial_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;
  &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;SET_VISIBILITY_FILTER&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;visibility_filter: &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet works exactly the same way as the JavaScript version! I think that’s a really elegant answer to my original question.&lt;/p&gt;

&lt;p&gt;Interestingly, if you compile down the instruction sequence for this code, you will see that it uses the C version of &lt;code&gt;Hash#merge&lt;/code&gt; under the covers. I like that I’m getting the semantics of &lt;code&gt;state.merge(visibility_filter: action.filter)&lt;/code&gt;, but can express it in a way that my JavaScript-writing friends can easily understand.&lt;/p&gt;

&lt;p&gt;If there’s one way to do something in Ruby, there’s probably at least one more. I think this is one of the reasons many people like Ruby: they can express their thoughts in the manner that is easiest for them.&lt;/p&gt;

&lt;p&gt;That’s all I have for you today. Did you know about the double-splat operator in this case?&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://michaeljherold.com/2018/08/17/using-double-splat-operator-ruby/"&gt;Using the double-splat operator in Ruby&lt;/a&gt; appeared first on &lt;a href="https://michaeljherold.com"&gt;Michael Herold&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>Talking to yourself for self-teaching</title>
      <dc:creator>Michael Herold</dc:creator>
      <pubDate>Thu, 16 Aug 2018 14:00:15 +0000</pubDate>
      <link>https://dev.to/michaelherold/talking-to-yourself-for-self-teaching-bnj</link>
      <guid>https://dev.to/michaelherold/talking-to-yourself-for-self-teaching-bnj</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2Fmic-mic-stand-microphone-64057-1024x576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmichaeljherold.com%2Fwp-content%2Fuploads%2F2018%2F08%2Fmic-mic-stand-microphone-64057-1024x576.jpg" alt="A microphone on a stand."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you ever talk to yourself? How about publicly? We, as a society, often make fun of our friends for talking to themselves. But self-talk can be a powerful technique for self-teaching something. As an exercise, I tried using a tweet storm to share how I was approaching relearning a numerical methods technique. This post is a recounting of why I did it and what I learned. I’ll also share whether I think I will do it again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;For a little bit of background, I was a computer science and mathematics double-major during my undergrad education. I was very strong in computer science but not nearly as good at the mathematics. I’m embarrassed to say that I was sometimes the student that fell asleep in class (sorry about that, Prof. Baldwin!).&lt;/p&gt;

&lt;p&gt;I really started to enjoy my maths classes as I grew older. By the time I was in graduate school, I found myself wishing I had spent more time on mathematics during undergrad. I began to see how all of the disparate concepts worked together.&lt;/p&gt;

&lt;p&gt;One of the classes that I took in my junior or senior year of college was a numerical methods class. If you’ve ever learned about splines (or used them in Illustrator!) or interpolating functions, that’s the kind of thing you do with numerical methods.&lt;/p&gt;

&lt;p&gt;I had been working on a problem in my head for a while on how to calculate the intersections of two lines for which you don’t know the function. Intersections are pretty simple when you have a function; you look for where the functions are equal. But for discrete functions you generate through surveys, I was struggling to come up with a general solution.&lt;/p&gt;

&lt;p&gt;So I turned to my trusty numerical methods textbook.&lt;/p&gt;

&lt;h2&gt;
  
  
  The storm
&lt;/h2&gt;

&lt;p&gt;One thing I remembered struggling with in undergrad is comprehension when reading my textbooks. I also remembered that it went better when talking about it with a classmate. My wife was out-of-town at a seminar, so I was home alone; what was I to do?&lt;/p&gt;

&lt;p&gt;I turned to Twitter.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1029504464854638593-455" src="https://platform.twitter.com/embed/Tweet.html?id=1029504464854638593"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1029504464854638593-455');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1029504464854638593&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;I started a “tweet storm,” or chain of tweets that form a longer thought. Each tweet was either an excerpt of my reading or single thought about the words. This made me slow down and analyze what I was thinking. It was &lt;em&gt;really&lt;/em&gt; effective at this. Since I had to explain the concepts to myself in order to write them down, I managed to look at each though from multiple angles.&lt;/p&gt;

&lt;p&gt;There was also, I admit, some entertainment value in blathering to myself on the internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was it effective?
&lt;/h2&gt;

&lt;p&gt;I’m not sure how effective it was. I definitely understood the concept better than I did the first time I learned it. I also received some feedback from two of my undergrad professors that I was looking into the wrong concept (hi, Dave and John!).&lt;/p&gt;

&lt;p&gt;I think the exercise was a good one. I enjoy reading train-of-thought style pieces from others. I wonder if anyone else found it useful? I received some good feedback from two friends that it was interesting. But is “interesting” a success?&lt;/p&gt;

&lt;p&gt;The next time I’m thinking about something like this, I might try it again … but only if I’m home alone!&lt;/p&gt;

&lt;p&gt;Have you ever talked to yourself on the internet? How did it go?&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://michaeljherold.com/2018/08/16/talking-to-yourself-for-self-teaching/" rel="noopener noreferrer"&gt;Talking to yourself for self-teaching&lt;/a&gt; appeared first on &lt;a href="https://michaeljherold.com" rel="noopener noreferrer"&gt;Michael Herold&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>teaching</category>
    </item>
    <item>
      <title>Senior developers: Can you recommend your path?</title>
      <dc:creator>Michael Herold</dc:creator>
      <pubDate>Wed, 15 Aug 2018 14:13:18 +0000</pubDate>
      <link>https://dev.to/michaelherold/senior-developers-can-you-recommend-your-path-38eg</link>
      <guid>https://dev.to/michaelherold/senior-developers-can-you-recommend-your-path-38eg</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sqKOGSON--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://michaeljherold.com/wp-content/uploads/2018/08/alphabet-class-conceptual-301926-1024x683.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sqKOGSON--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://michaeljherold.com/wp-content/uploads/2018/08/alphabet-class-conceptual-301926-1024x683.jpg" alt="Five dice arranged to spell T-E-A-C-H."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the duties I have at work is to mentor some of the Rails developers on our team. I enjoy this immensely, yet struggle with at the same time. In a previous life, I wanted to be a professor and help people learn computer science and programming. I became jaded with academia, so left it and have been working in the software industry ever since.  However, I still have that urge to teach, which is why I enjoy mentoring so much. My struggles with mentoring come from my long background in software development. I have been programming in some form since I was nine years old and have been paid for programming since I was eighteen. As such, I have somewhere between 13-22 years of experience across myriad different computer-related backgrounds. I spent the majority of my waking hours from the age of fourteen to the present building my skillset. Can I really ask more junior developers to do the same? How on Earth do I reconcile that when suggesting ways to improve to my colleagues?&lt;/p&gt;

&lt;h2&gt;
  
  
  Others ask this too
&lt;/h2&gt;

&lt;p&gt;I've been thinking about this for two years, ever since I started at &lt;a href="https://getflywheel.com"&gt;Flywheel&lt;/a&gt; and joined a team with a range of skill level. Prior to that, I worked at small companies where I was the only engineer or where all of the engineers were senior. I long thought this was something that only I struggled with (hah, hubris!) and didn't really know where to look for advice. Then, in the span of a single week&lt;sup id="fn-slow-return"&gt;1&lt;/sup&gt;, two Twitter threads popped up discussing this exact issue!&lt;/p&gt;

&lt;p&gt;Charity Majors &lt;a href="https://twitter.com/mipsytipsy/status/996985643484921860"&gt;asked herself&lt;/a&gt; why she deliberately tells people to focus on things other than work instead of her own path of spending many hours working on computers. Charity struggles with this throughout the thread and wrestles with the impulse to tell people that they need to put the time in to get better. While some part of her feels that way, another part wants to nurture a life outside of work for her colleagues. I empathize with Charity because I have the same internal struggle.&lt;/p&gt;

&lt;p&gt;Similarly, Alice Goldfuss &lt;a href="https://twitter.com/alicegoldfuss/status/997547804636602373"&gt;shared&lt;/a&gt; how she worked herself ragged in overtime just so she felt that she was doing well enough to avoid being fired. This is, obviously, not a good place in which to find yourself. Feeling like you are running on an advancement treadmill just to maintain your current position is an indicator that something failed somewhere in the chain. This, specifically, is what I would like to avoid in my mentoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Work-life balance
&lt;/h2&gt;

&lt;p&gt;I fundamentally believe that a work-life balance is important to have. You're more effective in your work when you unplug for a while and do something else. But, to this day, I don't practice this. Through numerous side projects, open source contributions, and endless reading about my craft, I am, in Charity's words, not a "moderate creature." Software design and construction is and has always been what I enjoy doing. I love to figure out how to build something that communicates its purpose and solves a real problem for people. That must be my manifestation of the "maker gene" that you hear people talk about.&lt;/p&gt;

&lt;p&gt;But I can't -- and won't -- for my immoderation on those who I mentor. It's unreasonable to pressure others to follow this path. My near-obsession with my craft has not been without cost through my life. To this day, I find myself getting grumpy when I don't spend enough time designing and building. This affects both my wife and my coworkers, albeit in different ways. I can't really recommend this path to anyone, but I also struggle to see another solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;How can I reconcile my two halves? I know that I wouldn't be where I am in my profession without my immoderation. I also know that I want to help my colleagues grow in a balanced way. These two sides are the balancing act that I, myself, have to play. Each time I find myself starting to recommend a path that I would enjoy due to my craft being a large part of my identity, I check what I'm going to say. Usually, I find a better way to approach it, but it's difficult work.&lt;/p&gt;

&lt;p&gt;Do you struggle with this problem? Have you come up with ways to manage the temptation to disrupt your colleagues' work-life balance in the interest of advancement? If so, please leave a comment and share your story!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://michaeljherold.com/2018/08/15/senior-developers-can-you-recommend-your-path/"&gt;Senior developers: Can you recommend your path?&lt;/a&gt; appeared first on &lt;a href="https://michaeljherold.com"&gt;Michael Herold&lt;/a&gt;.&lt;/p&gt;





&lt;ol&gt;
    &lt;li id="fn-slow"&gt;This was two months ago and I'm just now writing this. Crack reporter, I am not. ↩︎
&lt;/li&gt;
  &lt;/ol&gt;

</description>
      <category>mentoring</category>
      <category>leadership</category>
    </item>
    <item>
      <title>Does Phoenix make database CRUD too easy?</title>
      <dc:creator>Michael Herold</dc:creator>
      <pubDate>Tue, 14 Aug 2018 14:48:14 +0000</pubDate>
      <link>https://dev.to/michaelherold/does-phoenix-make-database-crud-too-easy-2llf</link>
      <guid>https://dev.to/michaelherold/does-phoenix-make-database-crud-too-easy-2llf</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bgy0XBBI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://michaeljherold.com/wp-content/uploads/2018/08/phoenix-1024x576.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bgy0XBBI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://michaeljherold.com/wp-content/uploads/2018/08/phoenix-1024x576.png" alt="The Phoenix framework logo, an orange firebird."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In 2014, the &lt;a href="https://phoenixframework.org"&gt;Phoenix framework&lt;/a&gt; emerged onto the web development scene as a fast, productive, and concurrent solution for the modern web. Its focus was on massive concurrency, thanks to the power of the &lt;a href="https://elixir-lang.org"&gt;Elixir&lt;/a&gt; language and Erlang's BEAM virtual machine. The original branding stressed the &lt;em&gt;productive&lt;/em&gt; aspect, positioning the framework against the venerable king of productivity, Ruby on Rails. Those who are familiar with Rails will see a lot of inspiration from Rails. The way Phoenix auto-reloads code in development mode makes it just as easy to use as Rails. The router grammar requires a good squint to see the difference between the two. This inspiration certainly makes for a quick learning experience for Rails developers. But I wonder: at what cost? Does Phoenix make it too easy to structure your application like a Rails application? Is this convenience to the detriment of using the full power and expressivity of Elixir?&lt;/p&gt;

&lt;h2&gt;
  
  
  Phoenix in the early days
&lt;/h2&gt;

&lt;p&gt;Originally, the core team clearly optimized Phoenix for productivity and similarity to Rails. There were modules that were called "models" that you were encouraged to treat similarly to Rails models. Concerns were mixed in the model modules (say that three times fast) between querying, persistence, and business logic. The first application that I spiked out in these days looked &lt;em&gt;a lot&lt;/em&gt; like a Rails application, despite reading through &lt;a href="https://pragprog.com/book/phoenix/programming-phoenix"&gt;Programming Phoenix&lt;/a&gt;. I understood that I should start to split business logic out into separate applications and only use Phoenix as the web interface to the application. However, the umbrella application concept put me into an "architecture astronaut" mode and I could either ignore it and "be productive" or endlessly spin my wheels.&lt;/p&gt;

&lt;p&gt;I admit, many of my problems in Phoenix prior to the 1.3 release likely stemmed from my simultaneously learning Elixir and Phoenix; I didn't know enough of either to be very effective with the toolset. Compounded by the fact that I was only using it on side projects, I wanted to continue to build and grow my skills rather than take the time to design my application as a piece of software first and a web interface second. I think this is often the same problem that people have early on in their Rails days: they want to build and "ship stuff," not deliberately build maintainable software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contexts and Domain-Driven Design
&lt;/h2&gt;

&lt;p&gt;With the release of v1.3.0, Phoenix radically shifted the way the default generators worked. In his &lt;a href="https://confreaks.tv/videos/lonestarelixir2017-keynote-phoenix-1-3"&gt;Lonestar ElixirConf 2017 keynote&lt;/a&gt;, Chris McCord described the new default architecture for Phoenix applications, which revolved around contexts. Based in Domain-Driven Design, contexts (or, as people are loath to say, bounded contexts) give a place for your business logic to live and define the interface between different components of your system. Does your application have a system of accounts with many bits of logic around them? Okay, those likely belong in an &lt;code&gt;Accounts&lt;/code&gt; context. Are you interfacing with social media as a facet of your business? Great, you probably should have a &lt;code&gt;SocialMedia&lt;/code&gt; context.&lt;/p&gt;

&lt;p&gt;Contexts are a great first step toward wrangling the architecture of a Phoenix application. Instead of a Phoenix-is-your-architecture structure, you can move toward a semblance of loosely connected pieces that work together. These form natural boundaries between the components of your application. The boundaries can later be used as seams by which you can slice-and-dice your application into several smaller pieces, should that be something that you need to do. The Phoenix maintainers made the decision to change the default generators to use this design pattern for structuring your application and it was a very positive move. However, the part that I worry about is that they chose a specific piece of the default Phoenix stack as the interface between different contexts: Ecto, the database Domain-Specific Language (DSL) and interface language.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Ecto-based architecture
&lt;/h2&gt;

&lt;p&gt;Because of the decision to use Ecto as the boundary between generated contexts, that is the natural direction that people will take when learning Phoenix. Ecto is a &lt;em&gt;wonderful&lt;/em&gt; library and very fun to work with. It helps you to be more thoughtful about your database design. You have to design queries since you don't get a lot for "free" like in Rails' ActiveRecord. Ecto also removes many of the ways that you can accidentally hamstring yourself (I'm looking at you, N+1 queries!). Its thoughtful architecture makes you be explicit about what you want from a query. However, because Ecto is &lt;em&gt;a database library&lt;/em&gt;, that means that the coordination of work between your contexts is fundamentally coupled to interacting with a database.&lt;/p&gt;

&lt;p&gt;There is nothing inherently wrong with this decision. If you are making a simple CRUD application, this pattern will serve you well and will help you move quickly. However, how many "simple CRUD applications" continue to stay simple? How many of them continue to be CRUD applications? Every web app that I've ever worked on has increasingly gravitated away from the happy place where you are building a "glorified spreadsheet". As time goes on, more and more of your business logic has nothing to do with CRUD and has everything to do with munging that data. The business logic is happier without knowing it works with a database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternatives?
&lt;/h2&gt;

&lt;p&gt;This mild existential crisis that I had with the architecture of my Elixir/Phoenix application was spurred by reading an &lt;a href="http://zxq9.com/erlmud/html/index.html"&gt;excellent commentary on building a Multi-User Dungeon (MUD) in Erlang&lt;/a&gt; and the thought and care that the author put into designing a process-based architecture for the application. It made me wonder: is Ecto really the best choice for the interface "language" between contexts? Is there something else we should use that gives us the nice affordances of &lt;code&gt;Ecto.Changeset&lt;/code&gt;s and their validation, but doesn't intrinsically tie us to the database?&lt;/p&gt;

&lt;p&gt;I have considered using &lt;a href="https://github.com/jakub-zawislak/formex"&gt;Formex&lt;/a&gt; as the mediation point between contexts. It interfaces well with &lt;code&gt;Phoenix.HTML&lt;/code&gt; and is pretty lightweight in what you need to know to use it for interacting with the application. I have also considered rolling my own way of doing things, but that usually isn't the wise choice. I'm wondering if anyone else out there has thought about this? Do you have any way of breaking the tie between your traditional database and your application? I'd love to hear from you in the comments!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://michaeljherold.com/2018/08/14/does-phoenix-make-database-crud-too-easy/"&gt;Does Phoenix make database CRUD too easy?&lt;/a&gt; appeared first on &lt;a href="https://michaeljherold.com"&gt;Michael Herold&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
    </item>
    <item>
      <title>Finding Rails migrations</title>
      <dc:creator>Michael Herold</dc:creator>
      <pubDate>Mon, 13 Aug 2018 17:19:07 +0000</pubDate>
      <link>https://dev.to/michaelherold/finding-rails-migrations-1dhc</link>
      <guid>https://dev.to/michaelherold/finding-rails-migrations-1dhc</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hKr6M29F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oi1xuee9oiz1x32pozhg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hKr6M29F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oi1xuee9oiz1x32pozhg.jpg" alt="Scrabble pieces arranged to spell S-E-A-R-C-H signifying the search for Rails migrations across branches."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, I find myself working across several branches helping different teammates with their stories. Often, these branches use Rails migrations to easily manage the database changes that need to be made to support the work. This means that I end up running migrations from many different branches. Because I am human, I often forget to roll those migrations back before switching branches. When a destructive migration has to happen as part of a branch, it leaves me in a situation where I have several migrations that I need to roll back at any given time. In addition, they might be interleaved with migrations that exist on the &lt;code&gt;master&lt;/code&gt; branch if it's a longer-running branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Missing Rails migrations
&lt;/h2&gt;

&lt;p&gt;When I have database migrations that I want to track across branches, I use &lt;a href="https://guides.rubyonrails.org/command_line.html#bin-rails"&gt;&lt;code&gt;rails db:migrate:status&lt;/code&gt;&lt;/a&gt; to see what the status is for every migration that exists on my current branch. However, when I have run migrations that haven't been merged into the &lt;code&gt;master&lt;/code&gt; branch, that leaves me with output that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   up     20180301163041  Add chocolate chips to the cookies
   up     20180302132931  ********** NO FILE **********
   up     20180302161231  Remove the egg from the recipe
   up     20180306171402  Change flour to almond flour
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I find myself wondering, "where did migration 201803021132931 come from? Is it something I need to roll back for my current task?" When this happens, I need a way to figure out what the missing migrations do in order to track what work I need to do when I switch contexts. To solve this problem, I created a small Git extension, called &lt;a href="https://github.com/michaelherold/dotfiles/blob/8b3b472be89487111ddc742921e93f7b79542855/bin/git-find-migration"&gt;&lt;code&gt;git-find-migration&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  New workflow
&lt;/h2&gt;

&lt;p&gt;My workflow now for tracking these migrations across branches is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I change to the &lt;code&gt;upstream/master&lt;/code&gt; branch on Git. This gives me the context for the current state of what is running in production (n.b. I don't actually check out &lt;code&gt;upstream/master&lt;/code&gt;, but I sync my local copy of &lt;code&gt;master&lt;/code&gt; with it).&lt;/li&gt;
&lt;li&gt;Then, I run &lt;code&gt;g fm -l&lt;/code&gt; to list any migrations that have been run, but I am missing on the branch (n.b. I use a &lt;a href="https://github.com/michaelherold/dotfiles/blob/8b3b472be89487111ddc742921e93f7b79542855/zsh/functions/g"&gt;function called &lt;code&gt;g&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/michaelherold/dotfiles/blob/8b3b472be89487111ddc742921e93f7b79542855/bin/git-find-migration"&gt;aliased &lt;code&gt;git-find-migration&lt;/code&gt; to fm&lt;/a&gt; to make this easier to type).&lt;/li&gt;
&lt;li&gt;For each migration that I am missing, I copy the timestamp, then run &lt;code&gt;g fm &amp;lt;timestamp&amp;gt;&lt;/code&gt; to see the name of the file in my Git repository.&lt;/li&gt;
&lt;li&gt;Once I know the name of the file, I run &lt;code&gt;git log --all -- db/migration/&amp;lt;migration_file&amp;gt;&lt;/code&gt; to see the context for that file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This workflow allows me to easily make decisions to handle the migration. Sometimes, the migration is an old one that has since been pruned from the repository (not a suggested tactic, might I add!) and it's fine. Sometimes, it's something that I should roll back to continue my work. In that case, I check out the branch with the migration and run a &lt;code&gt;rails db:migrate:down VERSION=&amp;lt;timestamp&amp;gt;&lt;/code&gt; to roll it back&lt;sup id="fn-rollback-return"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shortcomings
&lt;/h2&gt;

&lt;p&gt;I could likely still make some improvements to this workflow. For example, I currently limit my script to searching for only a single timestamp at once. This was because I didn't want to figure out how to write the Git query that could find more than one. Perhaps that would speed along the process when I have several migrations that I need to roll back. This happens a lot when we're working on a multistage, backwards-compatible, destructive change.&lt;/p&gt;

&lt;p&gt;Even with these shortcomings, the new workflow serves me well. Feel free to &lt;a href="https://github.com/michaelherold/dotfiles/blob/8b3b472be89487111ddc742921e93f7b79542855/bin/git-find-migration"&gt;download the script&lt;/a&gt; if this sounds interesting! Do you have any techniques for managing migrations across multiple branches?&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://michaeljherold.com/2018/08/13/finding-rails-migrations/"&gt;Finding Rails migrations&lt;/a&gt; appeared first on &lt;a href="https://michaeljherold.com"&gt;Michael Herold&lt;/a&gt;.&lt;/p&gt;


&lt;ol&gt;
    &lt;li id="fn-rollback"&gt;You always make sure your migrations can be rolled back, don't you? ↩︎
&lt;/li&gt;
  &lt;/ol&gt;

</description>
      <category>rails</category>
      <category>git</category>
    </item>
    <item>
      <title>Creating a subset font</title>
      <dc:creator>Michael Herold</dc:creator>
      <pubDate>Mon, 04 May 2015 12:27:52 +0000</pubDate>
      <link>https://dev.to/michaelherold/creating-a-subset-font-4olf</link>
      <guid>https://dev.to/michaelherold/creating-a-subset-font-4olf</guid>
      <description>&lt;p&gt;Using custom font faces on a web page introduces several potential issues. Most commonly, these issues manifest in one of two types of problem: the dreaded “flash of unstyled text” (FOUT) or “flash of invisible text” (FOIT); or poor initial render time due to font faces specified in blocking calls to outside services. By placing only a subset font in the critical render path, you can reduce the amount of FOUT/FOIT and speed up the initial render performance.&lt;/p&gt;

&lt;p&gt;However, the creation of a subset font is not described anywhere that I found. This post discusses how I went about creating a subset font, the tools I used, and some thoughts on what exactly you should subset in your font.&lt;/p&gt;




&lt;p&gt;Zach Leatherman (&lt;a href="https://twitter.com/zachleat"&gt;@zachleat&lt;/a&gt;) has &lt;a href="http://www.zachleat.com/web/critical-webfonts/"&gt;talked&lt;/a&gt; &lt;a href="http://www.zachleat.com/web/web-font-data-uris/"&gt;a lot&lt;/a&gt; &lt;a href="http://www.zachleat.com/web/preload/"&gt;about font loading strategies&lt;/a&gt; lately. While I understood the theory of the posts, I ran into a very simple problem when trying to figure out how to implement it: I had no idea how to create a subset font. I wanted to try his idea of a “flash of faux text,” but I had no idea how to create a subset font.&lt;/p&gt;

&lt;p&gt;I spent a while looking into it and figured out a way to make one. This post goes through the method that I used and some background about what exactly you do when subsetting a font.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a font?
&lt;/h3&gt;

&lt;p&gt;A font is essentially a list of glyphs specified by addresses. If you are familiar with the ASCII table, you might remember that the letter &lt;em&gt;A&lt;/em&gt; corresponds to the number &lt;em&gt;45&lt;/em&gt;. That is, &lt;em&gt;A&lt;/em&gt; is at the &lt;em&gt;address&lt;/em&gt; &lt;em&gt;45&lt;/em&gt;. The font creator then encodes this list in one of the font formats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embedded OpenType (EOT)&lt;/li&gt;
&lt;li&gt;OpenType Font (OTF)&lt;/li&gt;
&lt;li&gt;TrueType Font (TTF)&lt;/li&gt;
&lt;li&gt;Web Open Font Face (WOFF)&lt;/li&gt;
&lt;li&gt;Web Open Font Face 2 (WOFF2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At its heart, each of these formats is just a table of addresses and glyphs. There are some niceties like anti-alias hinting and ligatures that are available in different formats, but the table is what I am interested in.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a subset font?
&lt;/h3&gt;

&lt;p&gt;Fonts with a small alphabet like Noto Sans in Balinese might only have ~47 glyphs, but if you need a font with the full Chinese-Japanese-Korean (CJK) glyph set you might be looking at hundreds or thousands of glyphs.&lt;/p&gt;

&lt;p&gt;A subset font tries to avoid this by only including the glyphs that are essential to show the most important content on a page. If you’re writing an English language website, you might only include the English alphabet and Arabic numerals: a total of 62 characters.&lt;/p&gt;

&lt;p&gt;The resulting file size of the subset font will be substantially smaller than the full-blown font. Currently on this site, I use a subset of the Noto Sans font for my website’s initial render. The subset font in the WOFF file format is 7.4KB on disk while the full font is 190KB. That’s a savings of 96.1% for the subset font.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can I create one?
&lt;/h3&gt;

&lt;p&gt;There are many tools out there (both open- and closed-source) for working with fonts. The one that I used to create my subset font is a Python library called &lt;a href="https://github.com/behdad/fonttools"&gt;fonttools&lt;/a&gt;. It has a few command-line utilities for manipulating font files. &lt;code&gt;pyftsubset&lt;/code&gt; is the tool for subsetting and optimizing fonts.&lt;/p&gt;

&lt;p&gt;There are myriad options available in this tool. In the interest of brevity, I only cover the options that I use in creating the subset font.&lt;/p&gt;

&lt;p&gt;I want to take a moment to mention that you should only do this with a font that you have permission to modify. In the case of this article, I modify the Noto Sans font from Google under the &lt;a href="https://github.com/google/fonts/blob/c698ee1cbe301f79e6fe80c8cde18cb084384292/ofl/notosans/OFL.txt"&gt;SIL Open Font License&lt;/a&gt;. This license allows modification and redistribution, much like the MIT License for open source code.&lt;/p&gt;

&lt;p&gt;Next, I list the command that I used, then discuss the options.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pyftsubset NotoSans-Regular.ttf \
    --unicodes="U+0020,U+0041-005A,U+0061-007A" \
    --layout-features="" \
    --flavor="woff" \
    --output-file="NotoSansSubset.woff"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, the &lt;code&gt;NotoSans-Regular.ttf&lt;/code&gt; file is the font file that I started from.&lt;/p&gt;

&lt;p&gt;Next, I specify the glyphs to include in the subset font using the &lt;code&gt;--unicodes&lt;/code&gt; option. I include only the Latin alphabet (i.e. the standard alphabet used when writing in English) and the space character. These correspond to the following Unicode addresses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;U+0020&lt;/code&gt; is the standard space&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;U+0041-005A&lt;/code&gt; are the capital letters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;U+0061-007A&lt;/code&gt; are the lowercase letters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, I list the layout features I include in the font using the &lt;code&gt;--layout-features&lt;/code&gt; option. These are things like ligatures that make the font more readable at the cost of file size. I commit a cardinal sin here and opt for none of them due to how I plan to use the font. Because I intend the page to only show this subset font as a “flash of faux text” I feel that leaving out the niceties is okay.&lt;/p&gt;

&lt;p&gt;Because of its relative space efficiency and &lt;a href="http://caniuse.com/#feat=woff"&gt;wide availability of 88.13% on Can I Use&lt;/a&gt;, I pick WOFF as the file format for the font using the &lt;code&gt;--flavor&lt;/code&gt; option. The subset tool can only output WOFF or WOFF2, but you can take the resulting file into another tool to get a TrueType or OpenType font if you want.&lt;/p&gt;

&lt;p&gt;Lastly, I save the resulting file as &lt;code&gt;NotoSansSubset.woff&lt;/code&gt; using the &lt;code&gt;--output-file&lt;/code&gt; option.&lt;/p&gt;

&lt;h3&gt;
  
  
  What tradeoffs are there?
&lt;/h3&gt;

&lt;p&gt;Subset fonts give you a smaller file to download to display &lt;em&gt;most&lt;/em&gt; of the important text on a page before the full fonts download. This means that you have to play a balancing game between font size and features.&lt;/p&gt;

&lt;p&gt;In an ideal world, you would serve web fonts that only contain the glyphs that you use on the first page, then rely on the full web font download afterward. However, if you want to serve up a static web page, this becomes tedious because you have to create a subset font for each page on your website. This means that it might be better to include more glyphs than you need on a page to cover a broader set of pages; basically, increasing the glyph count at the cost of a larger file size.&lt;/p&gt;

&lt;p&gt;The flip side of this is that you’re essentially forcing your visitors to download a glyph set twice: once in the subset font and once in the full web font. This is the crux of the balancing act. You don’t want to serve up more glyphs than is necessary because you want to cut the amount of repetitive data over the wire.&lt;/p&gt;

&lt;p&gt;I think a practical solution is to create one subset font that roughly follows the &lt;a href="https://en.wikipedia.org/wiki/Pareto_principle"&gt;Pareto principle&lt;/a&gt;: cover 80% of the content on a first render. Distilling this down to a glyph count, I think that when writing English a good subset font will include only the alphabet (or perhaps the alphabet and numerals).&lt;/p&gt;

&lt;p&gt;Including only the alphabet allows the site visitor to start reading at the earliest moment. He or she might notice some missing punctuation or numbers, but your page is still understandable without it. You might disagree, so pick your own subset using a different set of rules!&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrap up
&lt;/h3&gt;

&lt;p&gt;Now you know what a subset font is and how to create one. Subset fonts are simple in concept but it’s not immediately clear how to create one. By using tools like &lt;code&gt;fonttools&lt;/code&gt;, you can make it easy to subset your own fonts.&lt;/p&gt;

&lt;p&gt;Subset fonts are one small optimization to make in your web performance strategy. By sending a smaller number of glyphs along the critical render path of your website, you can improve the time to first render and avoid the problems of a “flash of invisible text” or “flash of unstyled text” by using the subset font to show a “flash of faux text”.&lt;/p&gt;

&lt;p&gt;However, subset fonts are only one piece of the puzzle for this technique. Doing this requires some client-side logic to do the font replacement. The next post in this series will discuss a strategy for doing this that I learned from the writings of &lt;a href="https://twitter.com/zachleat"&gt;Zach Leatherman&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://michaeljherold.com/2015/05/04/creating-a-subset-font/"&gt;Creating a subset font&lt;/a&gt; appeared first on &lt;a href="https://michaeljherold.com"&gt;Michael Herold&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
  </channel>
</rss>
