models
USER
id: integer
name: string
email: string
MICROPOSTS
id: integer
content: string
user_id: integer
Creating a resource
rails generate scaffold User name:string email:string
rails generate = a command to rails to make a resource
scaffold = make the model, view, and controller
User = name of the resource
name:string = data attribute of the resource
email: string = data attribute of the resource
czech it out!
bundle exec rake db:migrate
rails s
1. update the database to include our new Users resource
2. run a local server so that we can see the site
ROSES, Smell em
/ users index page to list all the users
/users/1 show page to show user with id 1
/users/new new page to make a new user
/users/1/edit edit page to edit user with id 1
explore your new resource by entering these URLs manually into your browser
does this remind you of anything from the beginning of the class?
MVC IN ACTION
- The browser issues a request for the /users URI.
- Rails routes /users to the index action in the Users controller.
- The index action asks the User model to retrieve all users (User.all).
- The User model pulls all the users from the database.
- The User model returns the list of users to the controller.
- The controller captures the users in the @users variable, which is passed to the index view.
- The view uses embedded Ruby to render the page as HTML.
- The controller passes the HTML back to the browser.
MVC IN ACTION
-
pages correspond to actions in the controller
- a controller is just a collection of actions
- actions: index, show, new, create, edit, update, destroy
Actions either RENDER PAGES or MODIFY DATA
OK, SO LET'S REVIEW
- rails generate scaffold <RESOURCE> <ATTRIBUTES>
- bundle exec db:migrate :This adds the resource to the schema for a database
- the controller for that resource is created; the controller hold actions
- routes.db matches actions with URLs
- These actions perform HTTP requests at these URLs
- They either render pages or modify data (or both!)
microposts
rails generate scaffold Micropost content:string user_id:integer
- What do we need to do now?
microposts
rails generate scaffold Micropost content:string user_id:integer
bundle exec rake db:migrate
Let's see what we did. How?
Microposts
rails generate scaffold Micropost content:string user_id:integer
bundle exec rake db:migrate
rails s
open your browser to localhost:3000
What do you expect to see in your routes.rb file?
What does that mean for your controller and views?
Microposts
What is the action and purpose of each of these?
Where could you go to look?
A CAVEAT ABOUT UNIQUENESS
What can go wrong? Here’s what:
- Luke signs up for the sample app, with address luke@skywalker.com.
- Luke accidentally clicks on “Submit” twice, sending two requests in quick succession.
- The following sequence occurs: request 1 creates a user in memory that passes validation, request 2 does the same, request 1’s user gets saved, request 2’s user gets saved.
- Result: two user records with the exact same email address, despite the uniqueness validation.
what? how? really?
Really.
In order to fix this we need to enforce uniqueness on the database level.
To do this we need to change our model.
A BRIEF INTRO TO DATABASES
Databases are sets of 'tables' that relate to each other in certain ways.
The tables represent our models.
These tables have columns that represent our attributes.
Every database has a file that holds the names of these tables and their associated columns. It is called the schema.
A BRIEF INTRO TO DATABASES
For most databases, you have to write the schema yourself.
In Rails, you don't have to. Instead, the schema is dynamically generated.
We saw this when we generated the User and Microposts models.
We can add to these models by creating migrations.
Migrations
We can created a migration in terminal by typing:
rails generate migration <name_of_migration>
This will create a file in the db>migrations folder that looks like this
class <name_of_migration> < Activerecord::Migration
def change
end
end
Migrations
We can tell Rails to add a column to a model by typing this
add_column <model>, <attribute>, <type>
all of the values above should be typed as symbols, meaning put a colon in front of the name, e.g. :symbol
We can tell Rails to add an index to an attribute by typing this
add_index <model>, <attribute>, unique: true
Migrations
Everytime we write a migration, we need to tell Rails to run it.
We can do that by typing this in Terminal:
bundle exec rake db:migrate
Try it out
- Add a website field to our User model