Aug 6 2006

Raising Model Errors In Rails

Recently I covered rails’ model validators. I wanted to add a few more details regarding the validation methods. If a validation fails you can display an error message in the rhtml view by using the following code:

<%= error_messages_for 'user' %>

The parameter for error_messages_for is the name of an instance variable. An instance variable are those with the at sign, in this case @user. When creating, updating, or saving the @user instance if an error occurs the error_messages_for will create the HTML to display the error.

You can also directly add error messages to the model depending some business logic. In the controller you can add error messages to a model as follows:

@user.errors.add field_name, error_message

One thing to note is that adding errors to the model does not invalidate the model so you might want to save only if there are no errors.

if @user.errors.empty? && @user.save
  # successfully saved with no errors
else
  # Errors occurred, redirect to form
end

Technorati Tags: , , , ,


Jul 29 2006

Rails Model Validators

When developing a Ruby on Rails web application it is a good idea to use ActiveRecord validators to insure the state of a record before posting it to the database. To flush out this example I present the following model:

class User < ActiveRecord::Base
  validates_uniqueness_of :username
  validates_presence_of :username, :password, :email
  validates_size_of :username, :password, :within => 5..15
  validates_format_of :email,
    :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  validates_format_of :username, :with => /^\w+$/i,
    :message => "can only contain letters and numbers."
  validates_confirmation_of :password
  validates_inclusion_of :gender, :in => %w(male female)
  validates_acceptance_of :eula
end

This class models a user in a rails application. The application would normally have a user registration page and a login page. These user validations are checked when trying to save the model into the database but most of them support a :on options that accepts either the :save, :create, or :update values.

Let me now walk through each validation. The validates_uniqueness_of method ensures that the named attribute is unique in the system. In this case, when the record is being saved the system will check against the database to ensure that the username is unique. As mentioned above, this method supports the :on option. This validator also supports a :scope option that limits the scope of uniqueness, meaning that the combination of the values of the named attribute and those listed in the :scope option must be unique.

The validates_presence_of method insures that the list of attributes are not nil, empty, or blank. In this example the username and password attributes require a non empty string value. This validator also supports the :on option.

The validates_size_of method allows you to define the minimum, or maximum, or exact character size of a attribute. In the example above, I used the within range to indicate both the minimum and maximum size of a string.

The validates_format_of method allows you to validate the value of an attribute against a regular expression. The first example of the validates_format_of above is taken straight from the rails documentation and validates that the email attribute actually looks like an email address. The second validate_format_of method ensures that only alphanumeric characters are used for a username.

The validates_confirmation_of method is used to validate that the password typed in is the one the user intended. To confirm the password entered by a user you need to define two input fields in the form to check that they both match. The system will automatically check that the two password match when the user record is saved. Again, this validator supports the :on option. In my registration page I have a form with the following two password fields.

<label for="user_password">Password</label>
<%= password_field 'user', 'pass' %>
<label for="check_password">Confirm Password</label>
<%= password_field 'user', 'pass_confirmation' %>

The validates_inclusion_of method validates that the value of named attribute is in the list specified by the :in option. In this example, the gender of the user needs to be either male or female. You can also specify a range instead of a list. ActiveRecord also supports a validates_exclusion_of method that validates that the value of a named attribute is not within the range or list provided in the :in option.

The validates_acceptance_of method validates that the user accepted some sort of end user license agreement, term or service, or memorandum of understanding via a checkbox in a from. The validates_acceptance_of validator works only when you define a checkbox in the form. This means that in the registration page you can add the acceptance checkbox so that the user must accept the EULA but you can leave out the acceptance checkbox in the user update page. In this example, only when the form has the eula checkbox does this validator takes effect. For this example here is how you define the acceptance checkbox in your user registration form:

<%= check_box :user, :eula %>

To create the checkbox I am using symbols instead of strings, either one works.

There are a few other rails validators that I did not cover here such as validates_associated which is used to validate ActiveRecord associations, validates_numericality_of which can be used to validate if a form value is a number, and validates_each which allows you to define you own validation code blocks.

Technorati Tags: , , , , , ,


Jul 24 2006

Ruby Time Formatting

The Time class in Ruby has a powerful formatting function which can help you represent the time in a variety of ways. The strftime function is modeled after C’s printf. Here are some usages examples:

t = Time.now
t.strftime("%m/%d/%Y %H:%M:%S") # 07/24/2006 09:09:03

t.strtime("%A") # Monday
t.strftime("%B") # July

You can use the lower case a and b to get the abbreviated name of the weekday and month, respectively. To get the the day of the year, between 1 – 366, use the j option.

t.strftime("%j") # 205

The strftime function is useful when formatting the created_at datetime of your Rails application ActiveRecord models.


Jul 23 2006

CSS Hackary

A friend of mine recently asked me what was my most used CSS hack. The first thing I said was that I am not a web designer, I just play one on TV. I have found that everybody knows or can easily look up how to apply a border, text alignment, background image, etc to an HTML element using CSS. What I have discovered through experimentation is that browsers allow you to define more than one CSS class per element. I have recently been using the Yahoo UI Library and their yui-u CSS class that defines a layout block. But for that block I wanted to apply some additional style attributes. I was able to combine the yui-u layout and my style CSS class by doing the following:

