Samuel Mullen

What could possibly go wrong?

The Problem With Rails Callbacks

If you search StackOverflow for “Rails callbacks”, a large number of the results pertain to seeking means to avoid issuing the callback in certain contexts. It almost seems as though Rails developers discover a need to avoid callbacks as soon as they discover their existence.

Normally, this would be a cause for concern, that perhaps the feature should be avoided altogether or even removed, but callbacks are still part of Rails. Maybe the problem goes deeper.

What is a Callback?

As you likely already know, callbacks are just hooks into an ActiveRecord object’s life cycle. Actions can be performed “before”, “after”, or even “around” ActiveRecord events, such as save, validate, or create. Also, callbacks are cumulative, so you can have two actions which occur before_update, and those callbacks will be executed in the order they are occur.

Where Trouble Begins

Developers usually start noticing callback pain during testing. If you’re not testing your ActiveRecord models, you’ll begin noticing pain later as your application grows and as more logic is required to call or avoid the callback.

I say, “developers usually start noticing callback pain during testing” because in order to speed up tests or to get them to pass, it becomes necessary to “stub out” the callback actions. If you don’t stub out the action, then you must add the supporting data structure, class, and/or logic to each test in order for it to pass.

Here’s an example of what I mean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Post < ActiveRecord::Base
  has_many :followers
  after_save :notify_followers

  def publish!
    self.published_at = Time.now
    save
  end

  private

  def notify_followers
    Notifier.post_mailer.deliver
  end
end

describe "publishing the article" do
  it "saves the object with a defined published_at value" do
    Post.any_instance.stub(:notify_followers) # Codey McSmellsalot
    post = Post.new(:title => "The Problem with Callbacks in Rails")
    post.publish!
    expect(post.published_at).to be_an_kind_of(Time)
    expect(post).to_not be_a_new_record
  end
end

In order to get that example code to pass, notify_followers must be “stubbed out”. If it isn’t, and if followers are used within the mailer, the test will fail because it’s not able to execute the delivery (i.e. it’ll error out due to nil values).

What About Observers?

Rails developers who’ve begun moving into a more Object Oriented mindset might ask, “What about using observers instead of callbacks?” It’s the right direction: by creating an observer, you move responsibilities which don’t belong in the object being observed to the observer.

The problem is that observers in Rails are kind of like ninja callbacks: they perform the same function as callbacks, they just work in the shadows. Unless you look at the file system, you are very likely to forget Observers even exist in your application.

Furthermore, observers are assigned to their appropriate class when Rails starts up, and Rails starts up when you run your tests. Once again, you’ll start feeling pain in your tests first, because in order to avoid observer calls in your tests, you will need to either create all the dependent objects or install a gem such as no_peeping_toms. Just like callbacks, observers run every time their condition is met.

Aside: Herman Moreno wrote a good post on undocumented observer usage: Fun with ActiveRecord::Observer.

Why Are Callbacks So Problematic?

In his post on ActiveRecord, Caching, and the Single Responsibility Principle, Joshua Clayton noticed “after_* callbacks on Rails models seem to have some of the most tightly-coupled code, especially when it comes to models with associations.”

It’s no coincidence. “before_” callbacks are generally used to prepare an object to be saved. Updating timestamps or incrementing counters on the object are the sort of things we do “before” the object is saved. On the other hand, “after_*” callbacks are primarily used in relation to saving or persisting the object. Once the object is saved, the purpose (i.e. responsibility) of the object has been fulfilled, and so what we usually see are callbacks reaching outside of its area of responsibility, and that’s when we run into problems.

Solving the Problem

Jonathan Wallace, over at the Big Nerd Ranch, ran into to same problems and came up with one simple rule: “Use a callback only when the logic refers to state internal to the object.” (The only acceptable use for callbacks in Rails ever)

If we can’t use callbacks which extend responsibility outside their class, what do we do? We make an object whose responsibility is to handle that callback.

Before Example

Let’s look at a hypothetical example. This is what we might originally have:

Order model
1
2
3
4
5
6
7
8
9
10
11
12
13
class Order < ActiveRecord::Base
  belongs_to :user
  has_many :line_items
  has_many :products, :through => :line_items

  after_create :purchase_completion_notification

  private

  def purchase_completion_notification
    Notifier.purchase_notifier(self).deliver
  end
end
Notifier ActionMailer
1
2
3
4
5
6
7
8
9
class Notifier < ActionMailer...
  def purchase_notifier(order)
    @order = order
    @user = order.user
    @products = order.products

    rest of the action mailer logic
  end
end

