13.1 Iteration H1: Email Notifications 12.3 Iteration G3: Pagination
Add the xml format to the controller
edit app/controllers/products_controller.rb
def who_bought
@product = Product.find(params[:id])
respond_to do |format|
format.xml { render :xml => @product }
format.atom
end
end
Fetch the XML, see that there are no orders there
curl --silent --user dave:secret http://localhost:3000/products/2/who_bought.atom
<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
<id>tag:localhost,2005:/products/2/who_bought</id>
<link rel="alternate" type="text/html" href="http://localhost:3000"/>
<link rel="self" type="application/atom+xml" href="http://localhost:3000/products/2/who_bought.atom"/>
<title>Who bought CoffeeScript</title>
<updated>2012-10-11T07:15:28Z</updated>
<entry>
<id>tag:localhost,2005:Order/1</id>
<published>2012-10-11T07:15:28Z</published>
<updated>2012-10-11T07:15:28Z</updated>
<link rel="alternate" type="text/html" href="http://localhost:3000/orders/1"/>
<title>Order 1</title>
<summary type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<p>Shipped to 123 Main St</p>
<table>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Total Price</th>
</tr>
<tr>
<td>CoffeeScript</td>
<td>1</td>
<td>$36.00</td>
</tr>
<tr>
<th colspan="2">total</th>
<th>$36.00</th>
</tr>
</table>
<p>Paid by Check</p>
</div>
</summary>
<author>
<name>Dave Thomas</name>
<email>customer@example.com</email>
</author>
</entry>
</feed>
Include "orders" in the response
edit app/controllers/products_controller.rb
def who_bought
@product = Product.find(params[:id])
respond_to do |format|
format.xml { render :xml => @product.to_xml(:include => :orders) }
format.atom
end
end
Fetch the xml, see that the orders are included
curl --silent --user dave:secret http://localhost:3000/products/2/who_bought.xml
<?xml version="1.0" encoding="UTF-8"?>
<product>
<price type="decimal">36.0</price>
<created-at type="datetime">2012-10-11T07:11:35Z</created-at>
<title>CoffeeScript</title>
<image-url>cs.jpg</image-url>
<updated-at type="datetime">2012-10-11T07:11:35Z</updated-at>
<id type="integer">2</id>
<description><p>
CoffeeScript is JavaScript done right. It provides all of JavaScript's
functionality wrapped in a cleaner, more succinct syntax. In the first
book on this exciting new language, CoffeeScript guru Trevor Burnham
shows you how to hold onto all the power and flexibility of JavaScript
while writing clearer, cleaner, and safer code.
</p></description>
<orders type="array">
<order>
<name>Dave Thomas</name>
<address>123 Main St</address>
<created-at type="datetime">2012-10-11T07:15:28Z</created-at>
<updated-at type="datetime">2012-10-11T07:15:28Z</updated-at>
<pay-type>Check</pay-type>
<id type="integer">1</id>
<email>customer@example.com</email>
</order>
</orders>
</product>
Define an HTML view
edit app/views/products/who_bought.html.erb
<h3>People Who Bought <%= @product.title %></h3>
<ul>
<% for order in @product.orders %>
<li>
<%= mail_to order.email, order.name %>
</li>
<% end %>
</ul>
Add the html format to the controller
edit app/controllers/products_controller.rb
def who_bought
@product = Product.find(params[:id])
respond_to do |format|
format.html
format.xml { render :xml => @product.to_xml(:include => :orders) }
format.atom
end
end
See the (raw) HTML
curl --silent --user dave:secret http://localhost:3000/products/2/who_bought
<!-- START:head -->
<!DOCTYPE html>
<html>
<head>
<title>Pragprog Books Online Store</title>
<link href="/assets/application.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/carts.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/line_items.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/orders.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/products.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/scaffolds.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/store.css?body=1" media="all" rel="stylesheet" type="text/css" />
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery-ui.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/carts.js?body=1" type="text/javascript"></script>
<script src="/assets/line_items.js?body=1" type="text/javascript"></script>
<script src="/assets/orders.js?body=1" type="text/javascript"></script>
<script src="/assets/products.js?body=1" type="text/javascript"></script>
<script src="/assets/store.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="A793Ddg7q+KosiyDEYBpx8MERuhIsM6Nfqf4QXynrtQ=" name="csrf-token" />
</head>
<!-- END:head -->
<body class="products">
<div id="banner">
<img alt="Logo" src="/assets/logo.png" />
Pragmatic Bookshelf
</div>
<div id="columns">
<div id="side">
<!-- START_HIGHLIGHT -->
<!-- START:hidden_div -->
<!-- START_HIGHLIGHT -->
<!-- END_HIGHLIGHT -->
<!-- END:hidden_div -->
<!-- END_HIGHLIGHT -->
<ul>
<li><a href="http://www....">Home</a></li>
<li><a href="http://www..../faq">Questions</a></li>
<li><a href="http://www..../news">News</a></li>
<li><a href="http://www..../contact">Contact</a></li>
</ul>
</div>
<div id="main">
<h3>People Who Bought CoffeeScript</h3>
<ul>
<li>
<a href="mailto:customer@example.com">Dave Thomas</a>
</li>
</ul>
</div>
</div>
</body>
</html>
Anything that XML can do, JSON can too...
edit app/controllers/products_controller.rb
def who_bought
@product = Product.find(params[:id])
respond_to do |format|
format.html
format.xml { render :xml => @product.to_xml(:include => :orders) }
format.atom
format.json { render :json => @product.to_json(:include => :orders) }
end
end
Fetch the data in JSON format
curl --silent --user dave:secret http://localhost:3000/products/2/who_bought.json
{"price":"36.0","created_at":"2012-10-11T07:11:35Z","title":"CoffeeScript","image_url":"cs.jpg","updated_at":"2012-10-11T07:11:35Z","orders":[{"address":"123 Main St","name":"Dave Thomas","created_at":"2012-10-11T07:15:28Z","updated_at":"2012-10-11T07:15:28Z","pay_type":"Check","id":1,"email":"customer@example.com"}],"id":2,"description":"<p>\n CoffeeScript is JavaScript done right. It provides all of JavaScript's\n\tfunctionality wrapped in a cleaner, more succinct syntax. In the first\n\tbook on this exciting new language, CoffeeScript guru Trevor Burnham\n\tshows you how to hold onto all the power and flexibility of JavaScript\n\twhile writing clearer, cleaner, and safer code.\n </p>"}
Customize the xml
edit app/views/products/who_bought.xml.builder
xml.order_list(:for_product => @product.title) do
for o in @product.orders
xml.order do
xml.name(o.name)
xml.email(o.email)
end
end
end
Change the rendering to use templates
edit app/controllers/products_controller.rb
def who_bought
@product = Product.find(params[:id])
respond_to do |format|
format.html
format.xml
format.atom
format.json { render :json => @product.to_json(:include => :orders) }
end
end
Fetch the (much streamlined) XML
curl --silent --user dave:secret http://localhost:3000/products/2/who_bought.xml
<order_list for_product="CoffeeScript">
<order>
<name>Dave Thomas</name>
<email>customer@example.com</email>
</order>
</order_list>
Verify that the tests still pass
rake test
Loaded suite /home/rubys/.rvm/gems/ruby-1.8.7-p352/gems/rake-0.9.2.2/lib/rake/rake_test_loader
Started
.......
Finished in 0.489771 seconds.
7 tests, 28 assertions, 0 failures, 0 errors
Loaded suite /home/rubys/.rvm/gems/ruby-1.8.7-p352/gems/rake-0.9.2.2/lib/rake/rake_test_loader
Started
.................................
Finished in 1.452959 seconds.
33 tests, 54 assertions, 0 failures, 0 errors
Commit
git commit -a -m "Orders"
[master d8cf257] Orders
6 files changed, 46 insertions(+), 31 deletions(-)
git tag iteration-g
13.1 Iteration H1: Email Notifications 12.3 Iteration G3: Pagination