Musings on RailsConf 2014

This is a bit late, but I wanted to ramble for a bit on RailsConf 2014. I have a few main points that can be summarized as:

  1. TDD isn’t dead, but we’ve opened up a conversation about how useful it is.
  2. RailsConf is less and less about Rails each year and that’s ok.
  3. The Rails/Ruby community is awesome!

TDD isn’t dead

Some people say that DHH declared TDD dead. I disagree. What he did was to open a discussion about testing that we’ve been lacking in the community. The TDD “fad diet” has always troubled me. When TDD proponents quiz a room and ask people how many are using TDD lots of hands go up. Then when they ask if you write your tests first, the hands go down. It makes a point, but it also is a form of shaming. I believe in testing, but I have yet to see a test suite for an app or a gem that I thought was an outstanding example of great code. If it’s out there and I’m just missing it, please let me know. The tools we have now seem to be just barely scratching the surface of what we can do to teach effective testing. I’m thirsty for more testing tips and frameworks that take the confusion out of testing and give us a better way to talk about it and DHH opened the way for that conversation.

RailsConf is less and less about Rails

I’ve been to 3 RailsConfs now. Each one was well worth it. Austin was great as it opened my eyes to the Ruby community and what it has to offer. I learned it’s not possible to ruby without twitter, and that lightning talks rock. There were talks on nearly all aspects of a Rails application, and people even commented on how many were not really about Rails. Even so, talks on coffeescript, backbone, sass and others still seemed dominated the standard Rails talks.

RailsConf 2013 in Portland had Rails as well. But this time it seemed like something was shifting. There were testing tricks, talks on Gotalks about what we can learn from python, and even talks on talks.

And now in 2014, we had a whole track on learning from designers. We also had a track on training and team building and one on playing nicely. There was a talk about saving the world by saving the bees using sinatra. One devoted to databases of all kinds (but just use Postrgre), and another on the tricks our minds play on us.

Overall, I think that signifies that our community is growing, and we have a place for everyone. Which leads to the next section… because…

The Community is Awesome!

Rails is a very open community. We welcome everyone. Yes, there’s always talk about how we get more women, GLBT, and minorities involved, but here’s the thing… we talk about how we can get more women, GLBT and minorities involved! We are not nearly where we need to be yet, but we’re working on it. The more Katrina Owen, Sandi Metz, and Coraline Ehmke get to speak and have a voice, the more women like them will join our community. The diversity of ideas, gender and race can only help us to grow and find new and interesting ways to solve problems.

jQuery data and JSON

jquery_logojQuery is picky about the JSON that is read from in HTML5 data elements. Of course, it’s not really jQuery that’s at fault, it’s simply that the JSON spec is a lot more strict than simple javascript.

In javascript, I can define an object like this:

var object = { look: "ma", no: "quotes" };

Note the lack of quotes on the key names in the object.

Since JSON is a data exchange specification, it requires quoted keys.

So, if you want to put JSON into a data element, you need to do this.

<span data-stuff='{"i":"need","the":"quotes"}'></span>

Here is the relevant quote from the JSON documentation:

“When the data attribute is an object (starts with ‘{‘) or array (starts with ‘[‘) then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names.”

http://api.jquery.com/data/

Community Calendar API

At work, we had a hackathon and developed some sample apps that make use of our new HoopaNow API. HooplaNow is a community calendar in Iowa’s Creative Corridor.

These are still works in progress, but there is a Sinatra app called simply hooplanow_api_example for you Rubyists out there, and a wordpress plugin for those of you who have a wordpress blog, or want to take a peek at some PHP code that uses the API.

Neither is complete, but I would welcome pull requests from anyone who wants to help out.

Learning git made me a better svn user

Before learning git, I rarely created branches in svn projects. Honestly, I don’t know why. It seemed like too much work, but really that was just because I didn’t do it. Now, whenever I start a new feature, I create a branch first.

svn cp {{trunk}} {{branches/blah}}

Sure, it creates a branch on the svn server that may or may not go anywhere, but it’s simple to remove it, so there’s no harm. It also feels a lot safer. Even my experimental code lives on both my system and on the repository server. My commits are getting smaller and more focused as well. Previously, I would often wait until a whole feature was complete before committing. Now, I commit each individual step.

When I’m done, it’s simple to merge back in.

svn merge -r{{start_rev}}:{{end_rev}} {{branches/blah}}

But what about conflicts, right? Git handles merging much better, but again, it’s an unfounded fear. Yes, if changes are made to trunk while you are working on the branch, you might get conflicts, but in my experience, conflicts are rare and the benefits of branching outweigh the risk.

ActiveRecord: self.field vs field

TL;DR version:
“self.field” is only necessary when you are assigning a new value to a field.

It always confused me why it seemed like sometimes using the field name from the database failed to work in model methods that I wrote. When the method was simple, things would work fine, but then something would happen and it suddenly stopped working. I never quite put together what was going on until now. I would start out with something like this:

# Very simple, overused, contrived example
def full_name
  "#{prefix} #{first_name} #{last_name}"
end

It works beautifully and looks clean. But then, I’d need to add some defaults, like so.

def full_name
  prefix = "Mr." if prefix.blank?
  first_name = "First" if first_name.blank?
  last_name = "Last" if last_name.blank?
  "#{prefix} #{first_name} #{last_name}"
end

At first glance, it looks right, but it’s not. It causes full_name to produce “Mr. First Last”, every time you run it. WTF? Here’s where I would usually overreach and get it horribly wrong. I know that the fields are available as “self.field”, so I make one more change.

def full_name
  self.prefix = "Mr." if self.prefix.blank?
  self.first_name = "First" if self.first_name.blank?
  self.last_name = "Last" if self.last_name.blank?
  "#{self.prefix} #{self.first_name} #{self.last_name}"
end

So, one WTF leads right to another. This code is horrible. It’s ugly and it feels like there should be a better answer. In this example, it’s not so bad, but what usually ends up happening is this type of code gets written in a method that is already fairly ugly, and because of a simple misunderstanding, it goes directly from bad to worse.

Finally having some time, and just being fed up enough, I did some searching and found this. It ends up being fairly easy to understand once you think about it. In ActiveRecord models, the fields are methods. The way Ruby works, writing “field = ” creates a local variable instead of calling the “field=” method on self. It is the very act of assigning the field with a default that causes the issue. So, you can scale it back a little and rewrite the code like this. You only need “self.field” when assigning a new value.

def full_name
  self.prefix = "Mr." if prefix.blank?
  self.first_name = "First" if first_name.blank?
  self.last_name = "Last" if last_name.blank?
  "#{prefix} #{first_name} #{last_name}"
end

Much better.

My .gitconfig

Here’s my current .gitconfig file. It’s very simple, but it makes using git so much better. git s is a simplified git status, and git l is a log that shows one-line commit messages and a tree that shows where branches and merges were made.

[color] 
   ui = true 
[alias] 
   s = status -su 
   l = log --graph --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'

I also highly recommend you check out the table below, which I’ve copied from the bottom of the 10 things I hate about git post. It helps make sense of some common commands that I thought were useless as well. Adding the switches Steve Bennett recommends clears things up a bit.

Base commandUseless functionalityUseful commandUseful functionality
git branch fooCreates a branch but does nothing with itgit checkout -b fooCreates branch and switches to it
git remoteShows names of remotesgit remote -vShows names and URLs of remotes
git stashStores modifications to tracked files, then rolls them backgit stash -uAlso does the same to untracked files
git branchLists names of local branchesgit branch -rvLists local and remote tracking branches; shows latest commit message
git rebaseDestroy history blindfoldedgit rebase -iLets you rewrite the upstream history of a branch, choosing which commits to keep, squash, or ditch.
git reset fooUnstages filesgit reset –hard
git reset –soft
Discards local modifications
Returns to another commit, but doesn’t touch working directory.
git addNothing – prints warninggit add .
git add -A
Stages all local modifications/additions
Stages all local modifications/additions/deletions

Test IE virtual machines made easy

I just have to take a minute and thank @xdissent et al. for the amazing work done on ievms. I was able to install IE 6,7,8 and 9 virtual machines without hardly any work on my part.

I am running Ubuntu 12.04, and after uninstalling the virtualbox package found in the standard repository and installing the one found here, I simply ran the command in the readme, went to bed, and in the morning I was greeted with this in my VirtualBox window.

So far, each of them has worked without issue.