In the above example we can see that when an order is saved, it’s going to shoot off an email to the customer. That Mailer is going to use the order object to retrieve the ordering user and the products which were purchased and likely use them in the email. Pretty simple, right?

In a test, however, any time an order is saved to the database, user, line_items, and products will need to be created, or the purchase_notifier method will need to be stubbed out – Order.any_instance.stub(:purchase_notifier) (Ugh).

After Example

Here’s what happens when we move some responsibilities:

Our Order model is much simpler.

Order model
1
2
3
4
5
class Order < ActiveRecord::Base
  belongs_to :user
  has_many :line_items
  has_many :products, :through => :line_items
end

Here’s our new class:

OrderCompletion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class OrderCompletion
  attr_accessor :order

  def initialize(order)
    @order = order
  end

  def create
    if self.order.save
      self.purchase_completion_notification
    end
  end

  def purchase_completion_notification
    Notifier.purchase_notifier.deliver(self.order)
  end
end

What we’ve done above is moved the process of saving the order and sending the notification out of the Order model and into a PORO (Plain Old Ruby Object) class. This class is responsible for completing an order. Y’know, saving the order and letting the customer know it worked.

By doing this, we no longer have to stub out the notification method in our tests, we’ve made it a simple matter to create an order without requiring an email to be sent, and we’re following good Object Oriented design by making sure our classes have a single responsibility (SRP).

It’s a simple matter to use this in our controller too:

OrdersController.create
1
2
3
4
5
6
7
8
9
10
11
def create
  @order = Order.new(params[:order])
  @order_completion = OrderCompletion.new(@order)

  if @order_completion.create
    redirect_to root_path, notice: 'Your order is being processed.'
  else
    @order = @order_completion.order
    render action: "new"
  end
end

Wrapping up

As much as I complain about callbacks, they’re really not bad as long as you remember the rule: “Use a callback only when the logic refers to state internal to the object.” And really, that can be applied to any method.

When you start to feel those first twinges of pain from your tests, whether from callbacks or otherwise, consider if what you are trying to do exceeds your class’s responsibility. Creating a new class is a simple matter, especially compared to the pain and frustration caused by not doing it.

Many thanks to Pat Shaughnessy for proof-reading and providing feedback.

Determining and Encouraging Developer Growth

Excitement, frustration, discovery, passion, elation, disappointment, hunger, failure, conquest, defeat, insight, freedom, dominance. These are not subtle words, and I’ve chosen them because they are descriptive of programming, and more specifically, growth as a programmer. Not one word standing above the others, but all of them, in any order, and of varying durations. Do you know these words? Do you know them now, or are they a memory?

I’ve been thinking a lot lately about how to determine if you’re growing as a programmer. It’s easy to see growth when you are first beginning; you see the progress of acquiring knowledge. But as your mastery increases, quantifying growth moves from that based on knowledge, toward a growth based on understanding and application. What are the metrics for determining growth then?

An Experiment

To give us an idea if we are growing, let’s try an experiment. Answer the following questions:

  • List three new things you’ve learned in the last week about your current technology of preference.
  • What new idea, concept, pattern, or technique have you played with or tried to use in the past week.
  • What was the last technical book you read for fun? When did you read it?
  • Do you program outside of work? (For fun, not freelancing)
  • When was the last time you had an exciting conversation with a peer about programming?
  • Do you look forward to going to work?

Did your responses to those questions give you an idea about your current state of growth? Simply put, the best metric for determining if you are learning and growing as a programmer - probably as anything - is this: “Are you having fun?”

So, are you?

Go back to the first sentence of this post. When in your programming career have you felt those words most intensely? When you were learning, right? But weren’t you also enjoying yourself? Weren’t you having fun?

Being Stuck

If you had trouble providing positive answers for the questions above, maybe you’re in a bad spot. I know what that’s like. I know what it’s like to have every idea shot down because that’s “not how we do things.” I know what it’s like to have your creativity constrained because “failure’s not an option.” I know what it’s like to want to do better, but be told “it’s good enough.” I know what it’s like to be stuck.

Being stuck is a horrible state to be in. Maybe you’re stuck because of the technology you’re using, or maybe it’s your boss or your organization, maybe it’s the system, but whatever the case, there you are, unchanging, unmoving, not growing, stuck.

Needless to say, being stuck is not fun.

Encouraging Growth

The whole premise of this post is that if you’re having fun, you’re most likely growing as a developer; if you’re not having fun, then you’re not growing as much as you could. If you’re not growing as much as you would like, then something needs to change, and maybe several “somethings”.

