Working with Models

by Dave on May 23rd, 2010

Models

In Rails, the default data structure for a data model is called, naturally enough, a model (the M in MVC) . The default Rails solution to the problem of persistence is to use a database for long-term data storage, and the default library for interacting with the database is called Active Record.1
Active Record comes with a host of methods for creating, saving, and finding data objects, all without having to use the structured query language (SQL) used by relational databases. Moreover, Rails has a feature called migrations to allow data definitions to be written in pure Ruby, without having to learn an SQL data definition language (DDL). The effect is that Rails insulates you almost entirely from the details of the data store.

Create the model

$ script/generate rspec_model User name:string email:string

Migrate “up” using

$ rake db:migrate

Roll back (down) using

$ rake db:rollback

Model annotation

Though it’s not strictly necessary, I like to annotate my Rails models using the annotate models plugin:

$ script/plugin install \
> http://repo.pragprog.com/svn/Public/plugins/annotate_models
$ rake annotate_models

This will cause your model files to look like the following:

# == Schema Information
# Schema version:
# Table name:
# id :integer  not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime
# updated_at :datetime
#

class User < ActiveRecord::Base
end

After adding any plugins, remember to commit to Git

$ git add .
$ git commit -am "Annotated models"

Accessible attributes
Another step that isn’t strictly necessary but is a really good idea is to tell Rails which attributes of the model are accessible, i.e., which attributes can be modified by outside users (such as users submitting requests with web browsers). We do this with the attr accessible method. Using attr accessible is important for preventing a mass assignment vulnerability, a distressingly common and often serious security hole in many Rails applications.

class User < ActiveRecord::Base
  attr_accessible :name, :email
end

Searching models

User.find(1)  # where 1 is the User ID
User.find_by_email("david@example.com")  # notice the method being called to search for the email.
User.first  # finds the first User
User.all  # finds all Users and returns them in an array

Two ways to update attributes

user.email = "notDavid@example.com"
user.save

or using update_attributes which performs the update and saves in one step. It returns true if the save was successful.

user.update_attributes(:name => "The Guy", :email => "guy@example.com")
>> true

Model validations

Add validations to your model files.

class User < ActiveRecord::Base
  attr_accessible :name, :email

  validates_presence_of :name
end

The database will now not allow save’s to pass if all validations do not pass. Use the valid? method to check if an object passes all validations.

Don’t forget to use table indexes when searching using a database column or ensuring uniqueness.
$ script/generate migration add_email_uniqueness_index
add_index :user, :email, :unique => true

From → General

No comments yet

Leave a Reply

You must be logged in to post a comment.