The Highlander query with Rails’ ActiveRecord

For those cases in which there can be one and only one record on the database with certain fields and I don’t just want to get the first one and silently get the wrong one. I want to make sure there’s one and only one, so, I wrote this little extension to ActiveRecord that does exactly that:

module ActiveRecordExtension
  extend ActiveSupport::Concern

  class_methods do
    def one_and_only
      records = limit(2).all.to_a
      if records.count > 1
        raise "#{self} generated more than one record when expecting only one."
      else
        records.first
      end
    end

    def one_and_only!
      one_and_only.tap do |record|
        if record.nil?
          raise "#{self} didn't generate any records."
        end
      end
    end
  end
end

ActiveRecord::Base.send(:include, ActiveRecordExtension)

The first method, one_and_only, will raise an exception if there’s more than one item but it’ll return null if there aren’t any. one_and_only! will fail if there isn’t exactly one and only one record in the database.

If you don’t know why I’m calling this The Highlander query, you should go and watch Christopher Lambert’s masterpiece.

Left grouping label with Simple Form and Bootstrap 3

If you are using Simple Form and Bootstrap 3, you probably initialized your app with something similar to:

rails generate simple_form:install --bootstrap

which adds a file called simple_form_bootstrap.rb to your application with many customizations that make Simple Form output nicely formatted Bootstrap 3 forms.

For Call to Buzz, an app I’m building, I had several booleans to display, like this:

Call to Buzz booleans

My problem was that I wanted a label to explain what those booleans are, something like this:

Call to Buzz booleans with label

I achieved that by creating a wrapper that’s a mix between :horizontal_boolean and horizontal_radio_and_checkboxes which I called horizontal_boolean_with_label and looks like this:

config.wrappers :horizontal_boolean_with_label, tag: "div", class: "form-group", error_class: "has-error" do |b|
  b.use :html5
  b.optional :readonly

  b.use :label, class: "col-sm-3 control-label"

  b.wrapper tag: "div", class: "col-sm-9" do |wr|
    wr.wrapper tag: "div", class: "checkbox" do |ba|
      ba.use :label_input
    end

    wr.use :error, wrap_with: {tag: "span", class: "help-block"}
    wr.use :hint, wrap_with: {tag: "p", class: "help-block"}
  end
end

Storing SMTP credentials in secrets.yml in a Ruby on Rails Application

Rails 4.1 introduced the concept of secrets.yml, a file in which you store all the credentials for your app, separated by environment, so for example, development can talk to Test Stripe and production to Live Stripe. Furthermore, this file is capable of picking up environment variables which allows you to divorce credentials from code. Not properly separating credentials from code recently cost Uber the leakage of 50,000 driver names and license numbers.

At Qredo we are very strict about handling credentials, including the ones for SMTP, which in Rails projects are normally stored in config/environments/development.rbconfig/environments/production.rb, etc. Trying to read Rails.application.secrets from those files doesn’t work, because they are loaded before the secrets, so, we came up with this alternative solution.

The environment files that need to use SMTP for delivering email have this common configuration:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
    address: "smtp.example.com",
    port: 587,
    authentication: "plain",
    enable_starttls_auto: true
}

and then, on config/initializers/email.rb we finish configuring our SMTP credentials by reading it from secrets.yml:

if ActionMailer::Base.delivery_method == :smtp
  ActionMailer::Base.smtp_settings[:domain] = Rails.application.secrets.smtp_domain
  ActionMailer::Base.smtp_settings[:user_name] = Rails.application.secrets.smtp_user_name
  ActionMailer::Base.smtp_settings[:password] = Rails.application.secrets.smtp_password
end

In config/secrets.yml you need set those credentials:

development:
  secret_key_base: 123...
  smtp_domain: example.org
  smtp_user_name: postmaster@oderq.com
  smtp_password: <%= ENV["SMTP_PASSWORD"] %>

test:
  secret_key_base: c7f3f62597b14c7287d75c239168fd3a89d3a6cb51beb909679c2609e912aaa3ca0a0aa5df2e191648baed6fe49698527a75dd265d222697576405971f478c98

