The document discusses how Rails routes incoming requests. The router maps URLs to controller actions. It does this by matching routes in order from top to bottom. Resource routing is the modern style and maps HTTP verbs to actions. Named routes can be used for special cases or pretty URLs. Singleton resources handle unique per user resources like sessions. The router ensures each request is routed to the proper controller and action.
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
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
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
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
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
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
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
…
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
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
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
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
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
…
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
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
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
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
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
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
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