Deep in the CRUD Deep in the CRUD L EVE L 1 P rer e qui s ite s: - - PowerPoint PPT Presentation
Deep in the CRUD Deep in the CRUD L EVE L 1 P rer e qui s ite s: - - PowerPoint PPT Presentation
Deep in the CRUD Deep in the CRUD L EVE L 1 P rer e qui s ite s: TryRuby.org TryRuby.org TwitteR TwitteR for ZOMBIES for ZOMBIES DB TABLE DB TABLE C olu m ns { (w e h a ve 3) t wee t s R ows { (w e h a ve 4) i d s tat u s z omb i e Z omb i
LEVEL 1
Deep in the CRUD Deep in the CRUD
Prerequisites:
TryRuby.org TryRuby.org
TwitteR for ZOMBIES TwitteR for ZOMBIES
DB TABLE DB TABLE
{
tweets Rows {
(we have 4)
Columns
(we have 3) id status zombie
Retrieve the Tweet object with id = 3
Zombie Challenge #1
b =
Hash
Series of key value pairs b = { id: 3 }
Single key & value Multiple keys & values
variable = { key: value } Hash Recipe:
HASH HASH
{ id: 3, status: "I just ate some delicious brains", zombie: "Jim" }
b =
keys values
:id 3 :status "I just ate some delicious brains" :zombie "Jim" Symbols
HASH HASH
{ id: 3, status: "I just ate some delicious brains", zombie: "Jim" }
Hash
Series of key value pairs
Hash
b = { id: 3, status: "I just ate some delicious brains", zombie: "Jim" } b[:status] b[:zombie] b[:zombie] + " said " + b[:status] => "Jim said I just ate some delicious brains" => "Jim" => "I just ate some delicious brains" variable[:key] => value read recipe:
RETRIEVE RETRIEVE
Read the value
id status zombie 1 Where can I get a good bite to eat? Ash 2 My left arm is missing, but I don't care. Bob 3 I just ate some delicious brains. Jim 4 OMG, my fingers turned green. #FML Ash
{ id: 3, status: "I just ate some delicious brains", zombie: "Jim" }
Result
RETRIEVE RETRIEVE
Retrieve the Tweet object with id = 3
Zombie Challenge #1
tweets
Answer
t = Tweet.find(3)
Retrieve the Tweet object with id = 3
Zombie Challenge #1 RETRIEVE RETRIEVE
{ id: 3, status: "I just ate some delicious brains", zombie: "Jim" }
Result
t = Tweet.find(3)
Answer
id status zombie 1 Where can I get a good bite to eat? Ash 2 My left arm is missing, but I don't care. Bob 3 I just ate some delicious brains. Jim 4 OMG, my fingers turned green. #FML Ash
will allow you to access
Singular & Uppercase Table Name Lowercase & Plural Table Name
CASE & TENSE CASE & TENSE
tweets
Accessing tables
=> 3 puts t[:id] puts t[:status] => "I just ate some delicious brains." puts t[:zombie] => "Jim"
RETRIEVE RETRIEVE
id status zombie 1 Where can I get a good bite to eat? Ash 2 My left arm is missing, but I don't care. Bob 3 I just ate some delicious brains. Jim 4 OMG, my fingers turned green. #FML Ash
tweets
t = Tweet.find(3)
SYNTAX SYNTAX
=> 3 puts t[:id] puts t[:status] => "I just ate some delicious brains." puts t[:zombie] => "Jim" puts t.id puts t.status puts t.zombie Should I use the hash or dot syntax? Student Question: You can use EITHER syntax, It comes down to personal preference.
Alternate Syntax HASH vs DOT SYNTAX
Retrieve the Weapon object with id = 1
Zombie Challenge #2 Answer
w = Weapon.find(1)
CASE & TENSE CASE & TENSE
weapons
id name
1 Ash 2 Bob 3 Jim
Create Read Update Delete
Tweet.find(3) t = Tweet.find(3) t.zombie = "EyeballChomper" t.save t = Tweet.find(3) t.destroy t = Tweet.new t.status = "I <3 brains." t.save
CRUD Crud
CREATE CREATE
t = Tweet.new t.status = "I <3 brains." t.save
- how delicious -
The
i d
gets set for us Recipe
t = TableName.new t.key = value t.save t = TableName.new(hash) t.save TableName.create(hash) t = Tweet.new( status: "I <3 brains", zombie: "Jim") t.save Tweet.create(status: "I <3 brains", zombie: "Jim")
Alternate Syntax
Create a zombie
Read Read Read
Tweet.last => Returns the last tweet Tweet.first => Returns the first tweet Tweet.find(3, 4, 5) => Returns an array of tweets, id of 3, 4, or 5 Tweet.find(2) => Returns a single tweet with id of 2 Tweet.all => Returns all the tweets
Recipes to Read Read Read
Tweet.where(zombie: "ash") => Returns all tweets from zombie named ‘ash’ Tweet.limit(10) => Returns the first 10 tweets Tweet.order(:zombie) => Returns all tweets, ordered by zombies Tweet.count => Returns total number of tweets We can combine any of these read methods together to add constraints
Method Chaining
Method Chaining
- rdered by status
- nly the first 10
.order(:status).limit(10) .where(zombie: "ash") Tweet Tweet.where(zombie: "ash") .first
- nly tweets from zombie ‘ash’
=> Returns just the first one
- nly tweets from ‘ash’
=> Returns
Read Read
CREATE CREATE
t = Tweet.find(3) t.zombie = "EyeballChomper" t.save t = TableName.find(id) t.key = value t.save t = TableName.find(id) t.attributes = hash t.save t = Tweet.find(2) t = TableName.update(hash) t = Tweet.find(2) t.attributes = { status: "Can I munch your eyeballs?", zombie: "EyeballChomper" } t.save t = Tweet.find(2) t.update( status: "Can I munch your eyeballs?", zombie: "EyeballChomper")
Alternate Syntax
Update a zombie
Recipe
Delete a zombie
t = Tweet.find(2) t.destroy Recipe t = Table.find(id) t.destroy TableName.find(id).destroy TableName.destroy_all Tweet.find(2).destroy Tweet.destroy_all Alternate Syntax
DELETE DELETE
Zombie lab 1 Zombie lab 1
Models LIFEBLOOD OF THE APP Models LIFEBLOOD of the app
LEVEL 2
Model
The Lifeblood of the application
How your Rails application communicates with a data store
Models Models
Views Controllers Routes Application Stack Models
Routing ROUTING
?
class Tweet < ActiveRecord::Base end id status zombie 1 Where can I get a good bite to Ash 2 My left arm is missing, but I Bob 3 I just ate some delicious Jim 4 OMG, my fingers turned green. Ash t = Tweet.find(3) tweets Tweet app/models/tweet.rb
Models Models
class Tweet < ActiveRecord::Base end id status zombie 1 Where can I get a good bite to Ash 2 My left arm is missing, but I Bob 3 I just ate some delicious Jim 4 OMG, my fingers turned green. Ash tweets app/models/tweet.rb ActiveRecord::Base Maps the class to the table
Models Models
Tweet
class Tweet < ActiveRecord::Base end id status zombie 1 Where can I get a good bite to Ash 2 My left arm is missing, but I Bob 3 I just ate some delicious Jim 4 OMG, my fingers turned green. Ash tweets app/models/tweet.rb Class .find(3) t =
(Instance of Tweet #3)
Models Models
Tweet
Validations Validations
t = Tweet.new t.save 5
Validations
id status zombie 1 Where can I get a good bite to Ash 2 My left arm is missing, but I Bob 3 I just ate some delicious Jim 4 OMG, my fingers turned green. Ash tweets Ack, we don’t want to create a blank Tweet!
Validations Validations
>> t.errors.messages => {status:["can't be blank"]} >> t.errors[:status][0] => "can't be blank" => #<Tweet id: nil, status: nil, zombie: nil> >> t = Tweet.new >> t.save => false
class Tweet < ActiveRecord::Base end app/models/tweet.rb validates_presence_of :status
validates_presence_of :status validates_numericality_of :fingers validates_uniqueness_of :toothmarks validates_confirmation_of :password validates_acceptance_of :zombification validates_length_of :password, minimum: 3 validates_format_of :email, with: /regex/i validates_inclusion_of :age, in: 21..99 validates_exclusion_of :age, in: 0...21, message: “Sorry you must be over 21”
Validations Validations
validates :status, presence: true, length: { minimum: 3 } validates :status, presence: true validates :status, length: { minimum: 3 } presence: true uniqueness: true numericality: true length: { minimum: 0, maximum: 2000 } format: { with: /.*/ } acceptance: true confirmation: true
Attribute Validation
Validations Validations
Additional Options Alternate Syntax
Relationships Relationships
Because they always travel in packs
RELATIONSHIPS Relationships
tweets
id status zombie 1 Where can I get a good bite to eat? Ash 2 My left arm is missing, but I don't care. Bob 3 I just ate some delicious brains. Jim 4 OMG, my fingers turned green. #FML Ash
We want to store zombies in their own table!
id status zombie_id 1 Where can I get a good bite to eat? 1 2 My left arm is missing, but I don't care. 2 3 I just ate some delicious brains. 3 4 OMG, my fingers turned green. #FML 1
RELATIONSHIPS Relationships
tweets
id status zombie_id 1 Where can I get a good bite to eat? 1 2 My left arm is missing, but I don't care. 2 3 I just ate some delicious brains. 3 4 OMG, my fingers turned green. #FML 1
tweets
id name graveyard 1 Ash Glen Haven Memorial Cemetery 2 Bob Chapel Hill Cemetery 3 Jim My Father’s Basement
zombies
RELATIONSHIPS Relationships
class Zombie < ActiveRecord::Base end app/models/zombie.rb has_many :tweets Plural
RELATIONSHIPS Relationships
id name graveyard 1 Ash Glen Haven Memorial Cemetery 2 Bob Chapel Hill Cemetery 3 Jim My Father’s Basement id status zombie_id 1 Where can I get a good bite to eat? 1 2 My left arm is missing, but I don't care. 2 3 I just ate some delicious brains. 3 4 OMG, my fingers turned green. #FML 1
zombies tweets
HAS MANY
a Zombie Tweets
zombies
class Tweet < ActiveRecord::Base end belongs_to :zombie
Singular app/models/tweet.rb
RELATIONSHIPS Relationships
BELONGS TO
a Tweet a Zombie
id status zombie_id 1 Where can I get a good bite to eat? 1 2 My left arm is missing, but I don't care. 2 3 I just ate some delicious brains. 3 4 OMG, my fingers turned green. #FML 1
tweets
id name graveyard 1 Ash Glen Haven Memorial Cemetery 2 Bob Chapel Hill Cemetery 3 Jim My Father’s Basement
Using Relationships
> ash.tweets => [#<Tweet id: 1, status: "Where can I get a good bite to eat?", zombie_id: 1>, #<Tweet id: 4, status: "OMG, my fingers turned green. #FML", zombie_id: 1>, #<Tweet id: 5, status: "Your eyelids taste like bacon.", zombie_id: 1>] > ash.tweets.count => 3 > ash = Zombie.find(1) => #<Zombie id: 1, name: "Ash", graveyard: "Glen Haven Memorial Cemetery"> > t = Tweet.create(status: "Your eyelids taste like bacon.", zombie: ash) => #<Tweet id: 5, status: "Your eyelids taste like bacon.", zombie_id: 1>
RELATIONSHIPS Relationships
zombies
RELATIONSHIPS Relationships
id status zombie_id 1 Where can I get a good bite to eat? 1 2 My left arm is missing, but I don't care. 2 3 I just ate some delicious brains. 3 4 OMG, my fingers turned green. #FML 1
tweets
5 Your eyelids taste like bacon. 1 id name graveyard 1 Ash Glen Haven Memorial Cemetery 2 Bob Chapel Hill Cemetery 3 Jim My Father’s Basement
RELATIONSHIPS Relationships
> t.zombie.name => "Ash" > t.zombie => #<Zombie id: 1, name: "Ash", graveyard: "Glen Haven Memorial Cemetery"> > t = Tweet.find(5) => #<Tweet id: 5, status: "Your eyelids taste like bacon.", zombie_id: 1>
Using Relationships
Zombie lab 2 Zombie lab 2
VIEW VISUAL REPRESENTATION VIEW VISUAL REPRESENTATION
LEVEL 3
View
VIEWs VIEWS The Visual Representation
User Interface. What we see.
- f the application
Controllers Models Routes Application Stack Views
VIEWs VIEWS
Embedded Ruby
app views zombie_twitter zombies tweets index.html.erb
Edible Rotting Bodies
show.html.erb List all tweets View a tweet Ruby inside HTML
ERB ERB
<% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p>
Show a tweet
<!DOCTYPE html> <html> <head><title>Twitter for Zombies</title></head> <body> <header>...</header> </body> </html>
SHOW SHOW
<% ... %> Evaluate Ruby: <%= ... %> Evaluate Ruby & Print Result: /app/views/tweets/show.html.erb
Show a tweet
/app/views/tweets/show.html.erb
SHOW SHOW
<% ... %> Evaluate Ruby: <%= ... %> Evaluate Ruby & Print Result:
- R
- t
t e n C
- d
e
- W
e a r e r e p e a t i n g t h i s i n m u l t i p l e v i e w s . <!DOCTYPE html> <html> <head><title>Twitter for Zombies</title></head> <body> <header>...</header> </body> </html> <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by </p> <%= tweet.zombie.name %>
/app/views/layouts/application.html.erb
Show a tweet
/app/views/tweets/show.html.erb
<%= yield %>
SHOW SHOW
- Tasty Code -
Every page we create uses this template by default <!DOCTYPE html> <html> <head><title>Twitter for Zombies</title></head> <body> <header>...</header> </body> </html> <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by </p> <%= tweet.zombie.name %>
<%= link_to text_to_show, object_to_show %>
Link Recipe /app/views/tweets/show.html.erb
SHOW SHOW Show a tweet
H
- w
d
- w
e m a k e t h i s a l i n k ? ?
tweet.zombie.name, zombie_path(tweet.zombie) <%= link_to %> <%= link_to tweet.zombie.name, tweet.zombie %>
Alternate Syntax Create a Link As with tweets, shorter is better. <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by </p> <%= tweet.zombie.name %>
/app/views/tweets/show.html.erb
SHOW SHOW Show a tweet
<%= link_to tweet.zombie.name, tweet.zombie %>
<% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by </p>
/app/views/tweets/show.html.erb
SHOW SHOW Show a tweet
<%= link_to tweet.zombie.name, tweet.zombie %>
<% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by </p> Student Question: What options can we use with link_to?
Looking up Documentation
We’ll Billy, we are glad you asked! Our next topic happens to be:
- 1. Look in the source
Open your editor and search for “def link_to” git clone http://github.com/rails/rails.git cd rails Command Line
Link Link Options for link_to
grep -rin “def link_to”
- 1. Look in the source
Open your editor and search for “def link_to”
Link Link Options for link_to
- 2. Look at api.rubyonrails.org
(and search for link_to)
- 1. Look in the source
Open your editor and search for “def link_to”
Link Link Options for link_to
- 2. Look at api.rubyonrails.org
(and search for link_to)
- 1. Look in the source
Open your editor and search for “def link_to”
Link Link Options for link_to
- 2. Look at api.rubyonrails.org
(and search for link_to)
... <%= link_to tweet.zombie.name, tweet.zombie, confirm: “Are you sure?” %>
/app/views/tweets/show.html.erb
app views zombie_twitter index.html.erb application.html.erb layouts The main layout zombies tweets show.html.erb List all tweets View a tweet
VIEWs VIEWS
List Tweets
/app/views/tweets/index.html.erb
tweet.status tweet.zombie.name %></td> %></td> </table> <h1>Listing tweets</h1> <table> <tr> <th>Status</th> <th>Zombie</th> </tr> <% Loop through each tweet %> <tr> <td><%= <td><%= </tr> <% end %>
List Tweets
/app/views/tweets/index.html.erb
Tweet tweet
class single tweet
Tweet.all
array of tweets What they return
tweet.status tweet.zombie.name %></td> %></td> </table> <h1>Listing tweets</h1> <table> <tr> <th>Status</th> <th>Zombie</th> </tr> <% Tweet.all.each do |tweet| %> <tr> <td><%= <td><%= </tr> <% end %>
Link Link
/app/views/tweets/index.html.erb
Create Links
tweet.status tweet.zombie.name %></td> %></td> <% Tweet.all.each do |tweet| %> <tr> <td><%= <td><%= </tr> <% end %>
tweet.zombie.name link_to tweet.status <% Tweet.all.each do |tweet| %> <tr> <td><%= <td><%= </tr> <% end %> , tweet
/app/views/tweets/index.html.erb
Create Links Link Link
link_to %></td> %></td> , tweet.zombie
Empty Table?
Tweet.all <% .each do |tweet| %> ... <% end %>
VIEWs VIEWS
Empty Table? VIEWs VIEWS
Tweet.all tweets <% tweets = ... <% end %> .each do |tweet| %>
Empty Table?
Tweet.all <% <% tweets = %> ... <% end %> <em>No tweets found</em> <% end %> <% if tweets.size == 0 %>
VIEWs VIEWS
tweets.each do |tweet| %>
<% tweets.each do |tweet| %> <tr> <td><%= link_to tweet.status, tweet %></td> <td><%= link_to tweet.zombie.name, tweet.zombie %></td> </tr> <% end %> <td><%= link_to "Edit", edit_tweet_path(tweet) %></td> <td><%= link_to "Delete", tweet, :method => :delete %></td>
Edit & Delete Links VIEWs VIEWS
Action Code The URL Generated List all tweets tweets_path /tweets New tweet form new_tweet_path /tweets/new Action Code The URL Show a tweet tweet /tweets/1 Edit a tweet edit_tweet_path(tweet) /tweets/1/edit Delete a tweet tweet, :method => :delete /tweets/1 tweet = Tweet.find(1) These paths need a tweet
All Links For Tweets
<%= link_to text_to_show, code %> Link Recipe:
VIEWs VIEWS
Zombie lab 3 Zombie lab 3
Controllers BRAINS OF THE APP Controllers BRAINS OF THE APP
LEVEL 4
Controller
Controllers CONTROLLERs The Brains of the application
The binding between the Model and the View
Routes Application Stack Views Controllers Models
Routing ROUTING
/app/views/tweets/show.html.erb
Show A tweet
This code tastes like rotted brains. We will fix it later. <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> <!DOCTYPE html> <html> <head><title>Twitter for Zombies</title></head> <body> <header>...</header> </body> </html>
app zombie_twitter controllers tweets_controller.rb
Controllers CONTROLLERs
/app/views/tweets/show.html.erb <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p>
Request Controllers
/app/controllers/tweets_controller.rb /tweets/1
/tweets/1 /app/views/tweets/show.html.erb <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> app zombie_twitter controllers tweets_controller.rb
Controllers CONTROLLERs
Request Controllers
/app/controllers/tweets_controller.rb tweets tweets tweets It is no coincidence that the word ‘tweets’ is found in the URL, the controller name, and the view folder.
...
Request /tweets/1
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end /app/views/tweets/show.html.erb <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p>
REQUEST REQUEST
/app/views/tweets/show.html.erb <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> def show end
Request /tweets/1
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end tweet = Tweet.find(1)
REQUEST REQUEST
/app/views/tweets/show.html.erb <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> def show end
Request /tweets/1
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end show show
REQUEST REQUEST
def show end
Request /tweets/1
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end /app/views/tweets/show.html.erb <% tweet = Tweet.find(1) %> <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> tweet = Tweet.find(1)
REQUEST REQUEST
This is where we typically call our models, So let’s fix our code!
def show end
Request /tweets/1
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end tweet = Tweet.find(1) /app/views/tweets/show.html.erb <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> What about variable scope? Student Question:
REQUEST REQUEST
grants view access to variables with @ Instance Variable: def show end /app/controllers/tweets_controller.rb class TweetsController < ApplicationController end tweet = Tweet.find(1) /app/views/tweets/show.html.erb <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> @ @ @
Request /tweets/1
REQUEST REQUEST
def show /app/controllers/tweets_controller.rb class TweetsController < ApplicationController end tweet = Tweet.find(1) /app/views/tweets/status.html.erb <h1><%= tweet.status %></h1> <p>Posted by <%= tweet.zombie.name %></p> @ @ @
Rendering a Different View
render action: 'status' end
REQUEST REQUEST
tweet = Tweet.find( ) Params Recipe: def show /app/controllers/tweets_controller.rb class TweetsController < ApplicationController end @
Accepting Parameters
render action: 'status' end /tweets/1 /tweets/2 /tweets/3 /tweets/4 /tweets/5
params[:id]
params = { id: "1" } /tweets/6
REQUEST REQUEST
@tweet = Tweet.create(status: params[:status])
PARAMS PARAMS
Parameters
params = { status: "I’m dead" } /tweets?status=I’m dead @tweet = Tweet.create(status: params[:tweet][:status]) params = { tweet: {status: "I’m dead" }} @tweet = Tweet.create(params[:tweet]) Alternate Syntax /tweets?tweet[status]=I’m dead
@tweet = Tweet.create(params[:tweet]) require(:tweet) permit(:status)
PARAMS PARAMS
Parameters In Rails 4 we are required to use
We need to specify the parameter key we require And the attributes we will permit to be set
Strong Parameters
params = { tweet: {status: "I’m dead" }} /tweets?tweet[status]=I’m dead
- R
- t
t e n C
- d
e
- T
h i s c
- u
l d b e d a n g e r
- u
s ! U s e r s m i g h t b e a b l e t
- s
e t a n y a t t r i b u t e s !
@tweet = Tweet.create(params S t r
- n
g P a r a m s R e q u i r e d
- n
l y w h e n :
C R E A T I N G
- r
U P D A T I N G w i t h M U L T I P L E A t t r i b u t e s
@tweet = Tweet.create(params[:tweet])
PARAMS PARAMS
require(:tweet) permit(:status) . . ) If there were multiple things we needed to permit, we could use an array
params.require(:tweet).permit([:status, :location])
Strong Parameters
/tweets?tweet[status]=I’m dead params = { tweet: {status: "I’m dead" }}
PARSE PARSE
<?xml version="1.0" encoding="UTF-8"?> <tweet> <id type="integer">1</id> <status>Where can I get a good bite to eat?</status> <zombie-id type="integer">1</zombie-id> </tweet> {"tweet":{"id":1, "status":"Where can I get a good bite to eat?", "zombie_id":1}} XML JSON
Respond with XML or JSON?
/tweets/1
PARSE PARSE
{"tweet":{"id":1, "status":"Where can I get a good bite to eat?", "zombie_id":1}} JSON
Respond with HTML or JSON
/tweets/1 tweet = Tweet.find( ) def show /app/controllers/tweets_controller.rb class TweetsController < ApplicationController end @ end
params[:id]
respond_to do |format| format.html # show.html.erb format.json { render json: @tweet } end
.json
PARSE PARSE
XML
Respond with HTML, JSON, XML
/tweets/1 tweet = Tweet.find( ) def show /app/controllers/tweets_controller.rb class TweetsController < ApplicationController end @ end
params[:id]
respond_to do |format| format.html # show.html.erb format.json { render json: @tweet } end
.xml
format.xml { render xml: @tweet } <?xml version="1.0" encoding="UTF-8"?> ...
/app/controllers/tweets_controller.rb
Controller Actions
class TweetsController < ApplicationController end
Views
REQUEST REQUEST
def show def index def edit def create def update def destroy def new List all tweets Show a single tweet Show a new tweet form Show an edit tweet form Create a new tweet Update a tweet Delete a tweet
Controller Actions
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end def show def index def edit def create def update def destroy def new List all tweets Show a single tweet Show a new tweet form Show an edit tweet form Create a new tweet Update a tweet Delete a tweet
EDIT EDIT
def edit /app/controllers/tweets_controller.rb end @tweet = Tweet.find(params[:id])
The Edit Action
EDIT EDIT
app views zombie_twitter tweets edit.html.erb
Adding Some Authorization
EDIT EDIT
DELETE DELETE
Adding Some Authorization
DELETE DELETE
Adding Some Authorization
) redirect_to(tweets_path
Redirect and Flash
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end def edit end if session[:zombie_id] != @tweet.zombie_id end @tweet = Tweet.find(params[:id]) session Works like a per user hash flash[:notice] To send messages to the user redirect <path> To redirect the request flash[:notice] ="Sorry, you can’t edit this tweet"
REQUEST REQUEST
Alternate Recipe: ) redirect_to(tweets_path
Redirect and Flash
/app/controllers/tweets_controller.rb class TweetsController < ApplicationController end def edit end if session[:zombie_id] != @tweet.zombie_id end @tweet = Tweet.find(params[:id]) flash[:notice] ="Sorry, you can’t edit this tweet"
REQUEST REQUEST
redirect_to(tweets_path, "Sorry, you can’t edit this tweet") :notice => Flash + Redirect
/app/views/layouts/application.html.erb
Notice for Layouts
<!DOCTYPE html> <head> <title>Twitter for Zombies</title> </head> <body> <img src="/images/twitter.png" /> <%= yield %> </body> </html>
<!DOCTYPE html> <head> <title>Twitter for Zombies</title> /app/views/layouts/application.html.erb </head> <body> <img src="/images/twitter.png" /> <%= yield %> </body> </html>
Notice for Layouts
<% if flash[:notice] %> <% end %> <div id="notice"><%= flash[:notice] %></div>
DELETE DELETE
Adding Some Authorization
Adding Some Authorization
DELETE DELETE
/app/controllers/tweets_controller.rb
Controller Actions
class TweetsController < ApplicationController end
Views
REQUEST REQUEST
def show def index def edit def create def update def destroy def new List all tweets Show a single tweet Show a new tweet form Show an edit tweet form Create a new tweet Update a tweet Delete a tweet
/app/controllers/tweets_controller.rb
Controller Actions
class TweetsController < ApplicationController end
Views
REQUEST REQUEST
def show def index def edit def create def update def destroy def new List all tweets Show a single tweet Show a new tweet form Show an edit tweet form Create a new tweet Update a tweet Delete a tweet
Need Authorization
@tweet = Tweet.find(params[:id])
Before Actions
/app/controllers/tweets_controller.rb
class TweetsController < ApplicationController end
REQUEST REQUEST
def edit def update def destroy @tweet = Tweet.find(params[:id]) end @tweet = Tweet.find(params[:id]) end end ... ... ...
class TweetsController < ApplicationController end def edit def update def destroy @tweet = Tweet.find(params[:id]) end @tweet = Tweet.find(params[:id]) @tweet = Tweet.find(params[:id]) end end ... ... ... def get_tweet end before_action :get_tweet , only: [:edit, :update, :destroy]
/app/controllers/tweets_controller.rb
BEFORE ACTIONs BEFORE ACTIONs
/app/controllers/tweets_controller.rb
class TweetsController < ApplicationController end def edit def update def destroy @tweet = Tweet.find(params[:id]) def get_tweet end before_action :get_tweet , :only => [:edit, :update, :destroy] if session[:zombie_id] != @tweet.zombie_id flash[:notice] = "Sorry, you can’t edit this tweet" redirect_to tweets_path end def check_auth end before_action :check_auth , :only => [:edit, :update, :destroy]
BEFORE ACTIONs BEFORE ACTIONs
Adding Some Authorization
DELETE DELETE
Zombie lab 4 Zombie lab 4
Routing THROUGH RAILS Routing THROUGH RAILS
LEVEL 5
Application Stack Views Controllers Models
Routing ROUTING
Routes
In order to properly find these paths...
Action Code The URL Generated List all tweets tweets_path /tweets New tweet form new_tweet_path /tweets/new Action Code The URL Generated Show a tweet tweet /tweets/1 Edit a tweet edit_tweet_path(tweet) /tweets/1/edit Delete a tweet tweet, :method => :delete /tweets/1 tweet = Tweet.find(1) These paths need a tweet <%= link_to "<link text>", <code> %>
Routing ROUTING
and these actions...
/app/controllers/tweets_controller.rb
Views
REQUEST REQUEST
class TweetsController < ApplicationController end def show def index def edit def create def update def destroy def new List all tweets Show a single tweet Show a new tweet form Show an edit tweet form Create a new tweet Update a tweet Delete a tweet
We need to define Routes
ZombieTwitter::Application.routes.draw do resources :tweets end Code The URL Generated TweetsController action tweets_path /tweets def index tweet /tweet/<id> def show new_tweet_path /tweets/new def new edit_tweet_path(tweet) /tweets/<id>/edit def edit and a few more.... routes.rb Creating what we like to call a “REST”FUL resource config zombie_twitter
ZombieTwitter::Application.routes.draw do resources :tweets end /config/routes.rb
Custom Routes
http://localhost:3000/new_tweet http://localhost:3000/tweets/new class TweetsController end def new end ... get '/new_tweet' => 'tweets#new' Controller Action Path render Controller name Tweets Action name new
Routing ROUTING
Routing ROUTING
Controller name Tweets Action name index /config/routes.rb
Named Routes
http://localhost:3000/all class TweetsController end def index end ... get '/all' => 'tweets#index' <%= link_to "All Tweets",? %> tweets_path wouldn’t work
Routing ROUTING
http://localhost:3000/tweets render
Controller name Tweets Action name index /config/routes.rb
Named Routes
http://localhost:3000/all http://localhost:3000/tweets class TweetsController end def index end ... get '/all' => 'tweets#index' <%= link_to "All Tweets", %> , as: 'all_tweets' all_tweets_path render
Routing ROUTING
Routing ROUTING
redirects to
Routing ROUTING
but now our definitive URL is /tweets What can we do? What if our tweets used to be found at /all,
Routing ROUTING
get '/all' => redirect('/tweets') get '/google' => redirect('http://www.google.com/')
Redirect
http://localhost:3000/all http://localhost:3000/tweets redirect_to
Routing ROUTING
root to: "tweets#index" <%= link_to "All Tweets", %> root_path Controller Action
Root Route
http://localhost:3000/ http://localhost:3000/tweets render
Routing ROUTING
/local_tweets/32828 /app/controllers/tweets_controller.rb
Route Parameters
/local_tweets/32801 if params[:zipcode] @tweets = Tweet.where(zipcode: params[:zipcode]) else @tweets = Tweet.all end respond_to do |format| format.html # index.html.erb format.xml { render xml: @tweets } end end def index Find all zombie tweets in this zip code
referenced by params[:zipcode] in controller get '/local_tweets/:zipcode' => 'tweets#index' get '/local_tweets/:zipcode' => 'tweets#index', as: 'local_tweets' <%= link_to "Tweets in 32828", local_tweets_path(32828) %> /local_tweets/32828 /local_tweets/32801 Find all zombie tweets in this zip code
Route Parameters
Routing ROUTING
Routing ROUTING
/app/controllers/tweets_controller.rb /github /greggpollack get ':name' => 'tweets#index', as: 'zombie_tweets' Show the tweets for these zombies <%= link_to "Gregg", zombie_tweets_path('greggpollack') %> /eallam /envylabs def index if params[:name] @zombie = Zombie.where(name: params[:name]).first @tweets = @zombie.tweets else @tweets = Tweet.all end end
Route Parameters
Routing ROUTING