staging:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  smtp_domain: example.net
  smtp_user_name: staging_user@example.net
  password: <%= ENV["SMTP_PASSWORD"] %>

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  smtp_domain: example.com
  smtp_user_name: user@example.com
  smtp_password: <%= ENV["SMTP_PASSWORD"] %>

And that’s it! Enjoy bringing SMTP credentials into Rails >4.0 secrets management.

Show a devise log in or sign up forms in another page

This is an update of an old post of similar name but for a newer version of Devise and with better design decisions. The old post was for Devise 1.0.8, this one covers 4.0.0

I was trying to have a single page with both sign in and sign up forms with Devise 4.0.0 but this applies to whenever you want to show log in or registering individually or together anywhere on your site other than the views and controllers Devise creates for you.

For my task, I created a custom controller for it with a single new action as the create actions would be in the respective already existing Devise controllers. Something like this:

class Users::SessionsOrRegistrationsController < ApplicationController
  def new
  end
end

And then I created a new.html.erb (actually, new.html.haml, but I digress) that contained both log in and sign up one after the other. Something like this:


<h2>Sign up</h2>


<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
 <%= devise_error_messages! %>


<div class="field">
 <%= f.label :email %>
 <%= f.email_field :email, autofocus: true %>
 </div>



<div class="field">
 <%= f.label :password %>
 <% if @minimum_password_length %>
 <em>(<%= @minimum_password_length %> characters minimum)</em>
 <% end %>
 <%= f.password_field :password, autocomplete: "off" %>
 </div>



<div class="field">
 <%= f.label :password_confirmation %>
 <%= f.password_field :password_confirmation, autocomplete: "off" %>
 </div>



<div class="actions">
 <%= f.submit "Sign up" %>
 </div>

<% end %>

<hr/>


<h2>Log in</h2>


<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>

<div class="field">
    <%= f.label :email %>
    <%= f.email_field :email, autofocus: true %>
  </div>



<div class="field">
    <%= f.label :password %>
    <%= f.password_field :password, autocomplete: "off" %>
  </div>


  <% if devise_mapping.rememberable? -%>

<div class="field">
      <%= f.check_box :remember_me %>
      <%= f.label :remember_me %>
    </div>

  <% end -%>


<div class="actions">
    <%= f.submit "Log in" %>
  </div>

<% end %>

I actually ended up creating two _form partials and including them. In either case, when you try to render those views, you’ll get errors about some missing methods. You need to provide those as helper methods so my controller actually looks like this:

class Users::SessionsOrRegistrationsController < ApplicationController
  def new
  end

  private

  def resource_name
    :user
  end
  helper_method :resource_name

  def resource
    @resource ||= User.new
  end
  helper_method :resource

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end
  helper_method :devise_mapping

  def resource_class
    User
  end
  helper_method :resource_class
end

And now it works.

Run bundler-audit during testing

There’s a gem called bundler-audit that checks whether any of the gems in your project have open security advisors against them. A year or so ago there was an infamous month in which Rails itself got three of those. It was terrible and I think bundler-audit is a good idea. My only problem with it is having to remember to run it: it just won’t happen. I need to run it automatically and an easy way to do that is to run it as part of my tests.

Unfortunately, bundler-audit doesn’t make it easy. It’s designed for the command line and that’s it, but these days it’s easier than a year ago and I recommend everybody to add them to their integration tests. Here’s how we do it at Watu:

require "test_helper"
require "bundler/audit/database"
require "bundler/audit/scanner"

class SecurityTest < ActionDispatch::IntegrationTest
  should "not have any vulnerable gems" do
    Bundler::Audit::Database.update!
    scanner = Bundler::Audit::Scanner.new
    scanner.scan do
      raise "There are vulnerable gems in your Gemfile. Run bundle-audit check to know more"
    end
  end
end

I don’t try to show the vulnerable gems because I found those methods to not be easily reusable and I didn’t want to copy them because they look like they might change at any moment. It’s not a big problem, if something is wrong, you should run bundle-audit check anyway.

random_unique_id version 1.0.0 released

