Rails and routing - PowerPoint PPT Presentation

About This Presentation
Title:

Rails and routing

Description:

Rails and routing INFO 2310: Topics in Web Design and Programming Today s topics Model validation How can we make sure people enter stuff we want? – PowerPoint PPT presentation

Number of Views:57
Avg rating:3.0/5.0
Slides: 48
Provided by: PhoebeS8
Category:
Tags: rails | routing

less

Transcript and Presenter's Notes

Title: Rails and routing


1
Rails and routing
  • INFO 2310Topics in Web Design and Programming

2
Todays topics
  • Model validation
  • How can we make sure people enter stuff we want?
  • More about views and controllers
  • How does Rails decide what pages to show?
  • RESTful design
  • Embedded Ruby (erb)
  • How can we use Ruby in our HTML?

3
Model validation
4
  • Remember the CD catalog from INFO 230? You cant
    trust user input. So how do we deal with that in
    Rails?

5
Model validation
  • It turns out to be particularly simple in Rails.
  • Open up your Post model file (blog/app/models/post
    .rb). Add the line
  • validates_presence_of title, body
  • to the Post model.

6
Now try it
  • Fire up the webserver (ruby script/server from
    within your blog directory) and open up a browser
    (to http//localhost3000/posts).
  • Try entering/editing a post to have a blank title
    and/or body.

7
  • We can be slightly more sophisticated. Add
    another line to the Post model
  • validates_format_of title, with gt /\w\d/
  • Now try to see what happens

8
Lots of possibilities
  • validates_uniqueness_of
  • validates_numericality_of
  • validate_on_create methodname
  • validate_on_update methodname

9
Errors?
  • How are the errors getting displayed?
  • Each ActiveRecord object has a list of errors
    (e.g. _at_post.errors).
  • If you look at
  • blog/app/views/post/new.erb.html
  • blog/app/views/post/edit.erb.html
  • youll see a method that prints out the errors in
    this list
  • lt f.error_messages gt

10
More about views and controllers
11
From last time MVC
  • Recall from last time Rails uses the MVC
    (model-view-controller) pattern of software
    architecture
  • Model Objects holding data methods for
    operating on them.
  • Controllers Takes requests from user interface
    and decide which views to render.
  • Views The HTML Ruby that displays data from
    the model, gets input from the user.

12
From last time Models
  • In working on our blog, we created a model
    Posts with titles and bodies. We saw how we
    could manipulate data in the model.

13
This time Views and controllers
  • How does Rails take a URL and decide what to show
    you?

14
Routes.rb
  • Everything starts in the routes.rb file.
  • Open up blog/config/routes.rb.

15
Routes.rb
  • ActionControllerRoutingRoutes.draw do map
  • map.resources posts
  • map.connect 'controller/action/id'
    map.connect 'controller/action/id.format
  • end

16
Figuring a route
  • Each map.something command designed to take a
    URL, parse it, and direct it to the appropriate
    controller and method (action).
  • Route is decided on by first matching URL in
    routes.rb.
  • E.g. For our current mapping,
  • /users/show/1 would match
  • map.connect controller/action/id
  • with params controller gt users,
  • action gt show,
  • id gt 1
  • Would call on users_controller.rb and look for
    show method. (if we
  • had a users_controller). show can access
    paramsid.

17
Lets add some routes
  • First, lets add a route for the root, so we
    dont get the default Rails screen.
  • Add
  • map.root controller gt posts, action gt
    index
  • to routes.rb, just before the map.connect
    controller/action/index line.
  • Also delete blog/public/index.html (or rename
    it).
  • Try it!

18
Another route
  • Lets allow us to look up blog posts by date.
  • As the first routing line in routes.rb (after
    ActionController), add
  • map.connect posts/bydate/year/month/day,
  • controller gt posts,
  • action gt show_date,
  • requirements gt year gt /(1920)\d\d/,
  • month gt /01?\d/,
  • day gt /0-3?\d/ ,
  • month gt nil,
  • day gt nil
  • (Note for reasons well discuss in a minute,
    this isnt something we would really want to do
    given how posts current works).

19
Adding an action to a controller
  • Now open up blog/app/controller/posts_controller
    and add the following method at the bottom (just
    before the end).
  • def show_date
  • _at_posts Post.find(all)
  • _at_posts _at_posts.select x x.created_at.year
    paramsyear.to_i
  • _at_posts _at_posts.select x x.created_at.month
    paramsmonth.to_i if paramsmonth
  • _at_posts _at_posts.select x x.created_at.day
    paramsday.to_i if paramsday
  • render(action gt index)
  • end

20
Try it!
  • Try entering corresponding URLs into the browser.
  • http//localhost3000/posts/bydate/2008
  • http//localhost3000/posts/bydate/2008/09/05

21
What is happening?
22
Views
  • Each controller/action may have an associated
    layout/view.
  • The posts controller has an associated layout
    in app/layouts/posts.html.erb.
  • The views associated with the actions of the
    posts controllers are in app/views/post/
  • (ones for index, edit, new, and show).

23
Views
  • When an action is called, the corresponding view
    is rendered (unless another render or a
    redirect is called).
  • The view is output within a layout
    posts.html.erb in this case.
  • If the corresponding layout does not exist,
    application.html.erb is used instead (useful if
    you want one layout for many controllers).

24
In our case
  • show_date asks to render index. So
    app/views/posts/index.html.erb is rendered in the
    context of the layout app/layouts/posts.html.erb
    (with the _at_posts variable set as given in
    show_date).

25
Posts layout
  • !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
    Transitional//EN" "http//www.w3.org/TR/xhtm
    l1/DTD/xhtml1-transitional.dtd"gt
  • lthtml xmlns"http//www.w3.org/1999/xhtml"
    xmllang"en" lang"en"gt
  • ltheadgt
  • ltmeta http-equiv"content-type"
    content"text/htmlcharsetUTF-8" /gt
  • lttitlegtMy Blog lt _at_title gtlt/titlegt
  • lt stylesheet_link_tag 'scaffold' gt
  • lt/headgt
  • ltbodygt
  • ltp style"color green"gtlt flashnotice
    gtlt/pgt
  • lt yield gt
  • lt/bodygt
  • lt/htmlgt

26
Useful tricks
  • Since layouts are evaluated after the view, they
    can use variables set in the view.
  • Try this
  • in app/views/posts/show.html.erb add the line
  • lt _at_title " " _at_post.title gt
  • somewhere.

27
  • Then in app/layouts/post.html.erb, change the
    lttitlegt tag to
  • lttitlegtMy Blog lth _at_title gtlt/titlegt
  • Try it!

28
REST
29
  • But in fact, the only route related to posts in
    routes.rb was
  • map.resources posts
  • How does this manage to do everything that it
    does?

30
REST
  • REST Representational State Transfer
  • Basic ideas
  • All interactions between client and server
    handled by a small number of verbs applied to a
    larger number of well-defined nouns or
    resources. Resources can have multiple
    representations. Long-term state maintained by
    the resources.
  • In our case
  • verbs are HTTP methods (GET, POST, PUT, DELETE)
  • nouns are URLs (e.g. /posts/1).
  • representations are formats (HTML, XML, RSS,
    JSON, etc.)

31
REST cont.
  • Why is this useful?
  • Useful for networking components to know when
    they can cache responses.
  • Rather than using the URL to indicate the action
    (e.g. /posts/get_article/1), have standard
    action (HTTP GET) applied to a resource (e.g.
    posts/1).
  • Generalizes to other resources (e.g. we know what
    happes if we do an HTTP GET for /users/1).
  • But at some level, I dont get the fuss.

32
REST in Rails
  • Rails is set up for RESTful applications.
  • Can see the routes created by map.resources
    posts by typing rake routes.

33
HTTP method URL Action
GET /posts index Lists all posts
GET /posts/id show Show post id
GET /posts/id/edit edit Edit post id
GET /posts/new new Make new post (form input)
PUT /posts/id update Update post id using info from request
DELETE /posts/id destroy Delete post id
POST /posts create Make new post using info from request
34
posts_controller.rb
  • We can see the actions in the controller
  • def index
  • _at_posts Post.find(all)
  • respond_to do format
  • format.html index.html.erb
  • format.xml render xml gt _at_posts
  • end
  • end
  • def show
  • _at_post Post.find(paramsid)
  • respond_to do format
  • format.html show.html.erb
  • format.xml render xml gt _at_post
  • end
  • end

35
XML
  • Note that there is built-in support for an XML
    representation try browsing
  • http//localhost3000/posts.xml.

36
ERB
  • Now some of the .erb files make more sense.
    index.html.erb
  • lt for post in _at_posts gt
  • lttrgt
  • lttdgtlth post.title gtlt/tdgt
  • lttdgtlth post.body gtlt/tdgt
  • lttdgtlt link_to 'Show', post gtlt/tdgt
  • lttdgtlt link_to 'Edit', edit_post_path(post)
    gtlt/tdgt
  • lttdgtlt link_to 'Destroy', post, confirm gt 'Are
    you sure?', method gt delete gtlt/tdgt lt/trgt
  • lt end gtlt/tablegt
  • ltbr /gt
  • lt link_to 'New post', new_post_path gt

37
ERB
  • Any Ruby inside lt gt gets executed.
  • E.g. lt for post in _at_posts gt
  • Any Ruby inside lt gt gets executed, the
    result turned into a string, and displayed.
  • E.g. lt h post.title gt
  • h is a method that displays special characters
    correctly in HTML like PHP htmlentities().

38
ERB
  • link_to a method for creating links.
  • edit_post_path(post), new_post_path methods
    automatically created to return URLs to the
    edit and new actions of the posts_controller.
  • Note in Destroy link we have to specify the
    HTTP method delete.
  • lt link_to 'Destroy', post, confirm gt 'Are you
    sure?', method gt delete gt

39
Partials
40
Partials
  • With partials, we can create partial views
    that can be rendered inside other views. A bit
    like a PHP include.
  • The file name of a partial is prefixed with an
    _.

41
Lets try one
  • Notice that app/views/posts/new.html.erb and
    app/views/posts/edit.html.erb are almost
    identical.
  • Lets capture the common part in a partial.

42
_form.html.erb
  • Create a new file app/views/posts/_form.html.erb
    .
  • Copy the following from app/views/posts/edit.html
    .erb into _form
  • lt form_for(_at_post) do f gt
  • lt f.error_messages gt
  • ltpgt
  • lt f.label title gtltbr /gt
  • lt f.text_field title gt
  • lt/pgt
  • ltpgt
  • lt f.label body gtltbr /gt
  • lt f.text_area body gt
  • lt/pgt
  • ltpgt
  • lt f.submit "Create" gt
  • lt/pgt
  • lt end gt

43
  • Now edit blog/app/views/posts/edit.html.erb
  • by replacing the removed code with
  • lt render partial gt form gt
  • and the same for
  • blog/app/views/posts/new.html.erb.
  • Now try the blog

44
Problem
  • The submit button says Create for both entering
    a new entry and editing an old one.
  • We can solve this by passing in local variables
    to each

45
Edits
  • _form.html.erb change f.submit line to
  • lt f.submit action gt
  • new.html.erb change render line to
  • lt render partial gt 'form', locals gt
    action gt 'Create' gt
  • edit.html.erb change render line to
  • lt render partial gt 'form', locals gt
    action gt 'Update' gt

46
Review
47
Reminders
Write a Comment
User Comments (0)
About PowerShow.com