<?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[Nicholas Shirley]]></title><description><![CDATA[Nicholas Shirley]]></description><link>https://nicholasshirley.com/</link><image><url>https://nicholasshirley.com/favicon.png</url><title>Nicholas Shirley</title><link>https://nicholasshirley.com/</link></image><generator>Ghost 2.14</generator><lastBuildDate>Sun, 12 Apr 2026 13:40:14 GMT</lastBuildDate><atom:link href="https://nicholasshirley.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Verify That an ActiveRecord Object has at Least One Attribute]]></title><description><![CDATA[<p>Rails ActiveRecord callbacks make validation a breeze, but what happens if you want to verify that a record has at least one attribute present, but you don't care which attribute it is? This was a recent case I was working on for a client who was having their operators fill</p>]]></description><link>https://nicholasshirley.com/verify-that-an-activerecord-object-has-at-least-one-attribute/</link><guid isPermaLink="false">5cd3e4f2ad97d30fed01deb1</guid><category><![CDATA[Rails]]></category><category><![CDATA[ActiveRecord]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Thu, 09 May 2019 09:04:42 GMT</pubDate><content:encoded><![CDATA[<p>Rails ActiveRecord callbacks make validation a breeze, but what happens if you want to verify that a record has at least one attribute present, but you don't care which attribute it is? This was a recent case I was working on for a client who was having their operators fill in a form with a lot of uncertainty. They couldn't know which record would be needed, but we didn't want to allow all records to be blank.</p><h2 id="start-with-the-spec">Start with the Spec</h2><p>Let's describe the desired behavior in RSpect and FactoryBot first for an imaginary <code>Report</code> object.</p><pre><code class="language-ruby">spec/models/report_spec.rb

RSpec.describe Report, type: :model do
  # I set up all FactoryBot factories to build with the 
  # required fields. In this case no fields are actually
  # required so I sub them in whenever they are under test.
  # In this case the absensce case is under test, so no attribute
  # is passed

  let(:report) { FactoryBot.build(:report) }

  describe 'validations' do
    it 'requires at least one field to exist' do
      report.valid?

      # important: make sure you are looking for the custom
      # key that you create, not a generic error
      expect(report.errors[:report]).not_to be_empty
    end
  end
end
</code></pre>
<h2 id="build-the-custom-validator">Build the Custom Validator</h2><p>Rails offers two kinds of custom validators: <a href="https://guides.rubyonrails.org/active_record_validations.html#custom-validators"><code>Validator</code> and <code>EachValidator</code></a>. In this case, we want to pass in the entire record rather than a specific attribute, so we will go with <code>Validator</code>.</p><pre><code class="language-ruby">app/models/concerns/record_not_empty_validator.rb

class RecordNotEmptyValidator &lt; ActiveModel::Validator
  def validate(record)
    unless non_id_attributes(record).any? { |attr| record.attribute_present?(attr) }
      record.errors.add(record.model_name.human.downcase!, 'must contain at least one attribute')
    end
  end
  
  private
  
  def non_id_attributes(record)
    record.attribute_names.reject!{ |attr| attr.include?('_id') }
  end
end
</code></pre>
<p>This code uses some Rails convenience methods to first remove any attribute names which contain the substring <code>_id</code> (which is useful for models with associations because depending on how you build the objects this field may not be <code>nil</code>) and then checks that at least one of the remaining attributes have a value. One thing to note is that if you examine the object ancestor chain you don't have a lot of ActiveSupport modules to work with so <code>.human</code> was the best method I could find to transform the model name. It's not strictly necessary to downcase the resulting key because it will be capitalized when shown in the view regardless, but my specs all assume that keys are lowercase so I include it.</p><h2 id="include-it-on-the-model">Include it on the Model</h2><p>Finally, you just need to call the validator on the model itself.</p><pre><code class="language-ruby">app/models/report.rb

class Report &lt; ApplicationRecord
  validates_with RecordNotEmptyValidator
  ...
end
</code></pre>
<h2 id="handling-updates">Handling Updates</h2><p>The above code will work, but only for creating new objects. Let's say an object has been created and your user edits that object to remove all the fields. You would expect it to error, but it won't because there is now an <code>id</code> field that is not blank as well as <code>created_at</code> and <code>updated_at</code> fields (if you included timestamps in your migration).</p><p>To handle these we'll need to add some additional matchers: </p><pre><code class="language-ruby">app/models/concerns/record_not_empty_validator.rb