The core of random_unique_id was developed for Watu very early on, which means that it has been used in production for more than two years and a few thousands millions of records. It’s been released as a gem and we had a few iterations. It has 100% code coverage, code climate rating 4.0, 100% documentation coverage, a running continuous integration testing for many different versions of Ruby and Rails, up to date dependencies, it’s been downloaded more that 1700 times.

It’s time to release version 1.0.0. It’s ready for mass consumption. Get it while it’s hot!

Wrapped exceptions in Ruby

Sometimes you want to raise an exception when a method fails but without losing information about an inner exception. Let me explain it with an example.

At Watu we have a method that causes a user to be indexed in our search engine. This method is called many times in different situations. One of those situations is when indexing most or all of our users. Recently, something failed and I got this exception:

undefined method `each' for #<String:0x10dab8fc>

Something that should be an array is actually a string. In this case the indexing method is correct, it’s just getting broken data. I want to fix the bug in the data generation, but to locate it, I need to know which user has broken data. I added a rescue clause to my indexing method to show me that data:

def index
  # ...
rescue
  raise "Error when indexing user #{self}"
end

Now I get something like:

Error when indexing user #<User:1234>

which allows me know that user 1234 has something wrong in its data. The problem is that now I have no idea what the issue is. I lost the information about trying to call each on a string.

The solution to this problem is exception wrapping (or nesting). You want the custom exception to wrap the other one so that you have both pieces of information. This, for example, exists in Java and if you search the web you’ll find ways on how to implement it in Ruby. Implementing this manually is not needed anymore since Ruby 2.1. Unfortunately, it’s a bit hidden and the tools haven’t caught up yet.

The secret lies in a new method in the class Exception called, cause. At the time of this writing it doesn’t even have documentation:

No documentation for the method Exception#cause

No documentation for the method Exception#cause

Using it is very straightforward. Just raise an exception in the rescue clause and the new exception will have the previous one as its cause. For example, in this case:

begin
  a = 1 / 0
rescue
  raise "Something went wrong"
end

you get two exceptions: the divided-by-zero wrapped inside one with the “Something went wrong” message.

The problem arrises that nobody seems to be using the causes of exceptions yet. If you run that in IRB, this is what you get:

RuntimeError: Something went wrong
        from (irb):4:in `rescue in irb_binding'
        from (irb):1
        from /Users/pupeno/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `&lt;main&gt;'

But the exception’s cause is in there… hidden. If you catch the outer exception you can access its cause. For example:

begin
  begin
    a = 1 / 0
  rescue
    raise "Something went wrong"
  end
rescue => e
  puts e
  puts e.cause
end

would produce:

Something went wrong
divided by 0

The reason why it doesn’t produce something like that by default is because whatever IRB is using to print exceptions is ignoring the exception’s cause. Now we’ll have to wait until all the tools catch up with this new feature.

Well, we don’t actually have to wait. Aside from the fact that most of them are open source and you can fix them yourself, Ruby allows you to monkey patch so you can fix your own copy of these tools.

In my case I needed rake to print inner exceptions, so I wrote this monkey patch (which works for rake 10.1.1):

module Rake
  class Application
    def display_error_message(ex)
      trace "#{name} aborted!"
      display_exception(ex)
      trace "Tasks: #{ex.chain}" if has_chain?(ex)
      trace "(See full trace by running task with --trace)" unless options.backtrace
    end

    private

    def display_exception(ex, margin="")
      trace "#{margin}#{ex.message}"
      if options.backtrace
        trace "#{margin}#{ex.backtrace.join("\n#{margin}")}"
      else
        trace "#{margin}#{Backtrace.collapse(ex.backtrace).join("\n#{margin}")}"
      end
      if ex.respond_to?(:cause) && !ex.cause.nil? # Ruby < 2.1.0 doesn't have *cause*
        trace "#{margin}which was caused by:"
        display_exception(ex.cause, "#{margin} ")
      end
    end
  end
end

This is something that I would like to see in rake itself so I created an issue request (#253). Take a look at it to follow the development of this feature and hopefully, all tools will start displaying causes in one way or another.