What follows is a list of some ideas you should try in order to rekindle your love and excitement for the art. This is not an exhaustive list, and I would love to hear from you what things you’ve tried to get the development juices flowing.

  • Keep lists of researchables: I have a list - it sounds more organized than it is - I use to keep track of words, concepts, and ideas that I want to research. When I get a few minutes (between test runs) I go and look things up.
  • Develop a low pain threshold: We create applications to solve problems. Pay attention to those little annoyances and find a programmatic way of solving them. e.g. Be annoyed by the way your editor behaves and find a way to fix it.
  • Play more:
    • Take some time to tweak your configuration files; especially emacs, VIM, Git, or shell configs.
    • Experiment with a new library or language
    • Force a limitation on yourself: examples, try to use recursion instead of loops; use methods instead of constants; read source code in place of documentation; etc. See also Creative Limitations
    • Participate in a Hackathon
  • Find other developers who are passionate and start hanging out with them, especially if they’re better than you.
    • Check out your local user groups
    • Go to conferences
    • Find a mentor
    • Find a way, but make those connections
  • Start contributing to a FOSS project
  • Try playing with some Arduino or Raspberry Pi projects?

The point is to play and to have fun, and to remind yourself how much fun programming is. Yeah, at times programming is difficult and sometimes it’s even a chore, but you know from your past that it doesn’t have to be that way, and you know from your experience that it shouldn’t be that way. If you are at a point where you find yourself incapable of growth, maybe it’s time for a change; maybe a drastic change.

Because, let’s face it, “If you’re not having fun, you’re doing it wrong.”

Workload Based Marketing

I’ve been working through the book,“Get Clients Now,” as part of my never ending quest to attract and develop new clients. In the book, the author suggests you choose ten activities you can complete on a daily or weekly basis over a period of twenty-eight days. As I was discussing with my wife some of the activities I was considering (blogging, answering StackOverflow questions, attending networking events, reaching out to contacts, etc.), she stated rather bluntly, “You’re setting yourself up for failure.”

It sounds harsh, but it was really what I needed to hear. My wife worked in sales for a number of years and she recognized immediately the effort required to complete all the activities I had on my list. More importantly, she understands me and the effect it would have on me.

You see, as of this writing I am finishing up two projects and I’m gearing up to start three new ones - one which includes an unfamiliar technology. My wife knows that if I meet all my clients’ needs AND attempt to meet all ten of my marketing goals, something will have to give; probably a lot of somethings. And because I’m highly goal oriented, she knows I would beat myself up for not meeting all my expectations, and waste a lot of energy and time trying to figure out why I couldn’t get it all done.

My wife’s years of sales experience helped her recognize the obvious: I was trying to do too much. Part of what kept me from recognizing the same was my own inexperience with the demands of marketing, the rest was me blindly following recipes out of a book.

But from her insight and fresh perspective, I’ve come up with a new marketing strategy for myself which I’ve dubbed…

Workload Based Marketing

It’s not rocket science, and it’s certainly not an earth-shattering discovery, but it was eye-opening for me and where I was at. It starts with these three rules:

1. Focus on Current Clients First

Here’s the deal, you already have actual clients. Marketing represents clients you might get, and who might have money. If you have to choose between marketing and investing in relationships with your current clients, choose the latter; it’s the only decision guaranteed to pay dividends every time.

2. No Marketing Effort is Too Small

Like I said, clients always come first, but I also know none of us are heads-down 24/7. There’s always time in a week for at least something. Maybe it’s making a couple phone calls one day, eating lunch with a contact another day, or just getting a paragraph or two on that next blog post.

The point is to keep up the momentum. Momentum from small efforts can lead to big opportunities.

3. Waiting is Stupid

In “Get Clients Now”, the author instructs you to start your system on a Saturday. I had planned on starting mine on the first Saturday of the new year, after the holidays were over.

My wife asked, “Why do you want to wait to find clients?”

Ummmm….

The Plan(s)

With those rules in mind, let’s look at the plan itself.

Based on the name alone, you should already get the basic idea of “Workload Based Marketing”: if you have a lot of work on your plate, don’t push yourself to market so much; if your workload is light, increase your marketing efforts accordingly.

More than that, though, and before you start anything, devise plans for yourself which you can execute according to the intensity of your workload. To keep it simple, create three plans: one for when your workload is light; one for when it’s moderate, and then one for those times when you’re swamped. For example, I’ve created plans for myself based on possible workload, each with a variety of activities suggested from “Get Clients Now” or from my own marketing preferences.

Having these plans established ahead of time allows you to “just go on autopilot” rather than burning a lot of cycles trying to figure out what to do. You won’t need to waste time thinking about things, you’ll just be able to go. Organizing your plans around a weekly schedule is probably the simplest solution.