def non_id_attributes(record)
  record
    .attribute_names
    .reject!{ |attr| attr.include?('_id') }
    .reject!{ |attr| attr.include?('_at') }
    .reject!{ |attr| attr.match(/\bid\b/)
end
</code></pre>
<p>For the second reject statement, we'll assume that none of your real data fields include the <code>_at</code> suffix so we can match both <code>created_at</code> and <code>updated_at</code> fields. For the third, we will throw out any field that only contains <code>id</code> (which will only be the record primary key). </p><p>With those two additions you can now validate against updated records and all that's left to do is update the spec:</p><pre><code class="language-ruby">spec/models/report_spec.rb

RSpec.describe Report, type: :model do

  let(:report) { FactoryBot.build(:report) }
  # Assume report has a title field
  let(:saved_report) { FactoryBot.create(:report, title: 'title') }

  describe 'validations' do
  
    ...
  
    it 'precludes removing all fields' do
      saved_report.title = ''
      
      saved_report.valid?

      expect(saved_report.errors[:report]).not_to be_empty
    end
  end
end
</code></pre>
<p>If you are going to be doing this validation on a lot of models, you will probably want to pull this out into a shared example so it can included with one line.</p><p>As a final note: the docs indicate that you need <code>include ActiveModel::Validations</code> on the model, but I don't find that to be necessary.</p>]]></content:encoded></item><item><title><![CDATA[Learning Vim, the Long Way]]></title><description><![CDATA[Vim has changed the way I work in a massive positive way, but I spent over a year giving up and coming back before it finally stuck. This is what worked for me.]]></description><link>https://nicholasshirley.com/learning-vim-the-long-way/</link><guid isPermaLink="false">5c668aa6fb1d6b0c4f0df9a2</guid><category><![CDATA[Productivity]]></category><category><![CDATA[Tooling]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Sat, 16 Feb 2019 15:29:03 GMT</pubDate><content:encoded><![CDATA[<p>What does the long way mean? It means Vim didn't stick for me until well after a year of first trying to learn it. Multiple dips into Vim, especially if you can do it while your motivation is high, over a sufficient period of time, will lead to a tipping point. This is how I came to my own tipping point with Vim.</p>
<h2 id="whocares">Who Cares?</h2>
<p>To hear Vim users, and yes emacs users too, talk about how much they love their editors can really make you feel like you are missing out on something cosmically amazing. Personally, I thought it was 50/50 on whether they had actually unlocked something valuable or had Stockholm Syndrome after such a long period of suffering. But still, once you have watched someone who is amazingly productive in Vim, it's hard to get the thought out of your head that you could be (a lot) more productive. To watch someone accomplish in a few fluid keystrokes everything that they need before your hand can finish reaching for the mouse is awe inspiring in the singularly nerdy way that only those who write code into a terminal for a living (or fun) can be inspired.</p>
<p>But, you know why you're here. You want enlightenment. You want to hear it's worth it. All the time and the struggle and brain hurt of trying to remember what motion gets you where. You want to be done already. And you can be, but I would suggest that you take the long way to get there.</p>
<h2 id="dontdeletetheeditors">(don't) Delete the Editors!</h2>
<p>I'm sure you've heard deprivation stories before. What's a deprivation story? It's when a new analyst starts at a bank and to force them to learn Excel keyboard shortcuts their mice are taken away. For programmers it's uninstalling all other editors and forcing yourself to use Vim until you get good at it. If you go really deep it doesn't stop there either, I heard <a href="http://www.benorenstein.com/">Ben Orenstein</a> recommend once that you should lower your key repeat rate to force yourself to learn better navigation instead of using hjkl as a crutch. The path to enlightenment is never done.</p>
<p>For me, and I imagine if you're reading this, for you also, the deprivation angle didn't work. My theory on why it doesn't work is because if you are interested in using Vim you are probably interested in being more productive and a program that causes you to regress to what feels like your first touch typing lesson is frustrating. In the short term it's definitely counter productive.</p>
<p>But, I hear you say, I learned touch typing by just gutting it out and you can learn Vim this way to! This is, of course, technically true. I doubt you would quit your job if you could only use Vim and after a period of time you would become proficient with it. That period to proficiency would also probably be shorter, if more painful.</p>
<p>Why doesn't everyone do this?</p>
<p>One, we aren't starting from 0. When you first learned to touch type you had no other option to than to get through it (or live with your hunt and peck shame forever). This is the nature of beginning something wholly new. If you are already writing code though, typing isn't wholly new and Vim can represent a step backwards.</p>
<p>Second, for most of us this isn't a theoretical exercise (unless you are in college or otherwise have extra time on your hands, then I encourage you to try whatever drastic approaches you want), most of us have to produce things and if you're reading this blog, you probably have to produce characters, lots of them, in not enough time.</p>
<h2 id="whatworkedforme">What Worked for Me</h2>
<p>Here are the steps I took over the course of about a year that finally got me switch over to Vim full time:</p>
<ul>
<li><code>vimtutor</code>, got the basics, finally understand what this actually is</li>
<li>Try to use some Vim and a lot of Googling to write real files, give up when frustration reaches crtical mass, repeat for months</li>
<li>Try <a href="https://www.vimgolf.com/">VimGolf</a>, get more frustrated, decide Vim was a stupid idea anyway</li>
<li>Start popping open Vim for specific edits based on known skills, it's becoming a part of the toolset</li>
<li>Actually invest the time to manage <code>~/.vimrc</code>; amazement returns, but still far faster in old editor</li>
<li>Find a few plugins that handle specific annoyances, opening up Vim more and more</li>
<li>Discover something amazing (was <a href="https://github.com/ctrlpvim/ctrlp.vim">ctrlp</a> for file navigation for me); begin guessing at commands that &quot;should&quot; work and they do</li>
<li>Experience the tipping point: realize it would be faster to do something in vim, close other editor, vow to never come back</li>
<li>Realize that other editors are often still good for creating files, so, in the end, it's not all or nothing</li>
</ul>
<h2 id="thesecretdeliberatecustomization">The Secret: Deliberate Customization</h2>
<p>As I look back over that list I see someone grappling with the basics, gaining proficiency then finally mastery (then the final final step of realizing it's not some panacea that solves everything). What really made Vim worthwhile though was customization and plugins.</p>
<h3 id="startoutwithsomethingbutnottoomuch">Start Out With Something (but not too much)</h3>
<p>Customization will make any editor more comfortable. With Vim, however, I would argue you must customize to be productive. This isn't a new thought, there are a lot of bundles that dump in a bunch of config and customization into Vim all at once. The downside is that these bundles separate you from customizing Vim yourself. It becomes like just another editor with behavior you may not like, but limited ability to change (is that a Vim behavior or did it come from the bundle?). In the end you want your Vim config to be a special snowflake, your special snowflake.</p>
<p>After trying out some of the bigger config dumps, <a href="https://github.com/skwp/dotfiles/blob/master/vimrc">this was the one that worked for me</a>. It's not too big and the changes are nice QoL increases. One note, I would remove the <a href="https://github.com/skwp/dotfiles/blob/590bdc8bd42078c58451e87ec77b0c73c9834649/vimrc#L36">Vundle loader</a>. <a href="https://vimhelp.org/repeat.txt.html#packages">Vim packages</a> makes this unnecessary and if you are just starting out, I'd suggesting going this way as it seems like the future and is built in. <a href="https://shapeshed.com/vim-packages/">Here</a> you can read a longer discussion about packages.</p>
<h3 id="averyshortlistofthingstochangenow">A (very) short list of things to change now</h3>
<p>Here is a deliberately small number of things that I would change right now as you are experimenting with Vim:</p>
<ul>
<li>Remap capslock to escape. Esc just too far away and too small and you're going to be hitting it all the time (and you're out of luck if you have a Mac without one).</li>
<li>Remap your leader key. Mine is ',' but it doesn't matter what it is only that it's comfortable for you and your workflow.</li>
<li>Get a file navigation plugin (I use ctrlp, but find one you like). This alone will make you faster in Vim.</li>
<li>Take the time to groom your <code>wildignore</code> list. Don't waste time returning files you aren't going to open anyway.</li>
<li>Set a small number of leader commands that you will use right now. Work in Rails and always checking the schema? Try <code>map &lt;Leader&gt;db :sp db/schema.rb&lt;cr&gt;</code>. Work on files where spelling is important? <code>map &lt;Leader&gt;sp :setlocal spell spelllang=en_us</code>. Whatever you pick make sure you use them often so they stick. This will grow just like your alias list in bash.</li>
</ul>
<p>So take heart. You can learn vim. Just take a break when you need to. It will still be there when you come back.</p>
]]></content:encoded></item><item><title><![CDATA[Re-associate ActiveStorage attachments after changing a table name]]></title><description><![CDATA[Sometimes you have to change a table name. When you do, don't forget to update ActiveStorage relationships otherwise  your files will be orphaned.]]></description><link>https://nicholasshirley.com/re-associate-activestorage-attachments-after-changing-a-table-name/</link><guid isPermaLink="false">5c668aa6fb1d6b0c4f0df9a0</guid><category><![CDATA[Rails]]></category><category><![CDATA[ActiveStorage]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Thu, 26 Apr 2018 13:51:52 GMT</pubDate><content:encoded><![CDATA[<p>Quick and to the point: remember to re-associate <code>ActiveStorage::Attachment</code>s if you change a table name otherwise you won't see previously attached files.</p>
<p>Relationships are referenced by attachments with the <code>record_type</code> attribute where <code>record_type</code> is the name of the model. Here is an example attachment where the model name is <code>Training::Hike</code>:</p>
<pre><code class="language-ruby">#&lt;ActiveStorage::Attachment id: 8, name: &quot;files&quot;, record_type: &quot;Training::Hike&quot;, record_id: 1, blob_id: 9, created_at: &quot;2018-04-23 13:54:27&quot;&gt;
</code></pre>
<p>Once you update the table name (and the models and controllers and the file names etc etc) update the <code>record_type</code> with a simple query:</p>
<pre><code class="language-ruby">ActiveStorage::Attachment
  .where(record_type: 'Training::Hike')
  .update(record_type: 'Training::NewModelName')
</code></pre>
<p>Now you just have to update all those tests ;)</p>
]]></content:encoded></item><item><title><![CDATA[Deleting ActiveStorage Attachments From the Controller, 3 Ways]]></title><description><![CDATA[ActiveStorage in Rails 5.2 is awesome, but where do handle deleting attachments on the controller? Here are some possible options.]]></description><link>https://nicholasshirley.com/several-strategies-to-delete-activestorage-attachments/</link><guid isPermaLink="false">5c668aa6fb1d6b0c4f0df99f</guid><category><![CDATA[Rails]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Thu, 19 Apr 2018 20:04:41 GMT</pubDate><content:encoded><![CDATA[<p>ActiveStorage is by far the feature I am most excited about in Rails 5.2 (it was also the source of <a href="https://github.com/rails/rails/commit/f9a5839083e697f0d5aad6d9304cd5f26e2a7a11">my first bit of code</a> in Rails!). Now that 5.2 stable is out, I have been implementing it in a few apps, but already tripping over a few things, specifically, how to handle deleting attachments.</p>
<h2 id="howtodeleteattachments">How to delete attachments</h2>
<p>At the time of this writing, the Rails Edge Guide <a href="http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files">detailing removing attachments</a> is all of two sentences and two methods long. You can purge them now or you can purge them later. Note, for this post we will only talk about <code>purge</code> rather than <a href="https://github.com/rails/rails/blob/74525b26d2e2eee897707546b7d63e4fa6bdc0f1/activestorage/lib/active_storage/attached/many.rb#L43"><code>detatch</code></a> which calls <code>destroy_all</code> the attachments, but leaves the blob(s) intact.</p>
<p>For <code>has_many_attached</code> the default behavior of <code>purge</code> is to delete all the records (obviously the same is true of <code>has_one_attached</code>), however, you can target them for specific removal with any query. To get a better idea of how the objects are shaped, here is a Resource object which has two <code>:files</code> attached</p>
<pre><code class="language-ruby">Resource.last.files
#&lt;ActiveStorage::Attached::Many:0x00007f8ff866e470 @name=&quot;files&quot;, @record=#&lt;Resource id: 1, title: &quot;Testing&quot;, created_at: &quot;2018-04-17 16:30:29&quot;, updated_at: &quot;2018-04-17 16:30:29&quot;&gt;, @dependent=:purge_later&gt;

