...

A Little About Me...

I'm a web application developer living in the mountains of Western North Carolina. Vim is my editor, and I <3 mechanical keyboards, my current daily is a Nyquist Rev3. Ruby is my language of choice, although I consider myself a full-stack polyglot developer. I like to try different craft beers, and I prefer IPAs, the hoppier the better! Citra hops are my favorite hops so much in fact I named my rescue pup Citra. If I'm not behind a keeb I'm typically outdoors hiking, MTN biking, taking pitures or just living my best life.

11 November 2022

New error reporting in rails 7

While working through a bug where we were getting duplicate errors reported by sidekiq in honeybadger I learned about a new feature that was released in rails 7, but wasn’t documented. Have you ever written some code like this example below where you want to rescue an exception and still report to your error reporting service like honeybadger or sentry?

begin
  do_something
rescue SomethingIsBroken => error
  MyErrorReportingService.notify(error)
end

Well a new feature was added in rails called Error Reporting, and now we have a simple consistent way of doing this in rails.

Rails.error.handle(SomethingIsBroken) do
  do_something
end

The code above will handle the error if do_something raises an error and rails will automagically send it to the reporting service you are using in your app. To create a subscriber for the error reporting you just create an intializer like this. As of now honeybadger and sentry both create a subscriber for you so you can skip this if you use either of them.

# config/initializers/error_subscriber.rb
class ErrorSubscriber
  def report(error, handled:, severity:, context:, source: nil)
    MyErrorReportingService.report_error(error, context: context, handled: handled, level: severity)
  end
end

Rails.error.subscribe(ErrorSubscriber.new)

Thats it, now you can use the consistent Rails.error.handle block when handling errors in your app and rails will make sure it gets sent to the subscribed error reporting service.

It will be in the docs for the next release of rails also, for now check out the rails error reporting docs in rails edge guides.

18 September 2022

Preloading associations with ActiveRecord::Associations::Preloader

The other day I was working to reduce the number of N+1 queries for different pages in a rails app. I found I needed to preload some associations for an object similar to current_user, so for this example we will just use current user. The current_user helper method is defined in the ApplicationController all other controllers that inherit from ApplicationController and their views have access to current_user. Most of the time we don’t need associations to be preloaded when working with current_user, but sometimes we do. Let’s say we want to get all of the current_user’s posts and all of the comments associated with each of the posts. If we try to override current_user to use includes it won’t work, we’ll get a no method error for includes on the instance of User.

# Will raise no method error since .includes is a class methtod
class UserPostsController < ApplicationController
  def index
    @posts = current_user.posts
  end
  
  private

  def current_user
    super.includes(posts: :comments)
  end
end

A better way I found is to use ActiveRecord::Associations::Preloader. Here we can pass records and the associations to preload for the records that were passed. Now there will only be a total of 3 queries for this page, one for the user, one for the user’s posts, and one for the post’s comments.

class UserPostsController < ApplicationController
  def index
    @posts = current_user.posts
  end

  private

  def current_user
    super.tap do |user|
      ActiveRecord::AssociationsPreloader.new(
        records: Array(user),
        associations: { posts: :comments }
      ).call
    end
  end
end
13 March 2018

Deploy Your Jekyll Site to Github Pages With Travis CI for Free

I’ve been using Jekyll for my blog for quite some time now. I have also had the deployment of it automated for just about as long. While doing some revamping and adding a new post a few weeks ago, I decided to update my deploy script I had written for Travis CI. I was looking through the docs for Travis and low and behold they have added the ability to deploy to Github pages with their dpl tool. The way I was doing it worked well, but Travis dpl makes it dead simple, and it can all be configured from a .travis.yml file in your project. Now my blog publishing work flow goes like this. Write a post in my source branch of my danielnolan.github.com repository. Commit the new post and push the source branch to Github. Travis is configured to kick off a build when new code is committed to the source branch on Github. Travis runs my default rake task for my jekyll project which generates the static html for my blog and then lints it using htmlproofer. If html-proofer doesn’t report any errors Travis deploys my generated html site to the master branch of danielnolan.github.com. If errors are reported by html-proofer the build fails and my site is not deployed. The best part about all of this is I’m able to host my site on Github pages and use Travis to deploy it because my blog code is open source, and lives in a public repository on Github.

04 March 2018

Asynchronously Linting Ruby and Haml in Vim8 or NeoVim

In the past I have used Syntastic in Vim for linting code while editing. Syntastic was good, but was too slow for large projects and often felt like it was slowing me down. ALE (Asynchronous Lint Engine) is a plugin for Vim8 and NeoVim that makes use of the new Asynchronous features introduced in Vim8 to allow linting as you type. Rather than linting a file when opening or saving like Syntastic, ALE will run the linter in the background asynchronously as you type. Not only is the feedback loop much tighter, it doesn’t bog Vim down while your editing. I have used Rubocop with Vim for linting Ruby for many years now, but never used it for view files. I just started with a new organization and they use Haml for views in the project that I am working on, so I was curious if there was a linter for Haml. Sure enough I found Haml-Lint and it ties in with Rubocop to bring the Ruby linting power of Rubocop to your Haml views. Both Rubocop and Haml-Lint will both work with zero configuration if you have ALE installed in Vim. Install instructions can be found in the links below, but it’s really as simple as installing both gems and adding the ALE plugin to Vim with your favorite plugin manager.

Links:
ALE
Rubocop
Haml-Lint