Skip to content

Instantly share code, notes, and snippets.

@jim-clark
Last active April 10, 2018 15:50
Show Gist options
  • Save jim-clark/ab06625d4d1e0c2ab158 to your computer and use it in GitHub Desktop.
Save jim-clark/ab06625d4d1e0c2ab158 to your computer and use it in GitHub Desktop.

This presentation is available at:
https://presentations.generalassemb.ly/ab06625d4d1e0c2ab158#/1


Intro to Models in ActiveRecord


Learning Objectives


  • Explain the Use Case for ActiveRecord

  • Generate a Model

  • Run a Migration

  • Explain What a Migration Does

  • Create Data With a Model


What is ActiveRecord?


  • ActiveRecord is the layer of the Rails framework dedicated to working with data.

  • ActiveRecord implements the M in the MVC application architecture.

  • Previously, you saw how how data is stored in rows in a relational database where each row represented a single instance of a specific data entity, e.g., a blog post, a comment, an author, etc...


What is ActiveRecord? (cont.)


  • As "fun" as it is writing SQL commands to create tables and perform CRUD on data, ActiveRecord provides us with a more productive, a more objected-oriented way to work with data in our application.

  • ActiveRecord is known as an Object-Relational-Mapper, or ORM for short. ORM's are very popular in the world of software development because they allow us to work with data in our code via objects and methods, abstracting away the DB to the point we don't even know it's there.


Models


Intro to Models

  • In Rails, a Model is a class that represents a data entity. For example:

  • We will use Model classes to create, update and delete data entities in the database.

  • For example, if you wanted to create a new book, you would create an instance of the Book class and "save" it.
    How do we create an instance of a class in Ruby?


Intro to Models

  • Every model in our app will have a dedicated table in the database. There is a one-to-one mapping between them.

  • Note that the name of the Model class is singular (and upper camel case like all classes in Ruby) and the table name is plural (and snake cased).


Intro to Models


  • When we create a Model class, you will see that no attributes are defined in the Model class. The attributes are defined in the database table's schema.

  • In addition to performing CRUD, we use Models primarily to:

    • Inform ActiveRecord of the relationships with other Models (as shown in the previous diagram).
    • Define optional data validations.
    • Add custom behavior, for example, provide a full_name method.

Intro to Models


  • Here's another example showing Customer and Order Models:

  • A database review question: What type of column is the customer_id column in the orders table?

Working with Models - Workflow

For your reference, here's a list of steps you might follow to start a new Rails app that uses Models:

  • First, we need to create the Rails app before we create any Models:
    • We'll be working with the PostreSQL database (why?) so be sure to create your new app like this:
      rails new my_app -d postgresql -T
    • cd my_app
    • Run this command to create the database:
      rails db:create
    • Start the Rails server with rails s and browse to localhost:3000 to ensure all is well before creating any Models.

Now we can generate our Model(s)...


Working with Models - Workflow


  • With the Rails app created, here's what we need to do to create Models:
    • Use rails g model <Model name> <attribute list>... to generate your Model's class file and database migration file.
    • Run rails db:migrate to update the database's schema (structure) with any pending migrations.
    • Code your routes, controller & views as usual.

Ready? Let's try it out...


Creating our First Model


Setup our App


  1. Create a new app and specify PostrgeSQL:
    rails new car_app -d postgresql -T

  2. cd car_app

  3. Create the database:
    rails db:create

  4. Open the project in your text editor.

  5. In a new Terminal tab, rails s then browse to localhost:3000


Generating our Model


  • Let's generate a simple Model to represent car objects:
    rails generate model Car make:string year:integer price:float

  • After running this command, there will be a car.rb file in the models folder that has the following code:

     class Car < ApplicationRecord
     end

Generating our Model (cont.)


  • We will always define our Models with a name that represents a singular data object, e.g. Car, not Cars.

  • Wait, there's no attributes or anything else in there.
    Who can tell us where to find which attributes our Model has?


