Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.
First, we'll run the Rails model generator to create the models used throughout this project. The Rails model generator automatically creates stub files for the models and database migrations. Then we'll edit the generated files to add our own functionality.
expenses> ruby script/generate model Project
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/project.rb
create test/unit/project_test.rb
create test/fixtures/projects.yml
create db/migrate
create db/migrate/001_create_projects.rb
expenses> ruby script/generate model Expense
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/expense.rb
create test/unit/expense_test.rb
create test/fixtures/expenses.yml
exists db/migrate
create db/migrate/002_create_expenses.rbThe generator creates the Project model in app/models/project.rb and the Expense model in app/models/expense.rb, along with unit test stubs and test fixtures. The generator also created two migrations for us: db/migrate/001_create_projects.rb and db/migrate/002_create_expenses.rb.
Now that the model generator has created these two new migrations, we need to add the column definitions that will be used by the models as attributes. For now we'll only track the name of each project. Open up db/migrate/001_create_projects.rb and edit it to look like this:
class CreateProjects < ActiveRecord::Migration
def self.up
create_table :projects do |t|
t.column :name, :string
end
end
def self.down
drop_table :projects
end
endWe only added a single line, t.column :name, :string, to the migration. This line adds the column name of type String to the database table projects. Next, define the columns for the expenses table. Same routine: open up db/migrate/002_create_expenses.rb and add the columns project_id, description and amount.
class CreateExpenses < ActiveRecord::Migration
def self.up
create_table :expenses do |t|
t.column :project_id, :integer
t.column :description, :string
t.column :amount, :float
end
end
def self.down
drop_table :expenses
end
endAssuming that the database has already been created and the database connection has been configured, we can run the migrations. This will add the tables and columns defined in the two migration files to the development database configured in config/database.yml.
expenses> rake migrate
Now that the database contains the schema for the Expense Tracker we can define the relationships between the models. A Project has many Expense objects, so add the has_many() relationship to the Project model in the file app/models/project.rb.
class Project < ActiveRecord::Base has_many :expenses, :dependent => :delete_all end
We added the :dependent => :delete_all option to the has_many() call because we don't want any orphaned expenses lingering around in our database without a Project. Now define the belongs_to() relationship in the Expense model. An Expense object belongs_to() a Project because the Expense contains the foreign key. Open up app/models/expense.rb.
class Expense < ActiveRecord::Base belongs_to :project end
Now that the models are defined and the database is ready to go we can move on to the next step─generating and defining the controllers.