Naildrivin' ❺

➠ Website of David Bryant Copeland

❺➠ Rails Does Not Define Your Application Architecture

While Rails doesn’t prevent you from creating a well-architected application, it certainly doesn’t give you everything you need. This is not so bad if your application is incredibly simple, but for anything of moderate complexity (and I would argue that any app someone is paying you to produce is going to be moderately complex), Rails leaves a lot of architectural decisions to you.

† Use Bower for Managing Front-end Assets in Rails

By yours truly, on the GrowingDevs blog, giving you some more reasons and help on using Bower instead of RubyGems for managing your front-end assets in Rails:

Use Bower for managing front-end assets in Rails

Rails 4.0.4 depends on version 2.2.x of the jquery-rails gem which in turn bundles 1.9.1 of JQuery. Does that make any sense? The latest official release of angular-ui-bootstrap-rails is 0.9.0, which is at least a version behind the current release of the Angular UI bootstrap directives. When will it be updated? chosen-rails version 1.1.0 bundles an old version of chosen-jquery that has never been officially released. What?

The state of front-end assets in RubyGems is almost comical. Please start using Bower.

† Getting Angular and Rails Working Together

I’ve been doing a bit of AngularJS at work, and getting it all working with Rails, the asset pipeline, testing, and deployment was quite a challenge. It wasn’t so much difficult to do, but difficult to uncover the right information. So, I decided to compile it all in a nice tutorial and post it as a free mini-ebook, in web form, also known as a website1.

From angular-rails.com:

Once you’re familiar enough with Angular to start building an app, you’ll find there are a lot of unanswered questions:
  • How do I serve Angular assets via the Rails Asset Pipeline?
  • How does Angular’s templating system work with Rails?
  • How do I connect Angular to my Rails controllers?
  • How do I test my Angular code within a Rails app?
  • How do I manage all these JavaScript dependencies?
  • What challenges will there be in the production environment not present in the development environment?
I was able to find answers by piecing together information from Stack Overflow and various blog posts. You shouldn’t have to do that.

Check it out, start making some awesome Angular apps with Rails, and correct any mistakes you find.


  1. I have a longer-term goal to make this an actual e-book, but for now, I wanted to get it out and get feedback

Doing Your Best Work

If I could sum up the best programmers I’ve worked with in a sentence, it would be:

They know what to build and they know how build it

The later is almost trivial to achieve compared to the former, but without both, you won’t be doing your best work.

❺➠ What Rails Says About Your Application Design

Rails isn’t the only part of your application where design decisions are made. The developers of Rails aren’t the only developers whose past experience can be used to make design decisions. You have experience, too. And it’s that experience that must drive your design process.

A Defense of Ivars in Rails Controllers

Had a discussion with another developer at a meetup about testing Rails controllers. I test controllers a lot. In fact, I start most new features with a controller test. I also use ivars as the means of passing data from controller to view. Ex-colleague Adam Keys recently wrote a good piece about not using ivars:

If you stick with ivars long enough, you’re going to end up with two kinds of misadventures. Most commonly, you’ll wonder why @user is nil for some view or edge case… This leads to the second misadventure: where did this @user thing come from2?

He then goes onto propose creating methods, since it makes testing and experimentation easier.

Personally, I would find this far more confusing. Ruby’s tagline could be “where did that come from?”. You can’t write Ruby without grepping. A lot. And the string “@user” is going to be a lot easier to grep for than “current_user”. Finding “@user =” moreso.

But this is all beside the point. Fighting controllers and avoiding ivars unnecessarily adds complexity to Rails to solve a problem that is created not by Rails but by bad programming practices. Hiding those practices behind methods, helpers, and objects is just that - hiding. If want to avoid sloppy controllers and views, don’t fight Rails, instead do this:

  • Adjust your mindset about what Controllers are.
  • Adhere to three simple practices when writing controllers and views.

What Rails Controllers Really Are

Stop thinking of controllers as regular objects/classes in the traditional Ruby sense. The way they are written, tested, and used gives no indication that they are conventional. Instead, think of controllers as namespaces for functions, each having a single input—params—whose purpose is to render a view given some data:

1
2
3
4
def show(params)
  user = User.find(params[:id])
  render 'show', values: { user: user }
end
1
<h1><%= user.name %></h1>

As Rails is a DSL for making web applications, it uses the “specialness” of a controller to abstract away boilerplate so that all we need to write is what’s specific to our application.

First, there’s no need to have params passed in explicitly:

1
2
3
4
def show
  user = User.find(params[:id])
  render 'show', values: { user: user }
end

Next, we can automatically handle rendering:

1
2
3
4
def show
  user = User.find(params[:id])
  values = { user: user }
