In this second part of a five-part series that delves deeply into the Active Record of Rails, you will learn about associations and dependencies. This article is excerpted from chapter five of the book Beginning Rails: From Novice to Professional, written by Jeffrey Allan Hardy, Cloves Carneiro Jr. and Hampton Catlin (Apress; ISBN: 1590596862).
Associations and Dependencies with Active Record (Page 1 of 4 )
Adding the User Model
When we first started the events application, we decided to let anyone create new events. This worked fine when there was only one person using the system, but we want this to be a multiple-user application and let different people sign up, sign in, and start managing their own events, separately from one another.
Up until now, our events have been orphaned—they don’t belong to anyone. We’re going to remedy that now by creating aUsermodel and associating users with events. In our system, each event is going to belong to a user, and a user may have many events. Figure 5-3 illustrates this association.
Figure 5-3.The one-to-many relationship between users and events
Let’s fire up the generator and create theUsermodel now.
$ ./script/generate model User
Just as you saw in the previous chapter, the model generator creates, among other things, a model file inapp/modelsand a migration indb/migrate. Opendb/migrate/003_create_users.rband give it the schema definition shown in Listing 5-2 (add the following code to the file).
Listing 5-2. Migration to Create the users Table, db/migrations/003_create_users.rb
class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.column :login, :string t.column :email, :string t.column :password, :string end
# Add a foreign key reference to users in the events table add_column :events, :user_id, :integer end
def self.down drop_table :users remove_column :events, :user_id end end
This is standard migration fare. In theself.updefinition, we used thecreate_tablemethod to create a newuserstable. The new table object is yielded to the block in the variable,t, on which we call thecolumnmethod to create each row. Along with the standardloginandemailfields, we’re specifying ahashed_passwordfield, which we’ll use for authentication, as we’ll explain in the “Reviewing the Updated Models” section later in this chapter. The primary key,id, will be created automatically, so there’s no need to specify it here. Pay particular attention to theuser_idcolumn in theself.upsection. It’s the foreign key reference column we’ve been talking so much about. Also note that its type is:integer. That’s important, because it’s referring to a numericid.
Now all we need to do is run the migration and create the table using thedb:migrateRake task. Run the migration with the following command:
With the table and foreign keys in place, Listings 5-3 and 5-4 show how we declare the one-to-many association in ourEvent andUsermodels. Add these to the relevant models now.
Listing 5-3. belongs_to Declaration in app/models/event.rb
class Event < ActiveRecord::Base belongs_to :user end
Listing 5-4. has_many Declaration in app/models/user.rb
class User < ActiveRecord::Base has_many :events end
That’s all there is to it. This bit of code has endowed ourEventandUsermodels with a lot of functionality.
■Note All associations (except forhas_and_belongs_to_many, which we’ll cover shortly) need to declare abelongs_toon at least one side of the association. The rule of thumb is that thebelongs_todeclaration always goes in the class with the foreign key.