<DIV class="yui-u content">CONTENT HERE</DIV>

Technorati Tags: , , ,


Jul 23 2006

Ruby Symbols

If you are new to the Ruby programming language and only just recently started programming in Ruby via Rails you must be wondering what the hell are those thingies used to name actions in the link_to ActionView helper function. Here is an an example of what I mean:

<%= link_to 'link', :action => 'myaction' %>

The :action is a instance of a Symbol. In rails symbols are used as string in many places. For example, instead of providing a string for the name of the action I could have used a symbol:

<%= link_to 'link', :action => :myaction %>

There are a few additional ways to create symbols. You can create the myaction symbol in any of the following ways.

<%= link_to 'link', :action => :'myaction' %>
<% myvar = 'myaction' %>
<%= link_to 'link', :action => :"#{myvar}" %>
<%= link_to 'link', :action => myvar.intern %>
<%= link_to 'link', :action => "myaction".to_sym %>

It is good to remember that symbols are immutable and that the system will only hold onto one copy of a symbol no matter how many times you create references to them.

Technorati Tags: , , ,


Jul 23 2006

Ruby Language Goodies For Java Developers

If you are new to the Ruby programing language you might not be familiar with some of the short semantic sugar or language goodies that Ruby provides. I think that for most of the hard core Java developers the code samples that will be provided here will be novel but Perl hackers will not be impressed. So as an aid to all my fellow Java developers I will try to compare and contrast Ruby code with Java. To get started lets set three values to three variables in one line of Ruby code:

var1, var2, var3 = 'one', 'two', 'three'

You can’t do this in Java. The best you can do in Java is set three variables with the same value, which Ruby also supports, like this:

var1 = var2 = var3 = 'same value'

Methods
In Ruby, you can initialize default values to method parameters. Here is an example of a method with three parameters initialized to a numeral literal, empty list, and empty hash.

def my_method(parama = 1, paramb = [], paramc = {})
  # method implementation here
end

To invoke my_method you can do so with any of the following lines of code:

my_method
my_method()
my_method(2)
my_method(2, [:abc, :def])
my_method(2, [:abc, :def], :abc =&gt; 'abc', :def =&gt; 'def')
my_method 2, [:abc, :def], :abc =&gt; 'abc', :def =&gt; 'def'
my_method 2, [:abc, :def], {:abc =&gt; 'abc', :def =&gt; 'def'}

This is not method overloading as seen in Java. All of the above method calls invoke the same block of code, the same method implementation. In Java you would define overload the method by defining a separate implementation for each method signature.

Java 1.5 recently introduced variable length arguments, varargs. You could have done this in Ruby years back. To define a Ruby method with variable number of parameters you can do the following:

def my_vararg_method *params
  # params is an array
end

To invoke my_vararg_method you can do so with any of the following lines of code:

my_varargs_method # params is empty
my_varargs_method 'string', :symbol, {} # params = ['string', :symbol, {}]

At this time I invite you to notice that parentheses, like semi-colons, are not required.

Objects
In Java you have two types of data, objects and native. An int is completely different than an instance of Integer and depending on the situation you had to constantly convert one to the other. In Ruby everything is an object, and when I say everything I mean everything including the nil value. The nil value is Ruby’s equivalent to the Java null keyword. In Ruby you can do the following:

1.nil? # false
nil.nil? # true
1.3.class # Float
1.is_a? Float # false
'0'.to_i + 1 # 1
Float.class # Class

And because in Ruby everything is an object you don’t need a autoboxing hack to use the literal 1 as a key in a hash.

hash = {1 =&gt; 'one', 2 =&gt; 'two', 3 =&gt; 'three'}

Lists
Another convenient language goodie available in Ruby is the array initializer. If you want to construct an array of string values without white spaces in them you can quickly do so with the following statement:

list = %w(female male) # list = ["female", "male"]

If you need a whitespace inside a word just escape it with the backslash (\). Now If you want to define an array with the first 10 digits you can easily do so with ranges. Here is an example of how to construct an array composed of the numbers between 0 to 9, inclusive.

nums = (0 .. 9).to_a

Here is how to iterate through each letter in the alphabet using ranges.

('A' .. 'Z').each { |char| puts char }

If you want to loop over an array you will need a range from 0 to the array size, exclusive. To create an exclusive range use the … operator as in the following:

arr =  get_list # some array
(0 ... arr.size).each { |index| print arr[index] }

Control
To wrap let me walk through some Ruby control constructs. In addition to the control construct that Java developers are familiar with Ruby provides a unless and until. The ‘unless condition’ is equivalent to ‘if not condition.’ The ‘until condition’ is equivalent to ‘while not condition.’ Here is a trivial example of the the unless construct.

unless item.invalid?
  print item.to_s
end

Ruby also provides a shortcut for the above code in the form of conditional modifiers.

print item.to_s unless item.invalid?

In both of the above code snippets the item will only be printed if the item is in a valid state. You can use if, unless, while, and until as conditional modifier.

As a bonus, let me state where Ruby is lacking. The Ruby language does not support the — and ++ operator. The best you can do in Ruby is use the next method available to the Integer class.