“Get Clients Now” is a great book, and every freelancer should read it at least once and consider the author’s suggestions. In it, she gives some great advice for getting started, setting goals, and strategies for the different stages of the marketing cycle. But remember also, no system is perfect. Adjust whatever system you settle on to match your own needs, and prepare your plans ahead of time so that when storms hit, you can be ready with something to do, rather than wasting precious time and energy.

One last thought, review your plans in light of the end goal: right clients, right projects, and right price. Make certain your strategies and tactics are aimed at the right audience. Use your time wisely on existing clients first, and then pick the plan matching your workload to find the prospects who fit the profile you desire.

Why Your Company Should Sponsor Tech Conferences

Note: In this post, when I refer to “developers”, I’m generally referring to programmers, DevOps, and digitally creative types.

For the past couple of months, I’ve been reaching out to companies, asking them to sponsor Ruby Midwest 2013, a technology conference I’m helping to organize. Every company I’ve had contact with has been super nice and many have chosen to support us either financially or with products or services. Some companies have chosen not to sponsor for a variety of reasons, and that’s cool, I get that. There are definitely reasons not to become sponsors. But in this post, I want to look at some of the results decision-makers are expecting, and some which they might not consider, and which, if they do, might change their outlook on sponsorship.

Just looking at sponsorship from a general perspective, most companies are seeking to advertise, increase brand awareness, make sales, and maybe find new employees. The hope is that the amount of money invested will be offset by what is returned. And of course this works, which is why you see some of the same companies sponsoring so many conferences.

Take, for example, publishing companies O’Reilly and Addison Wesley. I can’t imagine a conference which didn’t have books from either of these companies to give away. The results of these minor investments are advertising and increased brand awareness (people get to see the books handed out), and increased sales by way of the book recipients buying more products from the same publisher, and also from them telling their friends or writing reviews. It’s nothing but “win” for these guys.

Since I am currently seeking sponsorship for Ruby Midwest, I am a little hesitant to say this, but investing in a conference may not be the best choice for a company if it is only looking for sales and advertising. Part of the problem is that those running the conference are usually developers (like myself), and, well, we’re not really known for our ability to sell and market companies and products (or even have “normal” conversations.)

The other part of the problem is the target audience. Most people attending tech conferences are company-employed developers (i.e. not the decision-makers). So even though a company might be selling the new whiz-bang product, we may not be in a position to do anything about it other than make the case to our management, (and again, we’re not really known for our ability to sell.)

Selling books or developer tools is one thing; developers are usually the decision-makers. Selling other types of products, especially those focused on companies, are a different matter; developers, even if they’re the target audience, may not be in a position to purchase.

And so at this point you may be asking yourself, “If we’re unlikely to make sales, get a good advertising push, or increase our brand awareness, why should my company sponsor a regional conference?” In short, by sponsoring conferences, you are telling your development staff that you support them and their passion, you inform the local development community that you “get it”, and you add to your reputation as a company who understands technology. Let’s break this down a bit.

I’ve written about this before in my post on ”Attracting Good Developers”, but in short, developers want to know they’re supported and needed. You can do that in a number of ways (and you should) but one way is to invest, not just in them (which you should), but also their interest: i.e. conferences they want to attend. By doing so, it’s understood that your company is taking an interest in their growth and improvement. That matters.

When you sponsor conferences, you not only tell your own development staff you support them, but that you support the local community and you’re a company who understands technology. Believe me, we notice.

Don’t underestimate the value of this. Good developers want to work for “cool” companies, because, well, to be honest, it makes us “cool”. Not “cool” like James Dean, but “cool” as in, we are good enough to work there. This can be a huge confidence boost, and can unleash hidden potential. Developers who once just thought of themselves as the line-workers of the 21st century, might now - with the added confidence - begin to think of themselves as something more, and increase their contribution to your organization.

Used with permission from KCITP’s post: 3 Reasons Why Developers Need To Attend Hack The Midwest

Alright, let’s pretend my arguments have convinced you to sponsor a conference, which ones to you sponsor? Here are three things to look at:

  1. If you’re local, stay local: If you are a company localized to a certain city or area, sponsor those conferences and developer communities resident in that area; in your market
  2. If you’re big, go BIG: If you’ve got offices all over the nation or world, you should probably be sponsoring the major events: OSCon, PyCon, RubyConf, Velocity, etc. But hey, don’t forget the to sponsor the regional conferences your offices are located.
  3. Stay with what you know: Unless you are trying to recruit talent from another technology area, don’t feel like you have to sponsor everything; just sponsor the conferences relevant to your company.