Resource.last.files.first
#&lt;ActiveStorage::Attachment id: 1, name: &quot;files&quot;, record_type: &quot;Resource&quot;, record_id: 1, blob_id: 1, created_at: &quot;2018-04-17 16:30:29&quot;&gt; 

Resource.last.files.last
#&lt;ActiveStorage::Attachment id: 2, name: &quot;files&quot;, record_type: &quot;Resource&quot;, record_id: 1, blob_id: 2, created_at: &quot;2018-04-17 16:30:29&quot;&gt;
</code></pre>
<p>The name assigned to each record is the one that you set in the model and will be the same for all attachments on that model. The specifics about the file itself are in the blob</p>
<pre><code class="language-ruby">Resource.last.files.first.blob
#&lt;ActiveStorage::Blob id: 2, key: &quot;9BG2pTG3S7Ms4jfVa9ysj33F&quot;, filename: &quot;Test_file.PDF&quot;, content_type: &quot;application/pdf&quot;, metadata: {&quot;identified&quot;=&gt;true, &quot;analyzed&quot;=&gt;true}, byte_size: 78618, checksum: &quot;kG/rsqFbw/BkHSSPYItqAg==&quot;, created_at: &quot;2018-04-19 19:17:27&quot;&gt; 
</code></pre>
<p>To remove all the attachments from either a has_one or has_many model, just target the attachment and call <code>.purge</code> on it. To get rid of a single attachment from a <code>has_many_attached</code> record, you can use a query:</p>
<pre><code class="language-ruby"># Directly
ActiveStorage::Attachment.find(1).purge

