Rails Routing And Rendering

  • 804 views
Uploaded on

This was the ninth speech of a three day Rails training I gave in Tulsa, OK in the spring 2010.

This was the ninth speech of a three day Rails training I gave in Tulsa, OK in the spring 2010.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
804
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
29
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide






































































































































Transcript

  • 1. Routing and Rendering An under the hood look at how Rails receives requests and writes responses
  • 2. The Router How Rails decides where to send each request
  • 3. The Router’s Job
  • 4. The Router’s Job Each time a request comes in, Rails needs to send it to some action in some controller
  • 5. The Router’s Job Each time a request comes in, Rails needs to send it to some action in some controller That’s what the router does
  • 6. The Router’s Job Each time a request comes in, Rails needs to send it to some action in some controller That’s what the router does The router primarily maps URL’s to actions
  • 7. The Router’s Job Each time a request comes in, Rails needs to send it to some action in some controller That’s what the router does The router primarily maps URL’s to actions It may also route based on HTTP verbs
  • 8. The Router’s Job Each time a request comes in, Rails needs to send it to some action in some controller That’s what the router does The router primarily maps URL’s to actions It may also route based on HTTP verbs It can be made to route on additional criteria, like host name
  • 9. config/routes.rb The routing file for your application probably looks something like this by now
  • 10. ActionController::Routing::Routes.draw do |map| map.resources :prompts map.resources :submissions map.resources :users map.resource :user_session map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end config/routes.rb The routing file for your application probably looks something like this by now
  • 11. ActionController::Routing::Routes.draw do |map| map.resources :prompts map.resources :submissions map.resources :users map.resource :user_session map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end config/routes.rb The routing file for your application probably looks something like this by now
  • 12. ActionController::Routing::Routes.draw do |map| map.resources :prompts map.resources :submissions map.resources :users map.resource :user_session map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end config/routes.rb The routing file for your application probably looks something like this by now
  • 13. ActionController::Routing::Routes.draw do |map| map.resources :prompts map.resources :submissions map.resources :users map.resource :user_session map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end config/routes.rb The routing file for your application probably looks something like this by now
  • 14. ActionController::Routing::Routes.draw do |map| map.resources :prompts map.resources :submissions map.resources :users map.resource :user_session map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end config/routes.rb The routing file for your application probably looks something like this by now
  • 15. The Default Routes
  • 16. The Default Routes map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format'
  • 17. The Default Routes map.connect ':controller/:action/:id' These rules support an map.connect ':controller/:action/:id.:format' older style of Rail routing /prompts /prompts/new /prompts/create /prompts/show/1 /prompts/edit/1 /prompts/update/1 /prompts/destroy/1
  • 18. The Default Routes map.connect ':controller/:action/:id' These rules support an map.connect ':controller/:action/:id.:format' older style of Rail routing It has fallen out of /prompts /prompts/new fashion /prompts/create /prompts/show/1 /prompts/edit/1 /prompts/update/1 /prompts/destroy/1
  • 19. The Default Routes map.connect ':controller/:action/:id' These rules support an map.connect ':controller/:action/:id.:format' older style of Rail routing It has fallen out of /prompts /prompts/new fashion /prompts/create /prompts/show/1 Some people now /prompts/edit/1 /prompts/update/1 remove these rules /prompts/destroy/1
  • 20. Route Priority
  • 21. Route Priority Routes are matches matched in top to bottom order as they appear in the routes file
  • 22. Route Priority Routes are matches matched in top to bottom order as they appear in the routes file The first route to match an incoming request wins
  • 23. Route Priority Routes are matches matched in top to bottom order as they appear in the routes file The first route to match an incoming request wins Lower routes may never fire, if a higher route hides them by matching requests
  • 24. Route Priority Routes are matches matched in top to bottom order as they appear in the routes file The first route to match an incoming request wins Lower routes may never fire, if a higher route hides them by matching requests This is why the default routes are at the bottom of the file: they are the last resort
  • 25. Resource Routing
  • 26. Resource Routing map.resources :prompts map.resources :submissions map.resources :users
  • 27. Resource Routing This is the modern map.resources :prompts Rails routing style map.resources :submissions map.resources :users GET /prompts GET /prompts/new POST /prompts GET /prompts/1 GET /prompts/1/edit PUT /prompts/1 DELETE /prompts/1
  • 28. Resource Routing This is the modern map.resources :prompts Rails routing style map.resources :submissions map.resources :users You can add non- standard actions GET /prompts GET /prompts/new POST /prompts GET /prompts/1 GET /prompts/1/edit PUT /prompts/1 DELETE /prompts/1
  • 29. Resource Routing This is the modern map.resources :prompts Rails routing style map.resources :submissions map.resources :users You can add non- standard actions GET /prompts It routes based on GET /prompts/new HTTP verbs POST /prompts GET /prompts/1 GET /prompts/1/edit PUT /prompts/1 DELETE /prompts/1
  • 30. Resource Routing This is the modern map.resources :prompts Rails routing style map.resources :submissions map.resources :users You can add non- standard actions GET /prompts It routes based on GET /prompts/new HTTP verbs POST /prompts GET /prompts/1 GET /prompts/1/edit You get named path/url PUT /prompts/1 DELETE /prompts/1 methods for free
  • 31. What are HTTP Verbs?
  • 32. What are HTTP Verbs? The Web’s transport protocol understands a powerful language of verbs and objects
  • 33. What are HTTP Verbs? The Web’s transport protocol understands a powerful language of verbs and objects Browser’s are generally dumb and do not
  • 34. What are HTTP Verbs? The Web’s transport protocol understands a powerful language of verbs and objects Browser’s are generally dumb and do not They use only GET (links) and POST (forms)
  • 35. What are HTTP Verbs? The Web’s transport protocol understands a powerful language of verbs and objects Browser’s are generally dumb and do not They use only GET (links) and POST (forms) Rails fakes it with browsers using hidden parameters
  • 36. What are HTTP Verbs? The Web’s transport protocol understands a powerful language of verbs and objects Browser’s are generally dumb and do not They use only GET (links) and POST (forms) Rails fakes it with browsers using hidden parameters It also supports the real verbs from smart agents
  • 37. What are HTTP Verbs? The Web’s transport protocol understands a powerful language of verbs and objects Browser’s are generally dumb and do not They use only GET (links) and POST (forms) Rails fakes it with browsers using hidden parameters It also supports the real verbs from smart agents This is very nice when building API’s
  • 38. Resource Path Methods
  • 39. Resource Path Methods new_user_path()
  • 40. Resource Path Methods new_user_path() GET for new
  • 41. Resource Path Methods new_user_path() GET for new edit_user_path()
  • 42. Resource Path Methods new_user_path() GET for new edit_user_path() GET for edit
  • 43. Resource Path Methods new_user_path() GET for new edit_user_path() GET for edit users_path()
  • 44. Resource Path Methods new_user_path() GET for new edit_user_path() GET for edit users_path() GET for index
  • 45. Resource Path Methods new_user_path() GET for new edit_user_path() GET for edit users_path() GET for index POST for create
  • 46. Resource Path Methods new_user_path() user_path(user) GET for new edit_user_path() GET for edit users_path() GET for index POST for create
  • 47. Resource Path Methods new_user_path() user_path(user) GET for new GET for show edit_user_path() GET for edit users_path() GET for index POST for create
  • 48. Resource Path Methods new_user_path() user_path(user) GET for new GET for show edit_user_path() PUT for update GET for edit users_path() GET for index POST for create
  • 49. Resource Path Methods new_user_path() user_path(user) GET for new GET for show edit_user_path() PUT for update GET for edit DELETE for destroy users_path() GET for index POST for create
  • 50. Singleton Resources
  • 51. Singleton Resources map.resource :user_session
  • 52. Singleton Resources A special case of map.resource :user_session resource routing GET /user_session/new POST /user_session GET /user_session GET /user_session/edit PUT /user_session DELETE /user_session new_user_session_path edit_user_session_path user_session_path
  • 53. Singleton Resources A special case of map.resource :user_session resource routing GET /user_session/new For unique to the user POST /user_session GET /user_session resources GET /user_session/edit PUT /user_session DELETE /user_session new_user_session_path edit_user_session_path user_session_path
  • 54. Singleton Resources A special case of map.resource :user_session resource routing GET /user_session/new For unique to the user POST /user_session GET /user_session resources GET /user_session/edit PUT /user_session DELETE /user_session Logins new_user_session_path edit_user_session_path user_session_path
  • 55. Singleton Resources A special case of map.resource :user_session resource routing GET /user_session/new For unique to the user POST /user_session GET /user_session resources GET /user_session/edit PUT /user_session DELETE /user_session Logins The user’s account new_user_session_path edit_user_session_path user_session_path
  • 56. Singleton Resources A special case of map.resource :user_session resource routing GET /user_session/new For unique to the user POST /user_session GET /user_session resources GET /user_session/edit PUT /user_session DELETE /user_session Logins The user’s account new_user_session_path edit_user_session_path user_session_path …
  • 57. Named Routes
  • 58. Named Routes map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create"
  • 59. Named Routes Best for special cases and map.login "login", :controller => "user_sessions", pretty URL’s :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create"
  • 60. Named Routes Best for special cases and map.login "login", :controller => "user_sessions", pretty URL’s :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create"
  • 61. Named Routes Best for special cases and map.login "login", :controller => "user_sessions", pretty URL’s :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create"
  • 62. Named Routes Best for special cases and map.login "login", :controller => "user_sessions", pretty URL’s :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" login_path is preferred to map.activate "activate/:token", new_user_session_path :controller => "activations", :action => "create" /login /logout /activate/5HkeFFwiInKfjA4x25q9
  • 63. Named Routes Best for special cases and map.login "login", :controller => "user_sessions", pretty URL’s :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" login_path is preferred to map.activate "activate/:token", new_user_session_path :controller => "activations", :action => "create" Email links must GET /login /logout /activate/5HkeFFwiInKfjA4x25q9
  • 64. Named Routes Best for special cases and map.login "login", :controller => "user_sessions", pretty URL’s :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" login_path is preferred to map.activate "activate/:token", new_user_session_path :controller => "activations", :action => "create" Email links must GET /login /logout You can choose to create the path method /activate/5HkeFFwiInKfjA4x25q9
  • 65. Example: A Sign-up Route
  • 66. Example: A Sign-up Route We could add a sign- up route map.signup "signup", :controller => "users", :action => "new"
  • 67. Example: A Sign-up Route We could add a sign- up route This would allow us to use signup_path map.signup "signup", instead of :controller => "users", :action => "new" new_user_path
  • 68. Example: A Sign-up Route We could add a sign- up route This would allow us to use signup_path map.signup "signup", instead of :controller => "users", :action => "new" new_user_path That would route to /signup instead of /users/new
  • 69. The Root Path
  • 70. The Root Path map.root :controller => "prompts", :action => "index"
  • 71. The Root Path Set this path to the landing page map.root :controller => "prompts", :action => "index" http://localhost:3000/ http://myapp.com/
  • 72. The Root Path Set this path to the landing page map.root :controller => "prompts", :action => "index" You have to remove public/index.html to get it to work http://localhost:3000/ http://myapp.com/
  • 73. The Root Path Set this path to the landing page map.root :controller => "prompts", :action => "index" You have to remove public/index.html to get it to work http://localhost:3000/ http://myapp.com/ This does create a root_path() method
  • 74. rake routes This command shows all of the routes currently set for your application
  • 75. prompts GET /prompts(.:format) {:action=>"index", :controller=>"prompts"} POST /prompts(.:format) {:action=>"create", :controller=>"prompts"} new_prompt GET /prompts/new(.:format) {:action=>"new", :controller=>"prompts"} edit_prompt GET /prompts/:id/edit(.:format) {:action=>"edit", :controller=>"prompts"} prompt GET /prompts/:id(.:format) {:action=>"show", :controller=>"prompts"} PUT /prompts/:id(.:format) {:action=>"update", :controller=>"prompts"} DELETE /prompts/:id(.:format) {:action=>"destroy", :controller=>"prompts"} submissions GET /submissions(.:format) {:action=>"index", :controller=>"submissions"} POST /submissions(.:format) {:action=>"create", :controller=>"submissions"} new_submission GET /submissions/new(.:format) {:action=>"new", :controller=>"submissions"} edit_submission GET /submissions/:id/edit(.:format) {:action=>"edit", :controller=>"submissions"} submission GET /submissions/:id(.:format) {:action=>"show", :controller=>"submissions"} PUT /submissions/:id(.:format) {:action=>"update", :controller=>"submissions"} DELETE /submissions/:id(.:format) {:action=>"destroy", :controller=>"submissions"} users GET /users(.:format) {:action=>"index", :controller=>"users"} POST /users(.:format) {:action=>"create", :controller=>"users"} new_user GET /users/new(.:format) {:action=>"new", :controller=>"users"} edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"} user GET /users/:id(.:format) {:action=>"show", :controller=>"users"} PUT /users/:id(.:format) {:action=>"update", :controller=>"users"} DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"} new_user_session GET /user_session/new(.:format) {:action=>"new", :controller=>"user_sessions"} edit_user_session GET /user_session/edit(.:format) {:action=>"edit", :controller=>"user_sessions"} user_session GET /user_session(.:format) {:action=>"show", :controller=>"user_sessions"} PUT /user_session(.:format) {:action=>"update", :controller=>"user_sessions"} DELETE /user_session(.:format) {:action=>"destroy", :controller=>"user_sessions"} POST /user_session(.:format) {:action=>"create", :controller=>"user_sessions"} login /login {:action=>"new", :controller=>"user_sessions"} logout /logout {:action=>"destroy", :controller=>"user_sessions"} rake routes This command shows all of the routes currently set for your application
  • 76. There’s More to the Router!
  • 77. There’s More to the Router! You can add “collection” or “member” actions to the seven standard resource routes
  • 78. There’s More to the Router! You can add “collection” or “member” actions to the seven standard resource routes You can nest resources
  • 79. There’s More to the Router! You can add “collection” or “member” actions to the seven standard resource routes You can nest resources Creating routes like: /prompts/1/submissions/1
  • 80. There’s More to the Router! You can add “collection” or “member” actions to the seven standard resource routes You can nest resources Creating routes like: /prompts/1/submissions/1 You can prefix routes
  • 81. There’s More to the Router! You can add “collection” or “member” actions to the seven standard resource routes You can nest resources Creating routes like: /prompts/1/submissions/1 You can prefix routes Creating routes like: /admin/users/1
  • 82. There’s More to the Router! You can add “collection” or “member” actions to the seven standard resource routes You can nest resources Creating routes like: /prompts/1/submissions/1 You can prefix routes Creating routes like: /admin/users/1 …
  • 83. Rendering a Response The different ways you can respond to a request in Rails
  • 84. What is Rendered?
  • 85. What is Rendered? If an action doesn’t call redirect_to() at some point, some kind of render() generally takes place
  • 86. What is Rendered? If an action doesn’t call redirect_to() at some point, some kind of render() generally takes place If render() is called, Rails will try to satisfy that request
  • 87. What is Rendered? If an action doesn’t call redirect_to() at some point, some kind of render() generally takes place If render() is called, Rails will try to satisfy that request Otherwise a default render happens
  • 88. What is Rendered? If an action doesn’t call redirect_to() at some point, some kind of render() generally takes place If render() is called, Rails will try to satisfy that request Otherwise a default render happens Rails will hunt for a view named for the current action
  • 89. What is Rendered? If an action doesn’t call redirect_to() at some point, some kind of render() generally takes place If render() is called, Rails will try to satisfy that request Otherwise a default render happens Rails will hunt for a view named for the current action Rails will try to honor the requested format
  • 90. The Render Format
  • 91. The Render Format Both resource routes and the default routes include an optional :format parameter
  • 92. The Render Format Both resource routes and the default routes include an optional :format parameter This allows you to visit a URL like: /users/1.json
  • 93. The Render Format Both resource routes and the default routes include an optional :format parameter This allows you to visit a URL like: /users/1.json The requested :format there is JSON instead of the default HTML
  • 94. The Render Format Both resource routes and the default routes include an optional :format parameter This allows you to visit a URL like: /users/1.json The requested :format there is JSON instead of the default HTML Rails also honors the HTTP Accept header
  • 95. Responding to Formats
  • 96. Responding to Formats def index @articles = Article.all respond_to do |format| format.html # take the default action format.xml do render :xml => @articles.to_xml end format.json do render :json => @articles.to_json end end end
  • 97. Responding to Formats You can use respond_to to set def index @articles = Article.all explicit responses for respond_to do |format| format.html # take the default action each format format.xml do render :xml => @articles.to_xml end format.json do render :json => @articles.to_json end end end
  • 98. Responding to Formats You can use respond_to to set def index @articles = Article.all explicit responses for respond_to do |format| format.html # take the default action each format format.xml do render :xml => @articles.to_xml end format.json do render :json => @articles.to_json end end end
  • 99. Responding to Formats You can use respond_to to set def index @articles = Article.all explicit responses for respond_to do |format| format.html # take the default action each format format.xml do render :xml => @articles.to_xml end format.json do ActiveRecord knows render :json => @articles.to_json end how to write XML and end end JSON
  • 100. The Accept Header Note how the responses changed as I modified the header but hit the URL
  • 101. $ curl http://localhost:3000/articles <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> … $ curl -H 'Accept: application/xml' http://localhost:3000/articles <?xml version="1.0" encoding="UTF-8"?> <articles type="array"> <article> … $ curl -H 'Accept: application/json' http://localhost:3000/articles [{"article":{"updated_at":"2010-03-05T16:08:33Z",…}}] The Accept Header Note how the responses changed as I modified the header but hit the URL
  • 102. $ curl http://localhost:3000/articles <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> … $ curl -H 'Accept: application/xml' http://localhost:3000/articles <?xml version="1.0" encoding="UTF-8"?> <articles type="array"> <article> … $ curl -H 'Accept: application/json' http://localhost:3000/articles [{"article":{"updated_at":"2010-03-05T16:08:33Z",…}}] The Accept Header Note how the responses changed as I modified the header but hit the URL
  • 103. Atom Feeds
  • 104. Atom Feeds A very popular use of response formats is to create Atom feeds
  • 105. Atom Feeds A very popular use of response formats is to create Atom feeds Rails adds a little syntactic sugar for this with some helper methods and the use of the Builder library
  • 106. Atom Feeds A very popular use of response formats is to create Atom feeds Rails adds a little syntactic sugar for this with some helper methods and the use of the Builder library Builder allows you to generate XML with a Ruby DSL
  • 107. Rendering Atom I’ve added the format and set an ordering that will help us set good Atom dates
  • 108. def index @articles = Article.all(:order => "created_at DESC") respond_to do |format| format.html # take the default action format.atom # take the default action format.xml do render :xml => @articles.to_xml end format.json do render :json => @articles.to_json end end end Rendering Atom I’ve added the format and set an ordering that will help us set good Atom dates
  • 109. def index @articles = Article.all(:order => "created_at DESC") respond_to do |format| format.html # take the default action format.atom # take the default action format.xml do render :xml => @articles.to_xml end format.json do render :json => @articles.to_json end end end Rendering Atom I’ve added the format and set an ordering that will help us set good Atom dates
  • 110. def index @articles = Article.all(:order => "created_at DESC") respond_to do |format| format.html # take the default action format.atom # take the default action format.xml do render :xml => @articles.to_xml end format.json do render :json => @articles.to_json end end end Rendering Atom I’ve added the format and set an ordering that will help us set good Atom dates
  • 111. XML With Builder Builder generates XML (or Atom) from the nested structure of Ruby blocks
  • 112. atom_feed do |feed| feed.title("My Blog Articles") feed.updated(@articles.first.created_at) @articles.each do |article| feed.entry(article) do |entry| entry.title(article.title) entry.content(article.body, :type => 'html') entry.author do |author| author.name("JEG2") # article.user.name end end end end XML With Builder Builder generates XML (or Atom) from the nested structure of Ruby blocks
  • 113. atom_feed do |feed| feed.title("My Blog Articles") feed.updated(@articles.first.created_at) @articles.each do |article| feed.entry(article) do |entry| entry.title(article.title) entry.content(article.body, :type => 'html') entry.author do |author| author.name("JEG2") # article.user.name end end end end XML With Builder Builder generates XML (or Atom) from the nested structure of Ruby blocks
  • 114. atom_feed do |feed| feed.title("My Blog Articles") feed.updated(@articles.first.created_at) @articles.each do |article| feed.entry(article) do |entry| entry.title(article.title) entry.content(article.body, :type => 'html') entry.author do |author| author.name("JEG2") # article.user.name end end end end XML With Builder Builder generates XML (or Atom) from the nested structure of Ruby blocks
  • 115. atom_feed do |feed| feed.title("My Blog Articles") feed.updated(@articles.first.created_at) @articles.each do |article| feed.entry(article) do |entry| entry.title(article.title) entry.content(article.body, :type => 'html') entry.author do |author| author.name("JEG2") # article.user.name end end end end XML With Builder Builder generates XML (or Atom) from the nested structure of Ruby blocks
  • 116. atom_feed do |feed| feed.title("My Blog Articles") feed.updated(@articles.first.created_at) @articles.each do |article| feed.entry(article) do |entry| entry.title(article.title) entry.content(article.body, :type => 'html') entry.author do |author| author.name("JEG2") # article.user.name end end end end XML With Builder Builder generates XML (or Atom) from the nested structure of Ruby blocks
  • 117. An Atom Feed Rails does a lot of work for us: adding ID’s and links, converting dates, …
  • 118. $ curl -H 'Accept: application/atom+xml' http://localhost:3000/articles <?xml version="1.0" encoding="UTF-8"?> <feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"> <id>tag:localhost,2005:/articles</id> <link type="text/html" rel="alternate" href="http://localhost:3000"/> <link type="application/atom+xml" rel="self" href="http://localhost:3000/articles"/> <title>My Blog Articles</title> <updated>2010-03-05T16:08:33Z</updated> <entry> <id>tag:localhost,2005:Article/1</id> <published>2010-03-05T16:08:33Z</published> <updated>2010-03-05T16:08:33Z</updated> <link type="text/html" rel="alternate" href="http://localhost:3000/articles/1"/> <title>The CRUD</title> <content type="html">Lorem ipsum…</content> <author> <name>JEG2</name> </author> </entry> </feed> An Atom Feed Rails does a lot of work for us: adding ID’s and links, converting dates, …
  • 119. $ curl -H 'Accept: application/atom+xml' http://localhost:3000/articles <?xml version="1.0" encoding="UTF-8"?> <feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"> <id>tag:localhost,2005:/articles</id> <link type="text/html" rel="alternate" href="http://localhost:3000"/> <link type="application/atom+xml" rel="self" href="http://localhost:3000/articles"/> <title>My Blog Articles</title> <updated>2010-03-05T16:08:33Z</updated> <entry> <id>tag:localhost,2005:Article/1</id> <published>2010-03-05T16:08:33Z</published> <updated>2010-03-05T16:08:33Z</updated> <link type="text/html" rel="alternate" href="http://localhost:3000/articles/1"/> <title>The CRUD</title> <content type="html">Lorem ipsum…</content> <author> <name>JEG2</name> </author> </entry> </feed> An Atom Feed Rails does a lot of work for us: adding ID’s and links, converting dates, …
  • 120. $ curl -H 'Accept: application/atom+xml' http://localhost:3000/articles <?xml version="1.0" encoding="UTF-8"?> <feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"> <id>tag:localhost,2005:/articles</id> <link type="text/html" rel="alternate" href="http://localhost:3000"/> <link type="application/atom+xml" rel="self" href="http://localhost:3000/articles"/> <title>My Blog Articles</title> <updated>2010-03-05T16:08:33Z</updated> <entry> <id>tag:localhost,2005:Article/1</id> <published>2010-03-05T16:08:33Z</published> <updated>2010-03-05T16:08:33Z</updated> <link type="text/html" rel="alternate" href="http://localhost:3000/articles/1"/> <title>The CRUD</title> <content type="html">Lorem ipsum…</content> <author> <name>JEG2</name> </author> </entry> </feed> An Atom Feed Rails does a lot of work for us: adding ID’s and links, converting dates, …
  • 121. $ curl -H 'Accept: application/atom+xml' http://localhost:3000/articles <?xml version="1.0" encoding="UTF-8"?> <feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"> <id>tag:localhost,2005:/articles</id> <link type="text/html" rel="alternate" href="http://localhost:3000"/> <link type="application/atom+xml" rel="self" href="http://localhost:3000/articles"/> <title>My Blog Articles</title> <updated>2010-03-05T16:08:33Z</updated> <entry> <id>tag:localhost,2005:Article/1</id> <published>2010-03-05T16:08:33Z</published> <updated>2010-03-05T16:08:33Z</updated> <link type="text/html" rel="alternate" href="http://localhost:3000/articles/1"/> <title>The CRUD</title> <content type="html">Lorem ipsum…</content> <author> <name>JEG2</name> </author> </entry> </feed> An Atom Feed Rails does a lot of work for us: adding ID’s and links, converting dates, …
  • 122. Support Head Content I have inserted a placeholder that will allow pages to insert content into the document head
  • 123. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title> <%= ["My Blog", yield(:page_title)].compact.join(" : ") %> </title> <%= yield :head %> </head> <body> <%= yield %> </body> </html> Support Head Content I have inserted a placeholder that will allow pages to insert content into the document head
  • 124. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title> <%= ["My Blog", yield(:page_title)].compact.join(" : ") %> </title> <%= yield :head %> </head> <body> <%= yield %> </body> </html> Support Head Content I have inserted a placeholder that will allow pages to insert content into the document head
  • 125. An Auto Discovery Link Now we can have the HTML page inform our browser of the existence of the feed
  • 126. <% content_for :head do %> <%= auto_discovery_link_tag :atom, :format => :atom %> <% end %> <h1>Articles</h1> <ul> <%= render @articles %> </ul> An Auto Discovery Link Now we can have the HTML page inform our browser of the existence of the feed
  • 127. <% content_for :head do %> <%= auto_discovery_link_tag :atom, :format => :atom %> <% end %> <h1>Articles</h1> <ul> <%= render @articles %> </ul> An Auto Discovery Link Now we can have the HTML page inform our browser of the existence of the feed
  • 128. Discovering the Feed My browser now recognizes the feed and allows me to view it
  • 129. Discovering the Feed My browser now recognizes the feed and allows me to view it
  • 130. Discovering the Feed My browser now recognizes the feed and allows me to view it
  • 131. Discovering the Feed My browser now recognizes the feed and allows me to view it
  • 132. Other Types of Renders
  • 133. Other Types of Renders Rails can respond to any Mime Type format
  • 134. Other Types of Renders Rails can respond to any Mime Type format You can also choose to send a file back to the browser
  • 135. Other Types of Renders Rails can respond to any Mime Type format You can also choose to send a file back to the browser Or generate data programmatically that is passed as a file
  • 136. Other Types of Renders Rails can respond to any Mime Type format You can also choose to send a file back to the browser Or generate data programmatically that is passed as a file I use this to stream CSV back to browsers
  • 137. Questions?
  • 138. Adding Atom Feeds Lab Your book has instructions for how to add a couple of feeds to your application