Tech conferences occur in every semi-major city around the globe and every company with a good development staff or who wants a good development staff should be sponsoring at least one a year. Sure, sponsorships can bring in new sales extend your company’s brand, but more than that, it can improve your company’s reputation among your own staff and in the development community.

In the end, sponsoring conferences isn’t just about investing in your company’s representation of itself, it’s really about investing in your development staff and in your company’s culture. It’s worth it.

Step by Step: Setting Up Minitest and Cucumber With Rails

I’ve tried a couple times in the past to successfully set up a Rails application with both minitest and Cucumber; each time, I ran in to issues. I’m not entirely sure why I ran into the issues I did, but I just couldn’t seem to get things working. Recently, I managed to get everything going with almost no effort. Here’s what I did.

Step 1: Creating and Configuring a New Rails App with minitest

For the sake of simplicity, we’ll assume that we’re creating a new Rails application. To do so, we’ll want to skip the standard usage of Test::Unit

Initializing a New App
1
rails new <app_name> --skip-test-unit

Immediately after this, we’ll need to install and initialize the minitest-rails gem

Gemfile
1
2
3
4
5
group :test, :development do
  ...
  gem 'minitest-rails', '~> 0.3.0` # as of this writing
  ...
end

bundle install and then initialize the gem in the app.

minitest installation
1
rails g mini_test:install

The last thing we’ll do is make sure our generators behave accordingly. To do that, add the following logic to the config/application.rb config block:

config/application.rb
1
2
3
config.generators do |g|
  g.test_framework :mini_test, :spec => true, :fixture => false
end

This turns on minitest’s spec functionality and turns off fixture generation. If you don’t want to use minispec or if you do want to use fixtures, just alter the values accordingly.

Step 2: Setting up Cucumber

Okay, at this point we have our foundational test suite set up. Now we need to add cucumber to the mix.

Add cucumber-rails to your Gemfile as you normally would.

Gemfile
1
2
3
4
group :test do
  gem 'cucumber-rails', "~> 1.3.0"
  gem "database_cleaner", "~> 0.9.1"
end

Call bundle install and then call the cucumber Rails generator:

cucumber:install
1
rails g cucumber:install

Now, add the following lines of code to features/support/env.rb. (I placed mine near the top.)

features/support/env.rb
1
2
3
require 'minitest/spec'
World(MiniTest::Assertions)
MiniTest::Spec.new(nil)

For greater separation, the previous lines of code above can be added to a different support file.

Step 3: Running the Tests

At this point, everything should work. Let’s find out with a couple simple tests.

minispec Test

Create the following test file and model:

test/models/foo_test.rb
1
2
3
4
5
6
7
require_relative "../minitest_helper"

describe Foo do
  it "must be valid" do
    Foo.must_respond_to :new
  end
end

And the corresponding model file:

app/models/foo.rb
1
2
class Foo
end

Notice in the first line of foo_test.rb that we’re using require_relative instead of a normal require call. We do this to avoid the need to use rake. Now, rather than running bundle exec rake minitest:models and running all the models, we can execute bundle exec ruby test/models/foo_test.rb.

Cucumber Test

Create the following Cucumber “feature” file:

test.feature
1
2
3
4
5
6
7
8
Feature: test
  In order to test cucumber
  a user
  wants to successfully land on the home page

  Scenario: foo
    Given I am on the home page
     Then I should see "Ruby on Rails: Welcome aboard"

And an associated step file:

test_steps.rb
1
2
3
4
5
6
7
Given /^I am on the home page$/ do
  visit "/"
end

Then /^I should see \"([^"]+)"$/ do |string|
  page.has_content?(string).must_equal true
end

Run the test and everything should be green.

Cucumber execution
1
bundle exec cucumber features/test.feature

Final Thoughts

I like minitest a lot, mainly because it’s fast, it’s simple, and it’s included in Ruby 1.9+, but there are drawbacks; the two main ones for me are its readability and the lack of integration with the vim-rails plugin. Neither of these “drawbacks” are deal breakers, however: the vim-rails plugin will eventually support it, and there are gems to make the suite more “civilized” (listed below).

So if you like the idea of a really simple and fast test suite, and you don’t mind the syntax, give minitest a go on your next project. Oh, and let me know how it works out for you.

Further Reading

The Introvert’s Networking Survival Guide: Large Events

I am an introvert. As a freelance developer, that works out well for me (mostly). It allows me to work from my home office with little to no contact with the majority of mankind for days on end. But as a freelancer, I also recognize that I have to get out and meet people in order to find new work.

A little over a year ago, I was invited to a BNI networking event. I thought it would be the same thing I’ve seen at any large gathering of people: people gathering to those they already know, new people getting ignored, uninteresting small talk, etc.

I was wrong.

From the moment I stepped through the door, I was greeted with a dozen hands thrust out to shake mine, people asking me my name, what I did, where I was located, then telling me their name, telling me what they did, wanting to know my pitch, telling me theirs, asking me if I was a member, if I wanted to be a member.

It was too much.

As soon as I could, I got out of the room and into a hallway, and called my wife. Yes, I wanted to talk to her, but at that moment, I also needed an excuse to escape and focus on one person. I slipped back into the room once the meeting had officially started, and counted the minutes until I could leave.

Since then, I’ve been to a number of other networking events. Each event had its own characteristics and quirks, and I’ve learned more about networking from each event I’ve attended.

Tip #1 :: No One Expects the Spanish Inquisition

Expectations are everything, and we enter in to every situation with at least some sort of preconceived idea of what is going to happen. Under normal circumstances, being a little off about what to expect isn’t a problem, but when your expectations are completely wrong, as mine were at the BNI event (and my 10th grade Geometry class), it can be difficult to recover from.

Knowing this about myself, I find it helpful to do a little pre-networking research. Not a lot, but just enough to have a better grasp of what to expect. Here are some of the things I look for:

  • Setting :: Where is the event taking place?Is it a bar or restaurant? A business? On a college campus?
  • Size :: How many people are expected to attend? This is an important one for me.
  • Format ::
    • Is this a presentation plus networking event?
    • Is it just networking?
    • Is there a structure to the event?
  • Topic :: Is there an overriding theme to the event?
  • People-group :: Is the event specific to a particular profession or more generalized?

The Spanish Inquisition Sketch

Tip #2 :: What is Your Quest?

“Why are you going to this event?” Have you ever asked yourself that question? Obviously you’re going there to increase your network and meet people, but really, to what end?

Are you looking to make a sale? To find someone to partner with? Are you looking for investors, or employees? Are you going just to practice networking (don’t laugh)?

Having a purpose in going to an event can 1) help determine if you should even go; 2) help determine if the event in question is going to help meet that goal; and 3) keep you on track while you are at the event.

If you don’t have a purpose in going to a networking event, you probably shouldn’t be going.

Three Questions

Tip #3 :: Are you the Judean People’s Front?

Okay, so you know where the event is going to be and what it’s going to be like, and you have a purpose in going, the last thing you need to know is who to talk to. If you’ve figured out why you are going to the event, this part should direct you to the people you should look for.

As an example, if I go to a networking event and my goal is to find a new client, I’m not going to spend a lot of time speaking with other freelancers, except to find out if they are looking to offload a client. Instead, I’m going to target IT decision makers in the markets I’m looking to get into.

Simple, right? But as introverts, it’s a lot easier to gravitate to those people we know, and to corners we feel safe in. Sometimes, you just have to embrace the suck and talk to people.

So based on your purpose for going to the event, who are the people who would best help you meet your goals?

The People’s Front

Bonus Tip :: Why Did You Say “Good Morning”?

Okay, last point. Most networking events - thankfully - last less than three hours. That means you have that much time to acclimate yourself to the environment, figure out how to meet your goals, and then find the people you need to meet. The last thing you need to do is waste the time with small talk.

I don’t care what the Bene Gesserit say, small talk, not fear, is the mind-killer.We fall in to the trap of small talk because it’s safe and it’s comfortable, but it’s also completely forgettable. The point of networking is to connect with people. If your conversation is forgettable, what value is the connection?

So what do you talk about? I like to use some of the following questions and roll on from there:

  • Why are you here and what kinds of people are you looking to connect with?
    • You will probably want to ask that less directly. The point is just to find out if there is potential value in the connection.
  • What do you do? It’s cliche and small talky, but it has to be asked.
  • What is your favorite part about what you do?
    • I ask this solely to ensure there is a positive experience to the time. Well, that, and it’s usually fun to see people get excited about their work/family/etc.
    • Note: I don’t ask what their least favorite part is
  • What are some of the struggles you are currently facing in your work?
    • This isn’t asking what they don’t like.
    • This is discovering if you can fix their problems.
  • and so on…

Silly Job Interview

As far as networking goes, I usually prefer meeting people for coffee or lunch. It fits my temperament, it’s less intense, and it generally makes for a better conversation. That’s the advice most “networking for introverts” articles provide. While more intimate types of networking fits the introverts’ personality, it doesn’t address the problem of what to do if you’ve managed to stumble into a larger event, which is to say, find out what to expect, figure out your purpose, know who you want to meet, and avoid small talk.

If all else fails, you can always hide out in the hallway and talk to your wife on the phone.

My Letter to the City of Shawnee, Kansas