# Through a resource
@resource.files.find(params[:attachment_id]).purge
</code></pre>
<h2 id="whattodoaboutcontrollers">What to do about controllers</h2>
<p>For me, the above discussion is interesting, but only the start. Yes, you know can target attachments and purge them, but as soon as you sit down to wire this up to a user action you will be confronted with where exactly to put it.</p>
<p>Interestingly, this is not an issue that the other actions have. Creating attachments doesn't require anything extra on the <code>create</code> action. Updating attachments will work great on the <code>update</code> action as long as you remember that updating a <code>has_one_attached</code> relationship will destroy and replace the old file and updating on a <code>has_many_attached</code> will create a new attachment. Neither of those requires anything explicit to work for ActiveStorage other than whitelisting your attachment name.</p>
<p>Here are three options I see on where you can locate your attachment deletion responsibilities:</p>
<ul>
<li>a global attachments controller that handles all delete requests</li>
<li>a non-restful endpoint and method on the resource controller</li>
<li>a switch on the resources destroy action</li>
</ul>
<p>I think each has their pluses and minuses depending on your application and how closely you want to hew to REST.</p>
<h3 id="aglobalattachmentscontroller">A global attachments controller</h3>
<p>A global attachments controller keeps things nice and clean. For example, you send your deletes to <code>/attachments/:id</code>, dust off your hands and call it day. For many apps I can see this working. In some ways it kind of feels like this is a missing controller for ActiveStorage.</p>
<p>One disadvantage that comes to mind, however is that now the <code>destroy</code> method is separated from any before filters, authorizations or controller logic specific to the resource controller. This may or may  not matter to you, depending on your use of callbacks.</p>
<p>A second disadvantage is that it's not quite as simple as just passing in the ID in the case where you want to purge only one record from as <code>has_many_attached</code> model. You could handle this in a number of ways, but it seems certain to involve some conditional logic.</p>
<h3 id="anonrestfulendpoint">A non-RESTful endpoint</h3>
<p>This was the first tool I pulled for when thinking about this issue. It makes your routes a little messier and there's another method in the controller, but all-in-all, it's not so bad. And, if you're making one endpoint, you might as well make 2 and then you can handle purging all attachments and selectively purging attachments without conditionals. This way you also get any controller specific callbacks and methods.</p>
<p>The reason I moved away from this, and I think it's primary disadvantage if you aren't worried about being completely RESTful, is that I had a lot or models that were handling files and building in this endpoint to each one was feeling like a lot of repeated work. I could still see it being worth it if you are doing a lot of controller specific work depending on where the delete was coming from, but in my case, all the destroy actions were the same.</p>
<h3 id="switchontheresourcesdestroymethod">Switch on the resource's destroy method</h3>
<p>For this approach, you don't have to mess with your routes or manage additional methods. I built mine to pick up on an <code>[:attachment_id]</code> param or a <code>[:purge]</code> param. If it's present, it handles the attachment(s), if not, it destroys the resource just like always.</p>
<p>Here is an example of a <code>has_many_attached</code> model:</p>
<pre><code class="language-ruby"># handle selective purge
if params[:attachment_id]
  @resource.files.find_by_id(params[:attachment_id]).purge
  ...
# handle purge all
elsif params[:purge]
  @resource.files.purge
  ...
# handle destroy resource
else
  @resource.destroy
  ...
