Chris Bloom
I've been developing web applications since earning certificates in client/server technologies and Unix administration from WPI in 1998/1999. I began my career using classic ASP, but now focus on PHP while experimenting with Ruby and Ruby on Rails. I specialize in creating scalable, data-driven web applications. I have worked with a variety of servers and development environments. I am analytical, thorough and user-conscious. I enjoy working directly with users and clients. I am a proponent of designing and testing for usability, unobtrusive scripting, accessibility, semantic markup, white-space, in-line comments, table-reduced designs and content reduction.
Posts by Chris Bloom
Testing for a redirect using Capybara and Selenium WebDriver
0I just spent the better part of 8 hours trying to figure out how to do this. The Selenium WebDriver API docs are pretty bewildering especially when it comes to trying to interact with the HTTP response or request itself because those constructs are abstracted quite a bit.
Then /^I should be on the (.*) page$/ do |page_name|
object = instance_variable_get("@#{page_name}")
page.current_path.should == send("#{page_name.downcase.gsub(' ','_')}_path", object)
page.status_code.should == 200
end
Then /^I should be redirected to the (.*) page$/ do |page_name|
page.driver.request.env['HTTP_REFERER'].should_not be_nil
page.driver.request.env['HTTP_REFERER'].should_not == page.current_url
step %Q(I should be on the #{page_name} page)
end
Which we can use in a Cucumber feature like so:
Given I am on the homepage When I click on the link to add a widget Then I should be able to complete the widget form And I should be redirected to the widget page And I should see a confirmation message And I should see the widget listed
Setting up a Rails 3 virtual machine using Vagrant and VirtualBox
0I recently started bringing other developers on board to help me with a project that up until then I had been the sole developer on. I already had some rudimentary installation instructions that I had updated on occasion as I was originally developing the application, but it turns out that all the developers experienced problems of one kind or another while following along on their own development machines. Although I had recommended using RVM to at least isolate the application gem bundle, it was clear that there were other per-machine libraries and dependencies that were not being accounted for. So, I decided to include instructions on setting up a virtual machine which would hopefully alleviate these issues. My problem with VMs in general though, especially ones that you want to spin up and tear down quickly, is that it’s still possible for everyone involved in the project to be using a different VM manager and linux distro, and thus a different package manager and standard lib setup, and you still need to do a lot of setup after the fact to get all the necessary components to work. Enter Vagrant. (more…)
Notes on STI in Rails 3.0
5I’m currently working on a project that calls for splitting up a single model into two similar models with slightly differing functionality. I was already familiar with Alex Reisner’s excellent article on when to use Single Table Inheritance versus the other alternatives that one might use, and after re-reading the article with a colleague it was determined that STI was probably our best bet. However, neither of us could remember seeing any recent articles on STI in Rails, specifically with Rails 3, and it’s been my experience that if people aren’t talking about a Rails feature it’s probably because it’s been recently deprecated or replaced.
Not wanting to back ourselves in a corner before we were sure it would work, I decided to spike a dummy Rails app and see what problems we would run into. There are plenty of questions on StackOverflow (1, 2, etc.), et. al., with various suggestions for working through issues related to STI, but there was no one concise guide that detailed the benefits and drawbacks of each approach. I decided to document my findings. This is my first real-life attempt at implementing an STI pattern, so please leave a comment if you feel that I omitted something or if you know of another way to approach one of these issues.
Testing model validations in rspec the short and sweet way
0There seems to be a divide in the Rails/TDD community over whether you should bother testing your model validations. On the one hand, it’s silly to just retest what the Rails core team has hopefully already tested — that validations work. On the other hand, I want to make sure that my models only accept the data that I design them to accept. I also tend to use my RSpec unit tests as blueprints for building out my models, in true TDD fashion, so I start out by defining what values they should accept.
Named redirect routes in Rails 3
0I didn’t see this mentioned anywhere in the Rails Guide or in my admittedly cursory Google searches, but apparently it’s possible to create named redirect routes in Rails 3. For example:
Myapplication::Application.routes.draw do match "/facebook" => redirect("http://www.facebook.com/pages/MarkZuckerbergFanClub/12345678"), :as => 'facebook' match "/twitter" => redirect("http://twitter.com/TweetyMcTweet"), :as => 'twitter'endThen you can use those in your layouts like so:
<ul class="social-links"> <li class="facebook"><%= link_to "Like us on Facebook", facebook_path %></li> <li class="twitter"><%= link_to "Follow us on Twitter", twitter_path %></li></ul>
It Should Include Only One Of – An RSpec Matcher
0I know RSpec tests should typically be implementation/data agnostic, but I ran into a situation in a unit test where I needed to make sure that the results of a query returned only one of the two records that were created during the setup but without knowing which record that would be ahead of time. This was due to the fact that the scoped finder returned a random record. So, I wrote a little matcher that lets me assert that a given array contains only one of a set of specified elements.
# Inspired by http://blog.nicksieger.com/articles/2011/01/20/rspec-2-matcher-funRSpec::Matchers.define :include_only_one_of do |*elements| match do |container| @included = [] elements.flatten.each do |e| @included << e if container.include?(e) end @included.count == 1 end
failure_message_for_should do |container| "expected array of #{container.length} elements to include only one member.\n" + "Found #{@included.flatten.inspect}" endendYou can use it like so:
require 'include_only_one_of'
describe "SomeTest" do it "should return only one wide format promotion if available" do first_wide_promotion = Factory(:promotion, :brand => @brand, :format => Promotion::FORMATS[:wide]) second_wide_promotion = Factory(:promotion, :brand => @brand, :format => Promotion::FORMATS[:wide]) @brand.featured_promotions.should include_only_one_of(first_wide_promotion, second_wide_promotion) endendJoin (implode) an Array of String Values with Formatting
1In programming, I often need to join values together from an array. Typically this will be to do something on the backend, like join a list of integers together in a comma-delimited string for use in a SQL statement. For those times, the native join/implode functions work fine. Occasionally however, we need to finesse the resulting string to look a little more readable. I wrote a small function to do so. It’s called pretty_join()
<?phpfunction pretty_join($array, $intermediate_separator = ', ', $final_separator = ' & '){ if (!is_array($array)) return null; switch (sizeof($array)) { case 0: return null; break; case 1: return reset($array); break; case 2: return implode($final_separator, $array); break; default: $end = array_pop($array); // This second call prevents the last two elements from being reversed $end = array_pop($array) . $final_separator . $end; array_push($array, $end); return implode($intermediate_separator, $array); }}?>Given an array of 0 or more values, pretty_join() will concatenate all of the values together using a common delimiter (a comma by default) except for the last two values which will be joined by the final separator (an ampersand by default).
Examples:
<?php//pretty_join with 0 elementsecho pretty_join(array());// =>//pretty_join with 1 elementsecho pretty_join(array('Big Tires'));// => Big Tires//pretty_join with 2 elementsecho pretty_join(array('Big Tires', 'Pretty Houses'));// => Big Tires & Pretty Houses//pretty_join with 3 elementsecho pretty_join(array('Big Tires', 'Pretty Houses', 'Fat Wives'));// => Big Tires, Pretty Houses & Fat Wives?>Writing the First Cucumber Feature
0I’m currently working on my first BDD project, but after reading through the Cucumber wiki for what felt like the 100th time I was still not sure where to start. I tried generating a boilerplate feature file as the documentation suggests (even though the documentation then tries to dissuade you from taking that approach in the next paragraph), but the generated file didn’t really provide much guidance so I was back to square one. Finally I started asking for advice on the freenode #cucumber channel. It seemed like a shot in the dark, knowing that every project is different and there isn’t really a single pattern that would work for everyone. The initial responses were less than illuminating, but after a few short minutes someone offered the following advice:
msassak: auth features are not very valuable, imo msassak: you need to do them, but i would implement almost anything first msassak: err anything else cbloom: So assume every user is registered for now. Then start hiding stuff after the other features are complete? msassak: that's what i would do cbloom: OK, that makes a lot of sense. msassak: imagine you are going to present this to someone who is going to pay you for it msassak: do they want to see that users can log in, or that users can do something cool on the site? cbloom: they want to see that users can print coupons cbloom: so I'll start with that msassak: yup, exactly cbloom: so simple, yet so abstract
It seems so simple now. Now to see if that actually cures my writers block.
Asserting your domain expertise and learning to say “no” to your clients
1When talking with colleagues about work, one of my biggest gripes is finding out they couldn’t say “no” to a client and are now stuck doing shit work. Having worked as a programmer and consultant for almost 10 years, I’ve certainly swallowed enough “no”s just to get a paycheck. But as the years went on, I realized that I was really just whoring myself out for pennies on the dollar when it was all said and done. The amount of time I ended up spending trying to implement a fix for that one CEO that refused to upgrade away from IE 6 was just never worth my time, and I get no satisfaction from having to hack up my own code in a less than beautiful way to make it happen.
More recently I’ve grown perversely attracted to the idea that I can say “no” to projects and still make a living. There is an axiom in the financial markets that the deal of a lifetime comes along every day, every week, every month, etc. Saying “no” to a mediocre project leaves you open to take on the great project that comes along right behind it. But even at a smaller scale, such as an enhancement request, it feels really good to not only say “no” to a client, but also back up that response with statistics that make great business sense. It wasn’t always a comfortable thing for me though, and I think it’s a privilege gained only through experience. (more…)
Earn Extra Money from Home with Web Development
1Note: This article is aimed at people who are unfamiliar with web development, as opposed to the other articles on my website which tend to be written for a more technical audience.
Many times I’ve heard or seen someone asking about ideas for ways that they can make a little extra money from home. The majority of these requests are from women that are stay-at-home mothers. That’s worth noting only because the responses therefore tend to gravitate towards Mary Kay, Athena, Silpada, etc., and which are essentially sales jobs with small commissions. I’m not knocking those jobs. Lot’s of people have personalities that are perfect for that type of job, and they have no problem making the commitment necessary to make it worth their while. But I would wager that there are just as many people for whom those types of jobs just don’t appeal to. Considering that, I am always tempted to answer with “try your hand at web development.” The inevitable response to that has been “but, I don’t know how to program!” That is a valid concern, but it’s also not an entirely accurate one. (more…)


Recent Comments