Migrations


  • Besides the Model class file, the model generator created a migration as well.

  • A migration file contains code that rails runs to modify our database's structure. What do we call the database's structure? What file in a Rails app represents it?

  • We will find the migration we just created in the db/migrate folder - let's check it out...


Migrations (cont.)

  • Note the filename is prefaced with a timestamp so that it sorts in chronological order.

  • We create migrations to modify the database over time as our application evolves.

  • We'll see that a migration is a class that inherits from ActiveRecord::Migration. The code inside of the class is a Ruby DSL.

  • Migrations can generate new or modify existing tables, e.g., to add/remove columns (attribute). These docs explain how.


Database Schema


  • You can check what the database schema file looks like by looking at the db/schema.rb file. But it doesn't exist yet because we haven't run a migration yet.

  • Now let's run the migration: rails db:migrate
    This is how we run all "pending" migrations.

  • To check the status ("up" or "down") of the migrations, run this command: rails db:migrate:status


Database Schema (cont.)


  • Now that we've run a migration, there will be a schema.rb file.

  • Look, but never touch the schema.rb file - consider it read-only. Our database schema must only be modified with _________!


Database Schema (cont.)


  • The naming convention for tables is the pluralized, snake-cased version of the Model class it represents.

  • Besides the make, year and price attributes we generated, note that Rails automatically generated created_at and updated_at datetime attributes for us.

  • Lastly, although not shown in schema.rb, there will always be an id attribute of type integer in every table/model.


Creating Data with Models


The Rails Console


  • Before we start using Models in controllers and views, let's see how we can do some CRUD in the Rails console.

  • Make sure that you're in your app's folder and run:
    rails console
    or
    rails c for short.

  • The console will load all of our app's Model classes automatically so that we can use them.


Creating New Model Objects


  • There are two methods we can use to create model instances in our database: new and create.

  • The difference between the two being that new creates an in memory instance of the Model that still needs to be saved to the database, while create will create an instance and save it to the database automatically.


Creating New Model Objects (cont.)


  • First, let's take a look at the new method:

     car = Car.new
     car.make = "Toyota"
     car.year = 2015
     car.price = 25000
     # the above code is same as this one line:
     # car = Car.new(make: "Toyota", year: 2015, price: 25000)

Creating New Model Objects (cont.)

  • Typing car will reveal that the id is equal to nil. This signifies that this is an in memory object only and has not been saved to the database yet.

  • Let's save it:

     car.save
  • Looking at the console's output will show us the SQL that ActiveRecord is abstracting us from, but more importantly, the result of the car.save method, which should be true.


Creating New Model Objects (cont.)



The process of saving in-memory data to a more permanent storage, such as a database, is known as:



Persistence


Creating New Model Objects (cont.)

  • If the save method fails, it will return false. This can happen for example if data is missing for required attributes or there's invalid data. This allows us to take different actions in our controllers. For example:

     if @car.save
     	# redirect to the show view
     	redirect_to car_path(@car)
     else
     	# render the new view again
     	render :new
     end

Creating New Model Objects (cont.)


  • Now let's look at the create method.

  • Calling create basically is like calling new + save:

     car2 = Car.create(make: "Mini", year: 2016, price: 20000)

Creating New Model Objects (cont.)


  • Another difference between create and new + save is that create will always return an object, which always evaluates to truthy.

  • So, to check if the model was saved successfully in the database, use the valid? method like this:

     if Car.create(make: "Mini", year: 2016, price: 20000).valid?
     	#successfully saved
     ...

Quick Review




####Let's go around the room and review the workflow when creating a basic Rails app with a model.


Practice


  1. Create another Model named Person with these attributes:

    • first_name (string)
    • last_name (string)
    • age (integer)
  2. Add one Person to the database using new.

  3. Add another Person to the database using create.


Final Questions


  • Models have a one-to-one mapping with __________ in the database.

  • A database's schema should only be modified using __________.

  • If we have a Model class called LineItem, what will the table be named?

  • As our application evolves over time, we use __________ to modify our database's schema.

  • What benefit does an ORM provide to developers?


References


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment