Wednesday, June 22, 2011

Rails Validation Syntax

Tonight while working through Agile Web Development with Rails, I was finishing up Chapter 7 and doing some of the extra stuff at the end. One of the exercises was adding validation to the Product model that checks the length of product titles is at least 10 characters.

No big deal! I fired up Rails API and found what I was looking for.

validates_length_of :title, :minimum => 10, :message => 'must be at least 10 characters.'

Ahh, perfect! Plus, editing the default message is the second optional exercise. Easy enough. But wait, what's this?

The book had me write validation like so:

validates :price, :numericality => {:greater_than_or_equal_to => 0.01}, :message => 'must be a number.'

This is a slightly different syntax than the validation I found on the Rails API and I don't like it as much. First, it's not as immediately obvious what this validation is doing. Second, it just feels clunkier. So since I'd already written a validation method in a different syntax, I figured this would do the same thing and be in a more readable format:

validates_numericality_of :price, :greater_than_or_equal_to => 0.01, :message => 'must be a number.'

And what do you know? It works! Is there anything I should be aware of when writing validation like this? Any ideas why Agile Web Development with Rails wrote it the other way? Personal preference of the programmer, perhaps? I'm assuming this is a standard way of writing validation, both because it's the same syntax I found on the Rails API, and because it's more readable. (It's also 5 characters shorter, but who's counting? A piece of Javascript I found online, that's who!)

Ahh, feels good to be making progress. I got hung up for a bit writing tests in the last chapter, until I realized I'd added a stray period and it was holding everything up. Anyone else try running test:unites by mistake? I've probably done it 3 or 5 times in the last 18 hours.

Sunday, June 19, 2011

Creating a new application with an older version of Rails

This weekend, I've been working through Agile Web Development with Rails, but I ran into a problem. The book is using Rails version 3.0.5, and I've been updated to Rails 3.1.0.rc2. Some things have been changed from Rails 3.0 to Rails 3.1. Most of these appear to be small, easy to work with changes such as moving images and stylesheets from /public to /assets, but Jquery is the new default javascript library for Rails and this is where I ran into trouble.

First off, I noticed the CSS wasn't working exactly as it did the first time I went through Agile Web Development with Rails. Mostly some minor issues that I was able to work with, and this wasn't that big a deal, since styling is best left until later. But the book deals with some styling up front, so this issue threw a red flag.

Next up, I noticed my :destroy method wasn't working. I ran into this issue a couple weeks ago with Chorenivore, and it was a matter of configuring Jquery. So I tried the fix that worked for me before, but I'm not sure why it wasn't working with a Rails 3.1 app. Is there more configuration needed? I generated the code with a scaffold command, so I'm not sure why it wasn't working by default.

At any rate, whether this is a bug (doubtful, even though this is a beta version of Rails 3.1) or I just didn't configure everything correctly, I decided the best solution for now is to create a new application using the same version used in Agile Web Development with Rails.

So the command for creating a new application with a previous version of Rails is easy enough:

rails _3.0.5_ new depot

In this case, I want to use Rails 3.0.5 and my project is named depot, so that's all there is to it! I think the gemfile may need to be edited as well, but so far I haven't run into any issues.

Rails is a framework that is updated and changed regularly, so I know in the long term I'll want to stay current with new versions. But for now, it's more important for me to keep learning and reinforcing what I already know, so using an older version of Rails is the way to go.