As a rule, I don’t post anything relating to politics, but since this has nothing to do with the banalities of left vs. right vs. independents, I am making an exception.

I am so completely excited about Google Fiber, I could burst, and I am terrified that rather than opening our doors to the future and to future growth, our local governments will instead see this as an opportunity to make a buck and flex its muscles.

The Internet represents freedom. We need to open our arms to it.

Ladies and Gentlemen of the Governing Body of Shawnee,

My name is Samuel Mullen. I’m a freelance programmer specializing in web and iPhone development. As such, I am very keen to learn what, if anything, has been done to encourage Google Fiber to come to Shawnee. Obviously we are some distance from the initial locations selected by Google, but they will inevitably spread out, and I am anxious for it’s arrival. I am convinced my business can only grow with its arrival: through new companies, technological improvements, and networking.

I believe the greater Kansas City metro area is in a unique position to usurp the technology crown which Silicon Valley currently wears. New businesses, new ideas, new people, and new opportunities are all on the horizon, we must be prepared to take up the mantle of Silicon Prairie.

Please let me know that you, the current leaders of Shawnee, are as excited about this technology as I am, and that you are doing everything in your power to eliminate road blocks which might hinder the arrival of Google Fiber.

Thank you, Samuel Mullen

If you live in the Kansas City metro area and you are not part of the Google Fiber rollout, I would encourage you to contact your city officials as well.

Update: August 24, 2012

The City of Shawnee did end up reaching out to Google. This is their letter.

Getting More Out of the Rails Console

Even at it’s most basic functionality, the console is indispensable in the Rails developer’s arsenal of tools. Whether it’s running a query, testing a chain of methods, or executing small blocks of code, the console may be the most useful tool available to the Rails developer. With that in mind, doesn’t it make sense to do what we can to get the most out of it?

IRB

.irbrc

Under the hood, the Rails Console is just IRB (Interactive Ruby), so anything you can do with IRB, you can do in the console. This means you can modify your IRB environment and .irbrc file to define methods to use at the console. Here are three methods I frequently use:

Useful IRB methods
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
\# return a sorted list of methods minus those which are inherited from Object
class Object
  def interesting_methods
    (self.methods - Object.instance_methods).sort
  end
end

\# return an Array of random numbers
class Array
  def self.test_list(x=10)
    Array(1..x)
  end
end

\# return a Hash of symbols to random numbers
class Hash
  def self.test_list
    Array(:a..:z).each_with_object({}) {|x,h| h[x] = rand(100) }
  end
end

Of course this isn’t even scratching the surface of what’s possible. Check out what other people are doing:

The Last Expression

While working in the console, have you ever typed out a bit of code to return a value and then realize you forgot to assign the returned value to a variable? You then have to go back into the console history, move your cursor to the beginning of the line, add the variable, and then execute the code again.

Ugh, what a pain!

Unbeknownst to most people, IRB places the output of the last command into the _ variable. Here, let me show you:

_ example
1
2
3
4
 > Array(1..10)
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 > _
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Now, as cool as that is, you have to understand that _ always contains the output of the last expression. This means if you try call a method on it, it will then contain the output of the method executed.

_ detailed example
1
2
3
4
5
6
7
8
 > Array(1..10)
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 > _
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 >  _.map {|i| i * 2}
 => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
 > _
 => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

Forking IRB

When working in the console, it’s sometimes desirable to have another instance to play with. It may be that you don’t want to lose what you were working with, or you just need another scratch area, but whatever the case, you can create a new console (IRB) session by calling irb at the prompt (note: you’ll use irb for the rails console as well).

I typically don’t use this. If I need another IRB instance, I just open a new tmux pane or window and work there.

If this sort of method fits your workflow, I highly recommend reading Gabriel Horner’s in depth post on IRB commands

The Rails Console

Models

One of the things you will want to make extensive use of in the console are your app’s models. The Rails console is a great way to play with your models and an alternative way of accessing your data.

Model Example
1
2
3
4
5
6
7
8
9
10
11
 > u = User.find 1234; nil
=> nil

 > u.name
 => "Foo Man"

 > u.email = "fooman@example.com"
 => "fooman@example.com"

 > u.save
 => true

The “app” object

The app object is used by test processes to mimic system interactions. Through this object, we can access routing information and even make requests to our app.

app Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# displaying path information
 > app.users_path
=> "/users/

 > app.user_path(User.last)
=> "/users/42

# making app requests

 > app.get app.user_path(User.last)
=> 200

 > app.response.body
=>  => "<!DOCTYPE html>\n<html>\n  <head>\n    <title>..."

The “helper” Object

I really don’t think I can do a better job on this than what Nick Quaranto already did in his “Three Quick Rails console tips” post.

