Archive for the 'rails' Category

A great quote and another opportunity to learn

By way of Paul Graham comes this quote by Kenneth Clark. I haven’t found the original source, so if you read this and know it, please add it to the comments. When I read this, I realized this is the guiding principle I’ve used in determining what new things to learn as a programmer:

If a lot of smart people have liked something, you should try and figure out what they saw in it.

This is what led me to Ruby and Rails. It’s what led me to Python and the world of dynamic languages five-plus years ago. It’s what drove the decision to implement Rails in Ruby (if I can speak for DHH for a second).

Today, I’ve found another opportunity to learn something new that a lot of smart people rave about: Structure and Interpretation of Computer Programs (Amazon version, Free HTML version). UC Berkely is offering CS 61A The Structure and Interpretation of Computer Programs as part of their free-to-the-public webcast series of courses.

If you love to learn, it’s a great time to be alive.

Good Week for Rails and AJAX On Safari

I’ve been a Safari technical books service subscriber for over four years now. The service just keeps getting better. But I’m not here to pimp Safari (or pimp Safari) but to point out how good of a week it’s been for Rails developers with a Safari account.

Just this week we’ve gotten a Prototype and Scriptaculous shortcut, Ajax On Rails, Prototype Quick Reference, and an update to the beta version of Rails Cookbook.

Here’s what was already on my bookshelf:

I certainly haven’t read all these titles yet, but you’ll not hear me complaining about a lack of Rails documentation.

File Column Unit Testing

In the Rails app I’m currently working on, I’m using the wonderful file-column plugin and updating one of my model’s position attribute manually using an after_create callback. It’s working out well. How do I know this? I tested it of course!

But, I ran into a little bit of a gotcha in the course of development. In my unit tests for the aforementioned model, I use fixture_file_upload when creating new instances. file-column treats these as it would any other uploaded file, which is exactly what we want for testing, with one exception: it stores the uploaded files in the same directory space regardless of RAILS_ENV. So, if you’ve uploaded some files through your browser as part of development, your unit tests will stomp anything with the same id.

The solution? It’s simple but undocumented, so here goes. file_column takes a couple configuration options. One of these is :root_path. It defaults to File.join(RAILS_ROOT, “public”). So, here’s the code from my model:

file_column :image,
            :root_path => ENV["RAILS_ENV"] == "test" ?
                          File.join(RAILS_ROOT, "public", "test") :
                          File.join(RAILS_ROOT, "public"),
            :magick => {:geometry => "640x480",
                        :versions => {:thumb => "128x96"}}

This puts our test files in public/test and our development files in public. I suppose I could move this functionality over to environments/test.rb, but it seems to make sense in the model for now. Opinions and dissent welcomed.

Rails Testing

I’m going to step up onto a crowded soapbox here for a minute.

If you’re not testing while you’re coding a Rails app, you’re doing yourself, your users, and your clients a disservice. I’ve been on Rails for the past year or so, but only recently really buckled down and got serious about testing. Oh, I’ve done some testing here and there, but it was “feel good” testing. You know, just to alleviate the guilt of not doing it at all.

Nowadays, I won’t add a feature without adding tests for it. I should’ve taken this approach all along. All it takes is discipline. The “I don’t have time” excuse, which I’ve used myself, just doesn’t make sense. The time you put into testing is made up for down the line. In the app I’m working on now, a couple things have really convinced me of this.

I’m catching bugs I wasn’t even testing for. For example, I’ve caught myself on a couple of occasions writing code that depended on empty strings evaluating to false. This is an ingrained habit from other languages. In Ruby, one checks String.empty? for an empty string. In Ruby, one checks String.empty? for an empty string. In Ruby, one checks String.empty? for an empty string. I’ve typed it three times now, maybe I’ll remember it.

UPDATE: You should actually be calling String.blank? It’s another nifty Rails add-on. More info here.

The only thing that caught these mistakes were tests. And most of the time, when I catch bugs like this, they are an unintended (but welcome!) side-effect of what I was actually testing for.

When I test, I also identify areas of complexity. I question why this or that has to be so complicated. Sometimes it doesn’t have to be. By making a feature simpler to test, I make the feature itself simpler. Simple is good.

I haven’t quite gotten to the point of test-first development with Rails. I’m not even convinced that that’s the Holy Grail. As long as I’m testing things as I go, whether I do it before or after I start to write the real code doesn’t seem terribly relevant. I know, I know, testing is about design. But, I still feel like I’m getting design benefits without always writing the tests first.

The other thing I’ve only dabbled in is integration tests, and only then out of the necessity to test across multiple controllers. So far, I’m really liking them, if only because they remove the single-controller limitation of functional test. I’m looking forward to diving into integration tests a bit more. The way you can write stories, devise a DSL, and wrap that all up into integration tests is definitely intriguing.

Intro to Rails at BarCampRDU

I mentioned in my last post that the thing I learned the most from at BarCampRDU was leading a session. The session was simply titled Intro to Ruby on Rails. Here’s the thing, and I think Ryan Daigle summed it up nicely: leading a session is different than giving a presentation. I chose to give a presentation and would have been better off leading a session.

The difference is in the level of interactivity, and it’s better for the audience to get them more involved. Leading a session takes more preparation and agility than giving a presentation, because when you are letting the audience direct the content somewhat, you never know where the discussion may lead, and thus, where the boundaries of your knowledge might be reached.

For example, the presentation I gave was originally intended for Python developers who had limited or no exposure to Rails. During one of the morning sessions, I changed it around to be a more general Rails introduction. When I was talking about Ruby blocks and the yield keyword, a Python programmer piped up and said, “Python has yield.” I doubted her, but I looked it up later and she was absolutely right. The Python code base I work with on a daily basis is fairly old-school and generators, which use the yield keyword, didn’t hit Python for real until 2.3, but that’s the subject of another post. I was also clued into Python’s enumerate, which is similar to Ruby’s each_with_index. So, ironically, the boundaries of my Python knowledge were exposed. Good for me, bad for the session.

The other lesson my session experience hammered home was that you never give a slide presentation when a demo would be more appropriate. When the subject of a demo was brought up, everyone wanted to see one. I raced through the slides then got about ten minutes into a demo that was really designed to take about an hour. I ended up finishing the demo with two other people during the hour slotted for the next session. This informal demo was easily the best part of my session. So, demos good, slides bad, let the audience in. I will be better prepared next time.

A funny aside

I was taking notes during the day. Here is one of the sections from my notes:

Cool things that happened before the sessions:

  • I met Andy Hunt
  • A lot of folks proposed talks, more than I expected
  • I got the balls up to propose a talk

During the Rails demo, while I was in the terminal, one of the above lines of text ended up getting inexplicably pasted into the terminal session. I’ll give you one guess as to which one.

Better OO through CRUD

During and after DHH’s keynote at Rails Conf, me and the person I was sitting with talked about how the keynote wasn’t really about CRUD, but about good OO design. By embracing the contstraints of CRUD/HTTP/REST, you’re forced into modeling not just your obvious objects, but the relationships between them. Scott Raymond has just written a great post detailing his quest to refactor IconBuffet by embracing the RESTful approach to controllers and actions. What he ends up with is a better software design.