end
</code></pre>
<p>The disadvantage is you need to deal with a conditional and it feels a bit like hijacking the destroy method, but for my current use case it's been pretty manageable.</p>
]]></content:encoded></item><item><title><![CDATA[Retrieve Associated Parent Attributes from Child Record in Rails]]></title><description><![CDATA[Calling attributes of associated records isn't "directional". Or, how I learned to stop worrying and love foreign keys.]]></description><link>https://nicholasshirley.com/retrieve-associated-parent-attributes-from-child-record-in-rails/</link><guid isPermaLink="false">5c668aa6fb1d6b0c4f0df99e</guid><category><![CDATA[Rails]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Fri, 13 Apr 2018 12:44:05 GMT</pubDate><content:encoded><![CDATA[<p>I'll file this one under &quot;things everyone else probably already knew, but I just found out and it is awesome!&quot; In a one-to-many (or one-to-one) relationship you can pull an associated parent attribute directly from the child record without an additional explicit lookup.</p>
<pre><code class="language-ruby">child.parent.parent_attribute
</code></pre>
<p>Meta-note: parent/child metaphors are not 100% apt for SQL and break down in a lot of examples. Below are &quot;children&quot; that all have a foreign key referencing their &quot;parent&quot;.</p>
<h2 id="aexample">A Example</h2>
<p>You are creating two records: Meeting, which only has a date and MeetingPresentation, which will carry some other information, but isn't important for this example.</p>
<pre><code class="language-ruby">class Meeting &lt; ApplicationRecord
  has_many :presentations, dependent: :destroy
end
</code></pre>
<pre><code class="language-ruby">class MeetingPresentation &lt; ApplicationRecord
  belongs_to :meeting
end
</code></pre>
<p>Now, let's say you want to loop over all the presentations in an index view, but you also want to display the meeting date attached to them. Getting the date is super simple:</p>
<pre><code class="language-ruby">&lt; @presentations.each do |presentation| %&gt;
    &lt;%= presentation.meeting.date %&gt;
&lt;% end %&gt;
</code></pre>
<p>A more complex example might be if you want to perform some kind of validation on the parent attribute before displaying. For example, assume that users are not allowed to edit a presentation on the meeting date or after. Using the validation module <a href="https://www.nicholasshirley.com/cancan-cant/">discussed here</a>, you can selectively not show them the edit button like so*:</p>
<pre><code class="language-ruby">&lt; @presentations.each do |presentation| %&gt;
    &lt;%= presentation.title %&gt;
    
    &lt;% if authorized?(:edit) &amp;&amp; presentation.meeting.date.future? %&gt;
      &lt;%= link_to edit_presentation_path(presentation) %&gt;
    &lt;% end %&gt;
&lt;% end %&gt;
</code></pre>
<p>*obviously you want to lock this down in the model too with a validation, not showing the button is just a convenience</p>
<h2 id="whywasthisconfusing">Why Was This Confusing</h2>
<p>If you already knew this, I imagined you stopped reading by now, but if you're still here, I think it's worth asking, why wasn't this obvious to me (and maybe you). For me, I had viewed ActiveRecord one-to-many objects as linear associations which only flowed downward because all the manipulation that I was doing to them involved linear parent -&gt; child modifications.</p>
<p>If you have two objects set up like the example above and you try to save <code>MeetingPresentation.new(title: 'title')</code> it will error because you haven't told it what meeting it's attached to. You can manually pass in the <code>meeting_id</code> as part of the hash, but more realistically, you will define a meeting and then build the relationship so that you don't need to know what that <code>meeting_id</code> is:</p>
<pre><code class="language-ruby">@meeting = Meeting.find(params[:id])
@meeting.meeting_presentations.create(title: 'a title')
</code></pre>
<p>Additionally, when you want to manipulate an already created record, you most often call either the record itself or, if it's a collection of records, that collection from the parent. Though it's possible to edit a parent relationship from the child, it's probably not advisable to do so unless you have thought out your specific use case. For example, the following will work:</p>
<pre><code class="language-ruby">presentation = MeetingPresentation.last
presentation.meeting.update(date: 5.days.from_now)
</code></pre>
<p>If there were 3 other presentations associated with that meeting, &quot;their&quot; dates (through the parent) have also been changed. Again, there may be a specific reason do make this change like this, but I think it should be carefully considered.</p>
<p>This was my mental model before. After closer examination though, this should make sense. Whether you are calling the parent or child, you are really just calling an <code>_id</code>. In this frame of mind, it doesn't matter which &quot;direction&quot; things are going. In fact, the idea of directionality doesn't make sense (and neither does the parent child analogy, really).</p>
<h2 id="howtomakeuseofthisbehavior">How to make use of this behavior</h2>
<h4 id="displayinginformationintheview">Displaying information in the view</h4>
<p>Displaying parent info, as in the above example, is useful if you have normalized your DB so that there is little duplicated information and a lot of ID references. Instead of doing a DB lookup in the view or declaring additional variables in the controller, you can just simply call and display the parent attribute from the child.</p>
<h4 id="links">Links</h4>
<p>If you have nested resources you will need to pass in both the parent and child IDs when targeting a child record. Collections (like an index of child records), may or may not need to display parent records. Extending the example above, imagine we want to show all the presentations organized alphabetically regardless of meeting date and give users buttons to edit and delete them. Assume that the loop variable is <code>|presentation|</code> and that presentations are the lower nested resource, you can call links as:</p>
<pre><code class="language-ruby">&lt;%= link_to edit_meeting_presentation_path(presentation.meeting, presentation) %&gt;
</code></pre>
<h4 id="validations">Validations</h4>
<p>In the validation example I said you should lock down the model as well as not show the link. One way you can do that would be an ActiveRecord hook that makes use of the parent attribute:</p>
<pre><code class="language-ruby">class MeetingPresentation &lt; ApplicationRecord
  validate :verify_valid_meeting_date, on: [:create, :update]
  
  private
  
  def verify_valid_meeting_date
    unless self.meeting.date.future?
      errors.add(
        :meeting_presentation, 
        'cannot be created on or after a meeting has taken place')
    end
  end
end
</code></pre>
<h4 id="parentupdate">Parent update</h4>
<p>Okay, yes I said this wasn't a good idea, but I thought I would lay out a hypothetical in which this might be what you want to do (it's admittedly a bit contrived). Let's keep with the meetings and presentations example. Users give many presentations and some of those presentations may be classified. They are also the only ones who are allowed to modify the presentations which they own (but not the meeting directly). For some record keeping authority, you need to classify any meeting which contains classified presentations as such.</p>
<p>At this point you can just loop through all the children to see if any presentations are classified and return a true/false on whether the meeting is classified, however users may mark their presentations declassified at a later date and the record keeping authority requires that any meeting which ever contained any classified presentations remain categorized as such (I told you it was a bit contrived, though I have seen some business requirements that are worse).</p>
<p>Now we set Meeting to have a <code>has_classified</code> boolean that defaults to false and update that any time a user submits a presentation with a boolean of <code>is_classified</code> equal to true.</p>
<pre><code class="language-ruby">class MeetingPresentation &lt; ApplicationRecord
  after_commit :mark_meeting_classified
  
  private
  
  def mark_meeting_classified
    if self.is_classified
      self.meeting.update(has_classified: true) unless self.meeting.has_classified
    end
  end
end
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Error Better: Effectively Utilize Active Model Errors with Rails in API Mode]]></title><description><![CDATA[Go beyond delivering just full_messages in Rails to send well formatted error messages using Rails API]]></description><link>https://nicholasshirley.com/error-better/</link><guid isPermaLink="false">5c668aa6fb1d6b0c4f0df99d</guid><category><![CDATA[Rails]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Mon, 26 Mar 2018 08:39:54 GMT</pubDate><content:encoded><![CDATA[<h1 id="therighttoolforthejob">The Right Tool for the Job</h1>
<p>It happens to all of us sometimes. We find a really useful tool and, once found, we keep reaching for it over and over again even when it might not be the best fit for the problem we want to solve. Sometimes it's worth going back to the docs to see if there is a better solution when your environment changes.</p>
<p>My most recent experience with this was Rails <code>full_messages</code> method. Since I started learning Rails using <a href="https://www.railstutorial.org/">Michael Hartl</a>'s book, I have been building controllers with branching logic to handle validation errors and wondering at the magic of it all. When you combine <code>full_messages</code> with the traditionally rendered pages and flash it makes displaying an unknown number of errors to the user really convenient.</p>
<p>The difficulty came when I started stripping out ERB in favor of Vue and running Rails in API mode. Now, delivering a bunch of strings in an array that gets dumped into a div seems like a gross underutilization of what's possible. Even something as simple as placing the error under the field that has failed validation requires a bunch of extra work (e.g. RegEx), but why work harder than you have to.</p>
<p>Here is how to leverage Active Model errors to deliver usefully formatted JSON objects to your front-end framework.</p>
<h1 id="activemodelerrors">Active Model Errors</h1>
<p>First let's take a look at what error methods are available. The <a href="http://api.rubyonrails.org/classes/ActiveModel/Errors.html">Active Model Errors</a> pages is a great resource for seeing all the things you can do with error messages, but let's focus on the subset of error messages that return messages as key/value pairs and how they are formatted.</p>
<h2 id="whatareactivemodelerrorsanyway">What are ActiveModel Errors anyway?</h2>
<p>If an ActiveModel validation fails, it delivers an <code>ActiveModel::Errors</code> object, the most relevant portion being the <code>@messages</code> variable. Here is a simple example for a made up model called <code>Item</code>:</p>
<pre><code>#&lt;ActiveModel::Errors:0x00007fe63fcff710 
  @base=#&lt;Item id: nil, name: nil, user_id: 15, created_at: nil, updated_at: nil&gt;, 
  @messages={:name=&gt;[&quot;can't be blank&quot;]},  
  @details={:name=&gt;[{:error=&gt;:blank}]}&gt;
</code></pre>
<p>You will also notice that there is an <code>@details</code> hash that will also give the type of error. This could be useful if you don't like the ActiveModel errors text and want to display your own text on the front end after matching on the error type (which is way more convenient than writing your own error messages in the controller).</p>
<h2 id="sendingerrors">Sending errors</h2>
<p>To send the errors as key/value pairs, you can call <code>.to_hash</code> or <code>.as_json</code> which are defined in <a href="https://github.com/rails/rails/blob/0951306ca5edbaec10edf3440d5ba11062a4f2e5/activemodel/lib/active_model/errors.rb#L354">ActiveModel::Errors</a>. Though it's not documented, you can also use <code>to_json</code> which will result in the same output, but doesn't allow you to use <code>full_messages</code> as shown below.</p>
<p><em>Note</em>: You might be tempted to call the ruby method <code>to_h</code> on item like <code>@item.errors.messages.to_h</code> which will return the key/value pairs with a string as the value, but doing this will ignore any validation messages after the first one which is fine if you only have one validation, but makes your controller brittle to changes in the future.</p>
<h2 id="addingdetail">Adding detail</h2>
<p>The nice thing about both the <code>to_hash</code> and <code>as_json</code> methods is that they will take an optional argument to set the value of <code>full_messages</code>. Like the <code>full_messages</code> method mentioned at the top, this will include both the name of the object as well as the validation failure in human readable format. The useful thing here is that it is still tied to the object name as the key so your front-end doesn't need to do anything other than display the message(s) after matching on the key.</p>
<p>To include <code>full_messages</code> call errors like this:</p>
<pre><code class="language-ruby">@item.errors.to_hash(true)
  or
@item.errors.as_json(full_messages: true)
</code></pre>
<p>which will deliver a hash shaped like this:</p>
<pre><code class="language-json">{
  &quot;name&quot;: [
      &quot;Name is too long (maximum is 2 characters)&quot;,
      &quot;Name has already been taken&quot;
  ]
}
</code></pre>
<h3 id="alittlebitofcleanup">A little bit of cleanup</h3>
<p>Personally, I like to wrap my error messages in an error key this way the front end gets not only an HTTP error code, but also an explicit error hash.</p>
<pre><code class="language-ruby">if @item.save
  ... do stuff ...
  }
else
  render status: 422, json: {
    errors: @dealsheet_view.errors.to_hash
  }
end
</code></pre>
<p>This is one way to return formatted errors as JSON, but of course, that's not the end of things. Once you see that <code>ActiveModel::Errors</code> is returning two hashes with differing levels of detail, there is really no limit to how you can manipulate this output to get exactly what you want for your use case.</p>
]]></content:encoded></item><item><title><![CDATA[Using Font Awesome 5 in the Rails Asset Pipeline with Turbolinks]]></title><description><![CDATA[Want to use Font Awesome 5 with the Rails Asset Pipeline and Turbolinks? Read on to find out what you need.]]></description><link>https://nicholasshirley.com/using-font-awesome-5-and-the-rails-asset-pipeline/</link><guid isPermaLink="false">5c668aa6fb1d6b0c4f0df99c</guid><category><![CDATA[Rails]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Mon, 26 Feb 2018 20:05:26 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://fontawesome.com">Font Awesome</a> is a pretty indispensable part of any project for me and I finally decided to show my appreciation and buy a year's  pro subscription. I was looking forward to using the &quot;light&quot; icons (as far as I can tell these are the only icons which are limited to the pro subscription), but I soon hit some road blocks on setting it up in the Rails asset pipeline.</p>
<p>If you have been following Font Awesome's development, you have probably seen the shiny new version 5 which changes the recommended way to include the icons. The <a href="https://fontawesome.com/how-to-use/svg-with-js">How to Use</a> section provides some great documentation, but sadly a Rails walkthrough is not to be found.</p>
<p>So, here's what we're going to set up:</p>
<ul>
<li>Download and serve only the light theme to save on file size</li>
<li>Fix a gotcha when using Turbolinks that keeps icons from displaying on every page</li>
</ul>
<h2 id="downloadandsavefiles">Download and save files</h2>
<p>When you download Font Awesome and unzip the files, you will see quite a few folders in the tree. The two you need are:</p>
<ul>
<li><code>fontawesome-pro-#{version}/svg-with-js/js/fontawesome.js</code></li>
<li><code>fontawesome-pro-#{version}/svg-with-js/js/fa-light.js</code> (or whatever specific style you want to include)</li>
</ul>
<p>Copy these two files into your <code>app/assets/javascripts/</code> folder. I'm, assuming that you are going to run these through Uglifier so there's no reason to opt for the minified versions.</p>
<p>To test that this is working, throw an <code>&lt;i class=&quot;fal fa-user&quot;&gt;&lt;/i&gt;</code> onto a page and see it display.</p>
<h2 id="makefontawesomeplaynicewithturbolinks">Make Font Awesome play nice with Turbolinks</h2>
<p>First and foremost, credit to <a href="http://michael.minton.io/2018/01/using-font-awesome-5-with-rails-5-turbolinks.html">Michael Minton</a> for posting a coffee-script example of how to do this (he also has a solution for layout shifting you should check out).</p>
<p>It won't be too long before you realize that you sweet Font Awesome icons are not displaying on every page, but only the first time the page is loaded (or refreshed). The problem (or complication if you prefer less accusatorial language) is Turbolinks. To fix this, you want Font Awesome to re-render the icon whenever the <code>turbolinks:load</code> event is triggered.</p>
<p>Add a new file with the following (<em>note</em>: I added jQuery back into my project to use with Bootstrap):</p>
<pre><code class="language-javascript">(function() {
  $(document).on(&quot;turbolinks:load&quot;, function() {
    return FontAwesome.dom.i2svg();
  });

}).call(this);
</code></pre>
<p>Alternatively, if you are using CoffeeScript, you can use Michael's example linked above.</p>
<p>So, there you go, Font Awesome Pro in the Rails asset pipeline using just the files you need. You could get the file size even smaller if you go through and delete the SVGs of the icons you aren't using, but I'll leave that up to you.</p>
]]></content:encoded></item><item><title><![CDATA[User authorization without cancan(can)]]></title><description><![CDATA[Building custom user authorization that integrates into Devise's current_user helper.]]></description><link>https://nicholasshirley.com/cancan-cant/</link><guid isPermaLink="false">5c668aa6fb1d6b0c4f0df99b</guid><category><![CDATA[Rails]]></category><category><![CDATA[Code Examples]]></category><category><![CDATA[User Authorization]]></category><dc:creator><![CDATA[Nicholas Shirley]]></dc:creator><pubDate>Wed, 21 Feb 2018 18:42:27 GMT</pubDate><content:encoded><![CDATA[<p>Update 10 April 2018: I changed the code on <code>application_controller</code> to accept a controller name as well as an action so you can check if a user is authorized to perform an action from any view.</p>
<p>Update 17 April 2018: At the bottom of this post, you will find modifications that will let you use this with namespaced classes.</p>
<p>I was recently working on a project that needed user authorization. I knew people who had used cancan before with some success so I started by looking through the repo and trying a small scale test. There were a few problems that made the gem not a perfect fit which I'll run through below as well as the solution I came up with.</p>
<p>Situation:</p>
<ul>
<li>Every resource behind the login page has a differing level of authorization</li>
<li>There are at least 5 groups who have different permissions for different resources</li>
<li>Users can belong to more than one group</li>
<li>I only want to maintain one user model that can easily move members from one group to another</li>
</ul>
<h2 id="optionswithcancan">Options with cancan</h2>
<p>It is possible to do one user model with multiple roles in cancan. The wiki lists a <a href="https://github.com/ryanb/cancan/wiki/Role-Based-Authorization#many-roles-per-user">walk through</a> on how to set this up, but this seemed a little involved and not exactly in keeping with the main use case from the Readme. Someone has extracted this model  into a <a href="https://rubygems.org/gems/role_model">gem</a> but it hasn't been updated in a few years and using a gem on top of a gem seemed to validate my gut feeling that this was more complicated than it needed to be.</p>
<h2 id="implementingitmyself">Implementing it myself</h2>
<h3 id="goals">Goals</h3>
<ol>
<li>One user model, multiple roles</li>
<li>A permissions hash that is easy to scan and modify</li>
<li>A simple <code>before_action</code> on the controllers to check authorization</li>
<li>A view helper that can conditionally display items based on the current users level of permission</li>
</ol>
<h3 id="goal1assigningroles">Goal 1: Assigning roles</h3>
<p>I was already using Devise for user authentication so I added a user role column to the model for roles.</p>
<pre><code class="language-ruby">db/migrations/...

class AddRoleToUsers &lt; ActiveRecord::Migration[5.2]
  def change
    add_column :users, :role, :string, array: true, default: []
  end
end
</code></pre>
<p>In the future I thought we might want to have the option to initialize users with a different class so I set up a <code>before_save</code> hook on the <code>User</code> model instead of defaulting the role in the migration.</p>
<pre><code class="language-ruby">app/models/user.rb

class User &lt; ApplicationRecord
  before_save :assign_user_role
  
  private
  
  def assign_user_role
    self.role.push('user') unless self.role.include?('user')
  end
</code></pre>
<p>Now we can create users with roles and know that they will always be at least assigned the role of 'user' and we don't duplicate that role if it's passed in create.</p>
<h3 id="goal2permissionshash">Goal 2: Permissions hash</h3>
<p>I wanted the permissions hash to be easy to scan at a glance and see what groups were authorized to do what. Moreover, I wanted it to be easy to call using the <code>current_user</code> helper that comes built in with Devise.</p>
<p>To do this, I created a module that can be mixed in to <code>User</code>.</p>
<pre><code class="language-ruby">lib/modules/policy.rb

module Policy
  # All members are users therefore any action for which a user is authorized
  # can be performed by all members

  def authorize(role, controller, action)
    policies = {
      wiki: {
        show: %w[user],
        index: %w[user],
        edit: %w[admin moderator],
        update: %w[admin moderator],
        new: %w[admin moderator],
        create: %w[admin moderator],
        destroy: %w[admin moderator],
        dynamic: %w[user]
      }
  if !((policies[controller.to_sym][action.to_sym] &amp; role).empty?)
      return true
    else
      return false
    end
  end
end      
</code></pre>
<p>The hash is pretty easy to scan. You can see at a glance what the controller is and what the actions are. In this case, we have 7 RESTful actions as well as one custom action that gathers up wiki topics dynamically.</p>
<p>To authorize the user, it looks up the controller and action in policies, then uses <code>&amp;</code> to check for set intersection, call <code>.empty</code> and negate the result using <code>!</code>. If the set intersection finds any roles in common, <code>.empty</code> will return false which means the user is authorized in our case, so we use the bang to negate and it reads a bit more naturally since authorize should return true if the user role is contained in the authorized roles.</p>
<p>Then, include the module on <code>User</code></p>
<pre><code class="language-ruby">app/models/user.rb

class User &lt; ApplicationRecord
  include Policy
  before_save :assign_user_role
  ...
</code></pre>
<p>If you like to save your modules under <code>/lib</code> remember to include it in the auto-load path</p>
<pre><code class="language-ruby">config/application.rb

...
config.autoload_paths += %W(#{config.root}/lib/modules)
...
</code></pre>
<h3 id="goal3asimplebefore_action">Goal 3: A simple <code>before_action</code></h3>
<p>Before the <code>before_action</code> can be called it first needs to be defined. In this case, every action in the site requires authorization so I defined the action on <code>ApplicationController</code></p>
<pre><code class="language-ruby">app/controllers/application_controller.rb

def authorized?(action=&quot;#{action_name}&quot;, controller=&quot;#{controller_name.singularize}&quot;)
    current_user.authorize(current_user.role, controller, action)
end

def authorize
  redirect_to unauthorized_path unless authorized?
end
</code></pre>
<p>This takes advantage of string interpolation to take the values being passed around from the controller name and controller action.</p>
<p>Jumping ahead just a bit, you can see that I set a default value for action and controller so it can be called on the controller without any arguments, but still have the option to pass a specific action and controller in the view. <code>redirect_to</code> could have been called directly on the <code>authorized?</code> method if you don't need this, but by separating them out you will be able to use <code>authorized? :edit</code> as a view helper later or <code>authorized? :edit, :controller_name</code> if you want to check against another controller.</p>
<p>Now on the controller a simple <code>before_action</code> is needed:</p>
<pre><code class="language-ruby">app/controllers/your_controller.rb

class WikisController &lt; ApplicationController
  before_action :authorize
  ...
</code></pre>
<h3 id="goal4aviewhelper">Goal 4: A view helper</h3>
<p>All the above works great to lock down your controller actions, but you don't want users to constantly be being sent to an unauthorized page every time they click on a link they don't have the permissions to do anything with. To clean this up using the <code>authorized?</code> method, it is first necessary add <code>authorized?</code> as a helper method:</p>
<pre><code class="language-ruby">app/controllers/application_controller.rb

...
helper_method :authorized?
...
</code></pre>
<p>Now, let's say in the view you have some users who are allowed to edit entries, some that are allowed to delete them and some that can do neither, this has you covered.</p>
<pre><code class="language-ruby">app/views/controller_name/show.html.erb

&lt;%= @item.title %&gt;

&lt;% if authorized? :edit %&gt;
  &lt;%= link_to edit_item_path(@item) %&gt;
&lt;% end %&gt;

&lt;% if authorized? :delete %&gt;
  &lt;%= button_to &quot;Delete&quot;, { action: &quot;destroy&quot;, id: @item.id }, method: :delete %&gt;
&lt;% end %&gt;
</code></pre>
<p>As written, this will default to the controller that is behind that view, but I find it useful on pages that are collecting different links to be able to authorize against a different controller. For example, if your show or index page is pulling in any associated data, you can drop an edit or delete button for that association and save the user a page load.</p>
<pre><code class="language-ruby">&lt;% if authorized? :edit, :controller_name %&gt;
  &lt;%= link_to edit_item_path(@item) %&gt;
&lt;% end %&gt;
</code></pre>
<p>Update: One things that I ran into while using this is is does not work with namespaced classes. The reason it doesn't work with namespaced classes is that the method <code>controller_name</code> that is used on the original example actually <a href="https://github.com/rails/rails/blob/f03889136adc01c202b17a14562fbd9a72db9997/actionpack/lib/action_controller/metal.rb#L129">strips outs modulization</a>. PS: learning that Rails has a <a href="http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-demodulize"><code>demodulize</code></a> method was a surprise for me; it seems like there are many weird and wonderful things in ActiveSupport.</p>
<p>Not the most elegant way, but this will make namespaced classes work:</p>
<pre><code class="language-ruby">def authorized?(action=&quot;#{action_name}&quot;, controller=&quot;#{self.class.to_s.gsub('::', '_').gsub('Controller', '').underscore.singularize.downcase}&quot;)
    current_user.authorize(current_user.role, controller, action)
  end
</code></pre>
]]></content:encoded></item></channel></rss>