Reloading the Environment

If you make changes to your app while still in the console, you will need to reload your console session with the reload! command. You will also need to reinstantiate objects which existed prior to the reload for them to recognize your changes.

reload! Example
1
2
3
4
5
6
7
8
 > u = User.find 1234; nil

\# changes made to User model outside the console 

 > reload!
Reloading...
 => true
 > u = User.find 1234; nil

Better Output

At one time it seemed like everyone was writing a gem for improving the IRB experience, but it appears like that particular endeavor has since been largely ignored. The one project that appears to be currently active is the awesome_print gem.

I’ve used this gem in the past, and it really does improve the output and IRB experience. It also supports pry.

In a pinch, you can format the output as YAML with the y command.

y example
1
2
3
4
5
6
7
8
 > y Array.test_list(5)
---
- 1
- 2
- 3
- 4
- 5
 => nil

Avoiding Output

Running commands in the console can get pretty noisy. Output follows every command which is run. To get around this, just end your command with a semicolon and nil.

Avoiding Output
1
2
 > u = User.last; nil
=> nil

In the above example, u still contains the “last” user record, it just doesn’t print out all the output that would normally be produced.

The Sandbox

Sometimes it would be nice to open up a console session and mess around with the data to see what happens. But if you do that, the data’s messed up. The solution to that is to lunch the console with the --sandbox flag. When launched, you can handle the data, tweak it, and destroy it, all without fear of harming any of your data.

Rails Console Sandbox
1
2
3
4
5
rails console --sandbox

Loading development environment in sandbox (Rails 3.2.1)
Any modifications you make will be rolled back on exit
 >

Conclusion

In my workflow, the rails console is an indispensible tool. It allows me to test out ideas, access the database, run minor tasks, and even calculate basic math. I can’t imagine developing Rails applications without it, because I know how painful it is to be deprived of such a tool in other languages and frameworks.

What are your favorite IRB and console tricks?

Validating Booleans

I ran into an instance today wherein I needed to validate that a boolean field was either true or false and not null. I tried using validates :fieldname, :presence => true, but since :presence uses #blank? under the hood, it was reading false as not being present. (Why is false considered blank?)

Anyway, I needed a validator to test whether an attribute was either true or false and I couldn’t find anything among the standard validators, so I wrote my own.

Just plop this file in your app’s lib/validators directory.

truthiness_validator.rb
1
2
3
4
5
6
7
class TruthinessValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value == true || value == false
      record.errors[attribute] << "must be true or false"
    end
  end
end

In your model, add the validation like so:

some_model.rb
1
2
3
4
5
6
7
class SomeModel < ActiveRecord::Base
  ...

  validates :field_name, :truthiness => true

  ...
end

For more information on writing validators, see Getting Started with Custom Rails3 Validators.

Why It’s Okay to Write Crummy Code

There is an inherent need in good developers to write “good” code. We continually look for ways to simplify, enhance, improve, and speed up the code we - or others - have written. We also look back on our older code and shake our head in disgust.

Perhaps it is because of this love of “good” code or perhaps it is because of what we know we can do in more familiar languages, or perhaps, even, it’s because we know what we don’t know, but it seems there is a sort of barrier between learning and using a new technology (by technology I mean a language, framework, methodology, etc.).

Rather than doing, sometimes it’s easier to continue reading and researching. “Just one more section”, “just one more chapter”, “just one more book”. It makes sense, of course, we have to have some sort of foundation upon which to build; and so we read a little bit more.

But the argument that we need to learn just a little more before we begin doing is a hollow argument: we learn far more by doing than by reading. Think back upon when you’ve learned the most: was it when you were in class listening to lectures, or in lab applying what you learned; when you read the chapter, or when you completed the exercises; when you read the API, or tried to implement it?

But the “doing” is difficult, we end up hitting speed bumps and roadblocks, we go in circles in roundabouts, and occasionally we even find ourselves in dark alleyways or hit dead ends, but eventually, if we persevere, we find our way onto the right path. It’s those little success which make all the difference. Finding out what doesn’t work is a learning experience all to itself, but it is the successes, both large and small, which make all the difference. It is the successes which provide us with the energy and motivation to continue on.

With this in mind, go ahead and write crummy code. Write obtuse, ugly, poorly thought out code. Disregard methodologies and best practices, violate principles, ignore everything which hinders you from learning and playing. Fool around and explore, find the speed bumps, the roadblocks, and even the dark alleyways; it’s how you learn and how you eventually succeed.

So to Hell with being ready and writing perfect code; go have fun. If you’re not having fun, you’re doing it wrong anyway.