Fork, clone, and bundle install
By the end of this lesson, students should be able to:
- Create a database table using Ruby on Rails
- Insert a row or rows into a database table using ActiveRecord
- Retrieve a row or rows from a database table using ActiveRecord
- Update a row or rows in a database table using ActiveRecord
- Delete a row or rows from a database table using ActiveRecord
- A working Rails installation.
- An introduction to relational databases
- Required reading: http://guides.rubyonrails.org/active_record_basics.html
ActiveRecord (see also Active record pattern) is the mechanism Rails uses to store and retrieve data from an RDBMS. This, and similar mechanism, are referred to as an Object-relational mapping or ORM.
Why is this important?
Because the vast majority of enterprise data is stored in relational databases, but objects are often used to manipulate that data in applications. And, although NoSQL databases (e.g Mongo DB) have been growing in popularity, their ability to support distributed data to enhance performance makes achieving ACID transactions a significant challenge.
The point of the video is not to state a preference for one technology over another, but to make clear that the need should drive the technology choice, not the hype.
ActiveRecord makes it easy for us to store and retrieve rows from a database table.
What about more complicated data?
ActiveRecord makes it easy to create objects that reference other objects (using tables that reference other tables) which allows arbitrary nesting of objects. This is something we'll be looking at more closely later.
We'll be using PostgreSQL as the RDBMS backing ActiveRecord.
The Rails App we'll be using was created with the command rails-api new --skip-sprockets --skip-spring --skip-javascript --skip-turbolinks --skip-test-unit --database=postgresql.
.
We'll use rails-crud_development
as the database to hold our tables and rails dbconsole (alias rails db
) to interact with it with SQL. By default, each Rails App is created to potentially use one of three databases, <rails app name>_development
, <rails app name>_test
, and <rails app name>_production
. We'll use rails console (alias rails c
) to interactively use Models and rails runner (alias rails r
) to invoke any scripts we write.
$ rails db
psql: FATAL: database "rails-crud_development" does not exist
$
As we can see, rails db
runs psql
. If the Rails app had been configured for a different database server, rails db
would have started a different command line client.
As before, we need to create the database. We'll use the command line application rake which Rails uses to manage changes to the structure of the database (among other things).
$ rake db:create
Rake is a task runner and rake -T
provides a brief description of the tasks it's configured to run from the current Rakefile
. Let's have a look at the db
tasks.
$ rake -T db
We'll store and manipulate information about people.
To generate the code necessary to create a table and the code to manipulate data stored in that table, we use rails generate model
(alias rails g model
). If you run rails g model
without any arguments, Rails tells you what you can do.
$ rails g model Person surname:string
invoke active_record
create db/migrate/<datetime>_create_people.rb
create app/models/person.rb
$
Let's look at the files created. The model created inherits from ActiveRecord::Base. The migration from ActiveRecord::Migration (see also http://guides.rubyonrails.org/active_record_migrations.html).
The table defined by the migration, and needed by the model, isn't created until we run rake db:migrate
.
Together let's create a table and model for cities
Create a table and model for pets, then people
To insert a row we can create a script that uses <Model>
.new combined with <Model>
.save, or <Model>
.create.
Let's add one person then see how we can add people in bulk.
Adding records in bulk recommends a transaction to wrap the call to create!
. We'll set this up as a rake task to make it easier execute.
Together let's do the same for cities.
First pets, then people
By id, <Model>
.find; by criteria, <Model>
.find_by. Let's also look at, http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html and http://guides.rubyonrails.org/active_record_querying.html. The where method provides more complex criteria.
Let's explore how we can retrieve ActiveRecord models for people.
Together let's do the same for cities.
First pets, then people
To modify an existing table we'll run rails generate migration
(alias rails g migration
) followed by rake db:migrate
.
Let's see how we change the table underlying the ActiveRecord models for people. Note that in many circumstances we don't need to change the model class when we change the table.
$ rails g migration RemoveHeightFromPerson height:integer
Together let's change the type for longitude and latitude for cities.
After retrieving an object, we can update it using <model>
.update. Or we can set the models attributes then call <model>.save
.
Let's update some people's weight using each of those methods.
Together let's do the same for some cities' population.
Update weight, first for pets, then people.
To delete a row we'll want to use <model>
.destroy or <Model>
.destroy_all. These methods are especially useful when dealing with Active Record Associations which we'll cover in more detail later.
We'll remove a few people.
Let's remove the cities that don't have a region.
Remove pets born before 1996 then people taller than 6 feet.