end

Finally, we can condense the passing of values to mere assignment:

1
2
3
def show
  @user = User.find(params[:id])
end
1
<h1><%= @user.name %></h1>

This description of what controllers really are is borne out in a canonical controller test:

1
2
3
4
5
6
7
8
# Setup our test data
user = User.create!(name: 'Dave')

# call our function, giving it a value for `params`
get :show, id: user.id

# assert something about the assigned values
assert_equal user, assigns(:user)

If you are comfortable using let to assign values in RSpec, you should be totally OK with this.

Because a controller isn’t a conventional object or class, but is instead a namespace for functions, it has no need of ivars. Knowing this, Rails co-opts the ivar mechanism to make our lives easier and our code easier to read and write. That you can declare an ivar anywhere in a controller and that doing so causes confusion is your problelm, not Rails. Avoiding ivars in favor of a custom mechanism seems more difficult in the long run than just making a commitment to just three simple practices.

Three Practices to Keep Your Controllers and Views Clean

When you take care with your views and controllers, the Rails Way results in code that is easy to read and modify.

Assign ivars only in controller actions or, if you must, filters.

Since your controller methods should be short, as should your filters, you can easily see all ivars assigned by a controller in one screenful of text. Yes, you can assign ivars anywhere you want. Don’t do that. You wouldn’t do that in any other class in your system, so why does the ability to do it in controllers necessitate a deviation from Rails idioms?

Assign as few ivars as possible.

Ideally, you have a single type describing the contract between controller action and view and that value is always expected to have a value. If that “type” isn’t a database-backed ActiveRecord model, you know what: spend 60 seconds making a class. If it takes you longer to create a model describing what your view expects, sharpen your tools.

But, there’s a reason I didn’t say “Assign one ivar”. Sometimes you need orthogonal data, such as reference data for select boxes, and assigning it in the controller as a second ivar can end up being much simpler that either putting it into your model object or as a helper.

Do not use ivars in partials.

This is usually the source of a lot of confusion and problems in Rails views. It’s not the fault of Rails, but it’s another bad programming practice. Using ivars in partials is akin to this Ruby code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Greeter
  def initialize(person)
    @person = person
  end

  def greet
    @first_name = @person.first_name
    "Hello #{normalize_name}"
  end

  def normalize_name
    @first_name.strip.downcase.capitalize
  end
end

Treat calls to render partial: as a method call and pass in arguments that that partial needs to work. Design that partial to require (and document) what should be passed in. Inside a view, think of ivars as global data. We don’t use global data to pass arguments to methods.

It may seem braindead to write render partial:'form', locals: { user: @user }, but you will thank yourself later for spending 5 seconds being explicit. The partial can now be moved around and re-used easily, because its contract is explicit.

Don’t Fear ivars - Fear Bad Coding Practices

These rules are incredibly simple to follow, and make your code easy to write, read, and maintain. Your controller tests are easy to write, and your partials can be easily extracted if needed.

You see time and time again that Rails conventions are designed around making readable and maintainable code in the context of good programming practices. Rails was never intended to make it hard to write bad code, but to make us productive. If we are comfortable making a mess and ignoring years of lessons learned about programming, Rails isn’t going to help us.

† Presenters: Delegation vs Just Making a Struct

I posted another blog entry at the Stitch Fix tech blog, this one on using simple structs instead of delegation for adapting your data for web views:

This is another way of saying that we get better, simpler code, without almost the same effort, if we just create a basic class instead of using delegation.

† Startup Engineering Team Super Powers

New post by yours truly on the Stitch Fix Tech Blog about some handy abilities and skills a start-up tech team needs to succeed: Startup Engineering Team Super Powers:

So far, we’ve been able to avoid creating a single monolithic application, and have been consistently delivering and deploying solutions to our users. I believe this is because we’ve developed a set of “super powers” which have been extremely helpful, and I believe these powers will keep our team and technology healthy for years to come.

Org Charts and Diff Production

Square’s @jackdanger wrote a great post on his blog titled ”The Upside Down Org Chart.” It’s a great read on improving how reasonably-sized companies are structured. His use of a tree that expands upwards, showing how management supports subordination, is genius. It visually explains the role of management:

For a tech company to describe their structure this way requires some humility from the leadership. It requires accepting that senior positions must be evaluated based on the support given to individuals on the team rather than the support given to the CEO or executives. But it makes the structure one in which nothing is extracted from the laborers – indeed it provides help that an individual could not find working alone.

His blog post’s description of traditional top-down management structures brought back memories of teams I’ve been on that, despite having favorable org charts, were unpleasant. The problem was that I was treated as (and acted like) a producer of diffs, rather than a problem-solver.