Table of Contents 12.2 Iteration G2: Atom Feeds
demonstrate streaming with ActionController::Live
Switch to puma as a server
edit Gemfile
gem 'puma'
add a route for downloading a product
edit config/routes.rb
Depot::Application.routes.draw do
resources :orders
resources :line_items
resources :carts
get "store/index"
resources :products do
get :download, :on => :member
get :who_bought, on: :member
end
# The priority is based upon order of creation:
# first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'store#index', as: 'store'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
mock streaming implementation for download
edit app/controllers/products_controller.rb
include ActionController::Live
def download
response.headers['Content-Type'] = 'text/plain'
40.times do |i|
response.stream.write "Line #{i}\n\n"
sleep 0.10
end
response.stream.write "Fini.\n"
ensure
response.stream.close
end
add order to the session
edit app/controllers/orders_controller.rb
def create
@order = Order.new(order_params)
@order.add_line_items_from_cart(@cart)
respond_to do |format|
if @order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
session[:order_id] = @order.id
format.html { redirect_to store_url, notice:
'Thank you for your order.' }
format.json { render action: 'show', status: :created,
location: @order }
else
format.html { render action: 'new' }
format.json { render json: @order.errors,
status: :unprocessable_entity }
end
end
end
render order in the side bar
edit app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "application", media: "all",
"data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
</head>
<body class="<%= controller.controller_name %>">
<div id="banner">
<%= image_tag("logo.png") %>
<span class="title"><%= @page_title || "Pragmatic Bookshelf" %></span>
</div>
<div id="columns">
<div id="side">
<% if @cart %>
<%= hidden_div_if(@cart.line_items.empty?, id: 'cart') do %>
<%= render @cart %>
<% end %>
<% end %>
<%= render Order.find(session[:order_id]) if session[:order_id] -%>
<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">
<%= yield %>
</div>
</div>
</body>
</html>
implement order partial
edit app/views/orders/_order.html.erb
<div id="order">
<h2>Your Downloads</h2>
<table data-no-turbolink>
<% order.line_items.each do |item| %>
<tr>
<td><%= link_to item.product.title, download_product_path(item.product) %></td>
</tr>
<% end %>
</table>
</div>
css tweaks
edit app/assets/stylesheets/application.css.scss
#side {
padding: 1em 2em;
background: #141;
form, div {
display: inline;
}
input {
font-size: small;
}
#cart, #order {
font-size: smaller;
color: white;
a, a:hover {
color: white;
background-color: #141;
}
table {
border-top: 1px dotted #595;
border-bottom: 1px dotted #595;
margin-bottom: 10px;
}
}
ul {
padding: 0;
li {
list-style: none;
a {
color: #bfb;
font-size: small;
}
}
}
}
place an order
get /
#<Errno::ECONNREFUSED: Connection refused - connect(2)> /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/net/http.rb:763:in `initialize' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/net/http.rb:763:in `open' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/net/http.rb:763:in `block in connect' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/timeout.rb:55:in `timeout' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/timeout.rb:100:in `timeout' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/net/http.rb:763:in `connect' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/net/http.rb:756:in `do_start' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/net/http.rb:745:in `start' /home/rubys/.rvm/rubies/ruby-1.9.3-p551/lib/ruby/1.9.1/net/http.rb:557:in `start' /home/rubys/git/gorp/lib/gorp/net.rb:132:in `post' makedepot.rb:2568:in `block in <main>' /home/rubys/git/gorp/lib/gorp/output.rb:59:in `call' /home/rubys/git/gorp/lib/gorp/output.rb:59:in `block (4 levels) in <top (required)>' /home/rubys/git/gorp/lib/gorp/output.rb:49:in `each' /home/rubys/git/gorp/lib/gorp/output.rb:49:in `block (3 levels) in <top (required)>' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:170:in `call' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:170:in `_nested_structures' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:63:in `tag!' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:88:in `method_missing' /home/rubys/git/gorp/lib/gorp/output.rb:22:in `block (2 levels) in <top (required)>' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:170:in `call' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:170:in `_nested_structures' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:63:in `tag!' /home/rubys/.rvm/gems/ruby-1.9.3-p551/gems/builder-3.1.4/lib/builder/xmlbase.rb:88:in `method_missing' /home/rubys/git/gorp/lib/gorp/output.rb:11:in `block in <top (required)>'