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
SMART_READER_LITE
LIVE PREVIEW

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


slide-1
SLIDE 1
slide-2
SLIDE 2

LEVEL 1

Deep in the CRUD Deep in the CRUD

slide-3
SLIDE 3

Prerequisites:

TryRuby.org TryRuby.org

slide-4
SLIDE 4

TwitteR for ZOMBIES TwitteR for ZOMBIES

slide-5
SLIDE 5

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

slide-6
SLIDE 6

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" }

slide-7
SLIDE 7

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

slide-8
SLIDE 8

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

slide-9
SLIDE 9

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

slide-10
SLIDE 10

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

slide-11
SLIDE 11

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

slide-12
SLIDE 12

=> 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)

slide-13
SLIDE 13

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

slide-14
SLIDE 14

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

slide-15
SLIDE 15

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

slide-16
SLIDE 16

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

slide-17
SLIDE 17

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

slide-18
SLIDE 18

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

slide-19
SLIDE 19

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

slide-20
SLIDE 20

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

slide-21
SLIDE 21

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

slide-22
SLIDE 22

Zombie lab 1 Zombie lab 1

slide-23
SLIDE 23

Models LIFEBLOOD OF THE APP Models LIFEBLOOD of the app

LEVEL 2

slide-24
SLIDE 24

Model

The Lifeblood of the application

How your Rails application communicates with a data store

Models Models

slide-25
SLIDE 25

Views Controllers Routes Application Stack Models

Routing ROUTING

slide-26
SLIDE 26

?

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

slide-27
SLIDE 27

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

slide-28
SLIDE 28

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

slide-29
SLIDE 29

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!

slide-30
SLIDE 30

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

slide-31
SLIDE 31

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

slide-32
SLIDE 32

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

slide-33
SLIDE 33

Relationships Relationships

Because they always travel in packs

slide-34
SLIDE 34

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!

slide-35
SLIDE 35

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

slide-36
SLIDE 36

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

slide-37
SLIDE 37

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

slide-38
SLIDE 38

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

slide-39
SLIDE 39

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

slide-40
SLIDE 40

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

slide-41
SLIDE 41

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

slide-42
SLIDE 42

Zombie lab 2 Zombie lab 2

slide-43
SLIDE 43

VIEW VISUAL REPRESENTATION VIEW VISUAL REPRESENTATION

LEVEL 3

slide-44
SLIDE 44

View

VIEWs VIEWS The Visual Representation

User Interface. What we see.

  • f the application
slide-45
SLIDE 45

Controllers Models Routes Application Stack Views

VIEWs VIEWS

slide-46
SLIDE 46

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

slide-47
SLIDE 47

<% 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

slide-48
SLIDE 48

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 %>

slide-49
SLIDE 49

/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 %>

slide-50
SLIDE 50

<%= 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 %>

slide-51
SLIDE 51

/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>

slide-52
SLIDE 52

/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:

slide-53
SLIDE 53
  • 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”

slide-54
SLIDE 54
  • 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)

slide-55
SLIDE 55
  • 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)

slide-56
SLIDE 56
  • 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

slide-57
SLIDE 57

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

slide-58
SLIDE 58

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 %>

slide-59
SLIDE 59

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 %>

slide-60
SLIDE 60

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 %>

slide-61
SLIDE 61

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

slide-62
SLIDE 62

Empty Table?

Tweet.all <% .each do |tweet| %> ... <% end %>

VIEWs VIEWS

slide-63
SLIDE 63

Empty Table? VIEWs VIEWS

Tweet.all tweets <% tweets = ... <% end %> .each do |tweet| %>

slide-64
SLIDE 64

Empty Table?

Tweet.all <% <% tweets = %> ... <% end %> <em>No tweets found</em> <% end %> <% if tweets.size == 0 %>

VIEWs VIEWS

tweets.each do |tweet| %>

slide-65
SLIDE 65

<% 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

slide-66
SLIDE 66

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

slide-67
SLIDE 67

Zombie lab 3 Zombie lab 3

slide-68
SLIDE 68

Controllers BRAINS OF THE APP Controllers BRAINS OF THE APP

LEVEL 4

slide-69
SLIDE 69

Controller

Controllers CONTROLLERs The Brains of the application

The binding between the Model and the View

slide-70
SLIDE 70

Routes Application Stack Views Controllers Models

Routing ROUTING

slide-71
SLIDE 71

/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>

slide-72
SLIDE 72

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

slide-73
SLIDE 73

/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.

slide-74
SLIDE 74

...

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

slide-75
SLIDE 75

/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

slide-76
SLIDE 76

/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

slide-77
SLIDE 77

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!

slide-78
SLIDE 78

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

slide-79
SLIDE 79

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

slide-80
SLIDE 80

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

slide-81
SLIDE 81

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

slide-82
SLIDE 82

@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

slide-83
SLIDE 83

@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 !

slide-84
SLIDE 84

@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" }}

slide-85
SLIDE 85

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

slide-86
SLIDE 86

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

slide-87
SLIDE 87

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"?> ...

slide-88
SLIDE 88

/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

slide-89
SLIDE 89

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

slide-90
SLIDE 90

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

slide-91
SLIDE 91

Adding Some Authorization

EDIT EDIT

slide-92
SLIDE 92

DELETE DELETE

Adding Some Authorization

slide-93
SLIDE 93

DELETE DELETE

Adding Some Authorization

slide-94
SLIDE 94

) 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

slide-95
SLIDE 95

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

slide-96
SLIDE 96

/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>

slide-97
SLIDE 97

<!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>

slide-98
SLIDE 98

DELETE DELETE

Adding Some Authorization

slide-99
SLIDE 99

Adding Some Authorization

DELETE DELETE

slide-100
SLIDE 100

/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

slide-101
SLIDE 101

/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

slide-102
SLIDE 102

@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 ... ... ...

slide-103
SLIDE 103

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

slide-104
SLIDE 104

/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

slide-105
SLIDE 105

Adding Some Authorization

DELETE DELETE

slide-106
SLIDE 106

Zombie lab 4 Zombie lab 4

slide-107
SLIDE 107

Routing THROUGH RAILS Routing THROUGH RAILS

LEVEL 5

slide-108
SLIDE 108

Application Stack Views Controllers Models

Routing ROUTING

Routes

slide-109
SLIDE 109

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

slide-110
SLIDE 110

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

slide-111
SLIDE 111

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

slide-112
SLIDE 112

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

slide-113
SLIDE 113

Routing ROUTING

slide-114
SLIDE 114

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

slide-115
SLIDE 115

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

slide-116
SLIDE 116

Routing ROUTING

slide-117
SLIDE 117

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,

slide-118
SLIDE 118

Routing ROUTING

slide-119
SLIDE 119

get '/all' => redirect('/tweets') get '/google' => redirect('http://www.google.com/')

Redirect

http://localhost:3000/all http://localhost:3000/tweets redirect_to

Routing ROUTING

slide-120
SLIDE 120

root to: "tweets#index" <%= link_to "All Tweets", %> root_path Controller Action

Root Route

http://localhost:3000/ http://localhost:3000/tweets render

Routing ROUTING

slide-121
SLIDE 121

/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

slide-122
SLIDE 122

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

slide-123
SLIDE 123

Routing ROUTING

slide-124
SLIDE 124

Routing ROUTING

slide-125
SLIDE 125

/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

slide-126
SLIDE 126

Routing ROUTING

slide-127
SLIDE 127

Zombie lab 5 Zombie lab 5