The Depot Application

The Depot Application

Table of Contents

Development Log

ruby /home/rubys/git/rails/railties/bin/rails -v
Rails 2.3.2
ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
gem -v
1.3.3

4 Instant Gratification

erb -r rubygems -r active_support -T - < /home/rubys/git/awdwr/data/code/erb/ex1.html.erb |  
       sed 's/<!--.*-->//'
<ul>
  <li>Addition: 3 </li>
  <li>Concatenation: cowboy </li>
  <li>Time in one hour:  Fri May 15 15:02:41 -0400 2009 </li>
</ul>
erb -r rubygems -r active_support -T - < /home/rubys/git/awdwr/data/code/erb/ex2.html.erb | 
       sed 's/<!--.*-->//'
 
Ho!<br />
 
Ho!<br />
 
Ho!<br />
 
Merry Christmas!
erb -r rubygems -r active_support -T - < /home/rubys/git/awdwr/data/code/erb/ex2a.html.erb | 
       sed 's/<!--.*-->//'
Ho!<br />
Ho!<br />
Ho!<br />
 
Merry Christmas!
sed 's/-%>\n/%>/' < /home/rubys/git/awdwr/data/code/erb/ex2b.html.erb |  
       erb -r rubygems -r active_support -T - |
       sed 's/<!--.*-->//'
Ho!<br />
Ho!<br />
Ho!<br />
Merry Christmas!

6.1 Iteration A1: Getting Something Running

ruby /home/rubys/git/rails/railties/bin/rails depot
      create  
      create  app/controllers
      create  app/helpers
      create  app/models
      create  app/views/layouts
      create  config/environments
      create  config/initializers
      create  config/locales
      create  db
      create  doc
      create  lib
      create  lib/tasks
      create  log
      create  public/images
      create  public/javascripts
      create  public/stylesheets
      create  script/performance
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/performance
      create  test/unit
      create  vendor
      create  vendor/plugins
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  Rakefile
      create  README
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  config/database.yml
      create  config/routes.rb
      create  config/locales/en.yml
      create  db/seeds.rb
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/new_rails_defaults.rb
      create  config/initializers/session_store.rb
      create  config/environment.rb
      create  config/boot.rb
      create  config/environments/production.rb
      create  config/environments/development.rb
      create  config/environments/test.rb
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/runner
      create  script/server
      create  script/plugin
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  test/test_helper.rb
      create  test/performance/browsing_test.rb
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/index.html
      create  public/favicon.ico
      create  public/robots.txt
      create  public/images/rails.png
      create  public/javascripts/prototype.js
      create  public/javascripts/effects.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/controls.js
      create  public/javascripts/application.js
      create  doc/README_FOR_APP
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
ln -s /home/rubys/git/rails vendor/rails
edit config/environments/development.rb
# Settings specified here will take precedence over those in config/environment.rb
 
# In the development environment your application's code is reloaded on
# every request.  This slows down response time but is perfect for development
# since you don't have to restart the webserver when you make code changes.
config.cache_classes = false
 
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
 
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_view.debug_rjs                         = true
config.action_controller.perform_caching             = false
 
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
 
config.logger = Logger.new(config.log_path, 2, 10.kilobytes)

6.2 Creating the Products Model and Maintenance Application

ls -p
app/
config/
db/
doc/
lib/
log/
public/
Rakefile
README
script/
test/
tmp/
vendor/
ruby script/generate scaffold product title:string description:text image_url:string
      exists  app/models/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/products
      exists  app/views/layouts/
      exists  test/functional/
      exists  test/unit/
      create  test/unit/helpers/
      exists  public/stylesheets/
      create  app/views/products/index.html.erb
      create  app/views/products/show.html.erb
      create  app/views/products/new.html.erb
      create  app/views/products/edit.html.erb
      create  app/views/layouts/products.html.erb
      create  public/stylesheets/scaffold.css
      create  app/controllers/products_controller.rb
      create  test/functional/products_controller_test.rb
      create  app/helpers/products_helper.rb
      create  test/unit/helpers/products_helper_test.rb
       route  map.resources :products
  dependency  model
      exists    app/models/
      exists    test/unit/
      exists    test/fixtures/
      create    app/models/product.rb
      create    test/unit/product_test.rb
      create    test/fixtures/products.yml
      create    db/migrate
      create    db/migrate/20090515180247_create_products.rb
rake db:migrate
mv 20090515180247_create_products.rb 20080601000001_create_products.rb
(in /home/rubys/git/awdwr/work/depot)
==  CreateProducts: migrating =================================================
-- create_table(:products)
   -> 0.0024s
==  CreateProducts: migrated (0.0028s) ========================================
 
sqlite3> select version from schema_migrations
version = 20080601000001

restart

edit app/views/products/new.html.erb
<h1>New product</h1>
 
<% form_for(@product) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_area :description, :rows => 6 %>
  </p>
  <p>
    <%= f.label :image_url %><br />
    <%= f.text_field :image_url %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>
 
<%= link_to 'Back', products_path %>
get /products

Listing products

Title Description Image url

New product
get /products/new

New product




Back
post /products
You are being redirected.
get http://127.0.0.1:3000/products/1

Title: Pragmatic Version Control

Description: <p> This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. dont use any version control at all. Many others dont use it well, and end up experiencing time-consuming problems. </p>

Image url: /images/svn.jpg

Edit | Back
get /products

Listing products

Title Description Image url
Pragmatic Version Control <p> This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. dont use any version control at all. Many others dont use it well, and end up experiencing time-consuming problems. </p> /images/svn.jpg Show Edit Destroy

New product
sqlite3 db/development.sqlite3 .schema
CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "description" text, "image_url" varchar(255), "created_at" datetime, "updated_at" datetime);
CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
rake test
/usr/bin/ruby1.8 -I"/home/rubys/git/awdwr/work/depot/lib" -I"/home/rubys/git/awdwr/work/depot/test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/unit/product_test.rb" "test/unit/helpers/products_helper_test.rb" 
(in /home/rubys/git/awdwr/work/depot)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
Started
.
Finished in 0.04595 seconds.
 
1 tests, 1 assertions, 0 failures, 0 errors
/usr/bin/ruby1.8 -I"/home/rubys/git/awdwr/work/depot/lib" -I"/home/rubys/git/awdwr/work/depot/test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/functional/products_controller_test.rb" 
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
Started
.......
Finished in 0.225427 seconds.
 
7 tests, 10 assertions, 0 failures, 0 errors
/usr/bin/ruby1.8 -I"/home/rubys/git/awdwr/work/depot/lib" -I"/home/rubys/git/awdwr/work/depot/test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader.rb"  

6.3 Iteration A2: Add a Missing Column

ruby script/generate migration add_price_to_product price:decimal
      exists  db/migrate
      create  db/migrate/20090515180309_add_price_to_product.rb
cat db/migrate/20090515180309_add_price_to_product.rb
class AddPriceToProduct < ActiveRecord::Migration
  def self.up
    add_column :products, :price, :decimal
  end
 
  def self.down
    remove_column :products, :price
  end
end
edit db/migrate/20090515180309_add_price_to_product.rb
class AddPriceToProduct < ActiveRecord::Migration
  def self.up
    add_column :products, :price, :decimal,
      :precision => 8, :scale => 2, :default => 0
  end
 
  def self.down
    remove_column :products, :price
  end
end
rake db:migrate
mv 20090515180309_add_price_to_product.rb 20080601000002_add_price_to_product.rb
(in /home/rubys/git/awdwr/work/depot)
==  AddPriceToProduct: migrating ==============================================
-- add_column(:products, :price, :decimal, {:scale=>2, :precision=>8, :default=>0})
   -> 0.0017s
==  AddPriceToProduct: migrated (0.0019s) =====================================
 
sqlite3 db/development.sqlite3 .schema
CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "description" text, "image_url" varchar(255), "created_at" datetime, "updated_at" datetime, "price" decimal(8,2) DEFAULT 0);
CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
edit app/views/products/index.html.erb
<h1>Listing products</h1>
 
<table>
  <tr>
    <th>Title</th>
    <th>Description</th>
    <th>Image url</th>
    <th>Price</th>
  </tr>
 
<% @products.each do |product| %>
  <tr>
    <td><%=h product.title %></td>
    <td><%=h product.description %></td>
    <td><%=h product.image_url %></td>
    <td><%=h product.price %></td>
    <td><%= link_to 'Show', product %></td>
    <td><%= link_to 'Edit', edit_product_path(product) %></td>
    <td><%= link_to 'Destroy', product, :confirm => 'Are you sure?',
                                        :method => :delete %></td>
  </tr>
<% end %>
</table>
 
<br />
 
<%= link_to 'New product', new_product_path %>
edit app/views/products/new.html.erb
<h1>New product</h1>
 
<% form_for(@product) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_area :description, :rows => 6 %>
  </p>
  <p>
    <%= f.label :image_url %><br />
    <%= f.text_field :image_url %>
  </p>
  <p>
    <%= f.label :price %><br />
    <%= f.text_field :price %>
  </p>
 
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>
 
<%= link_to 'Back', products_path %>
edit app/views/products/edit.html.erb
<h1>Editing product</h1>
 
<% form_for(@product) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_area :description %>
  </p>
  <p>
    <%= f.label :image_url %><br />
    <%= f.text_field :image_url %>
  </p>
  <p>
    <%= f.label :price %><br />
    <%= f.text_field :price %>
  </p>
 
  <p>
    <%= f.submit 'Update' %>
  </p>
<% end %>
 
<%= link_to 'Show', @product %> |
<%= link_to 'Back', products_path %>
edit app/views/products/show.html.erb
<p>
  <b>Title:</b>
  <%=h @product.title %>
</p>
 
<p>
  <b>Description:</b>
  <%=h @product.description %>
</p>
 
<p>
  <b>Image url:</b>
  <%=h @product.image_url %>
</p>
 
<p>
  <b>Price:</b>
  <%=h @product.price %>
</p>
 
<%= link_to 'Edit', edit_product_path(@product) %> |
<%= link_to 'Back', products_path %>
get /products

Listing products

Title Description Image url Price
Pragmatic Version Control <p> This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. dont use any version control at all. Many others dont use it well, and end up experiencing time-consuming problems. </p> /images/svn.jpg 0.0 Show Edit Destroy

New product
get /products/1

Title: Pragmatic Version Control

Description: <p> This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. dont use any version control at all. Many others dont use it well, and end up experiencing time-consuming problems. </p>

Image url: /images/svn.jpg

Price: 0.0

Edit | Back
get /products/new

New product





Back
rake test
/usr/bin/ruby1.8 -I"/home/rubys/git/awdwr/work/depot/lib" -I"/home/rubys/git/awdwr/work/depot/test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/unit/product_test.rb" "test/unit/helpers/products_helper_test.rb" 
(in /home/rubys/git/awdwr/work/depot)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
Started
.
Finished in 0.041266 seconds.
 
1 tests, 1 assertions, 0 failures, 0 errors
/usr/bin/ruby1.8 -I"/home/rubys/git/awdwr/work/depot/lib" -I"/home/rubys/git/awdwr/work/depot/test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader.rb" "test/functional/products_controller_test.rb" 
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
Started
.......
Finished in 0.183199 seconds.
 
7 tests, 10 assertions, 0 failures, 0 errors
/usr/bin/ruby1.8 -I"/home/rubys/git/awdwr/work/depot/lib" -I"/home/rubys/git/awdwr/work/depot/test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader.rb"  
edit app/views/products/show.html.erb
<p>
  <b>Title:</b>
  <%=h @product.title %>
</p>
 
<p>
  <b>Description:</b>
  <%= @product.description %>
</p>
 
<p>
  <b>Image url:</b>
  <%=h @product.image_url %>
</p>
 
<p>
  <b>Price:</b>
  <%=h @product.price %>
</p>
 
<%= link_to 'Edit', edit_product_path(@product) %> |
<%= link_to 'Back', products_path %>
get /products/1

Title: Pragmatic Version Control

Description:

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. dont use any version control at all. Many others dont use it well, and end up experiencing time-consuming problems.

Image url: /images/svn.jpg

Price: 0.0

Edit | Back

6.4 Iteration A3: Validate!

edit app/models/product.rb
class Product < ActiveRecord::Base
  validates_presence_of :title, :description, :image_url
  validates_numericality_of :price
  validate :price_must_be_at_least_a_cent
  validates_uniqueness_of :title
  validates_format_of :image_url, :allow_blank => true,
                      :with    => %r{\.(gif|jpg|png)$}i,
                      :message => 'must be a URL for GIF, JPG ' +
                                  'or PNG image.'

    
protected
  def price_must_be_at_least_a_cent
    errors.add(:price, 'should be at least 0.01') if price.nil? ||
                       price < 0.00
  end

    
end
get /products/new

New product





Back
post /products
  • product[price] => 0.0

New product

3 errors prohibited this product from being saved

There were problems with the following fields:

  • Image url can't be blank
  • Title can't be blank
  • Description can't be blank





Back
get /products/new

New product





Back
post /products
  • product[image_url] => /images/utj.jpg
  • product[price] => wibble
  • product[description] => A true masterwork. Comparable to Kafka at his funniest, or Marx during his slapstick period. Move over, Tolstoy, there's a new funster in town.
  • product[title] => Pragmatic Unit Testing

New product

1 error prohibited this product from being saved

There were problems with the following fields:

  • Price is not a number





Back
edit app/models/product.rb
class Product < ActiveRecord::Base
  validates_presence_of :title, :description, :image_url
  validates_numericality_of :price
  validate :price_must_be_at_least_a_cent
  validates_uniqueness_of :title
  validates_format_of :image_url,
                      :with    => %r{\.(gif|jpg|png)$}i,
                      :message => 'must be a URL for GIF, JPG ' +
                                  'or PNG image.'
 
protected
  def price_must_be_at_least_a_cent
    errors.add(:price, 'should be at least 0.01') if price.nil? ||
                       price < 0.01
  end
 
end
edit app/views/layouts/products.html.erb

6.5 Iteration A4: Making Prettier Listings

edit db/migrate/003_add_test_data.rb
class AddTestData < ActiveRecord::Migration
  def self.up
    Product.delete_all
    Product.create(:title => 'Pragmatic Version Control',
      :description =>
      %{<p>
         This book is a recipe-based approach to using Subversion that will 
         get you up and running quickly---and correctly. All projects need
         version control: it's a foundational piece of any project's 
         infrastructure. Yet half of all project teams in the U.S. don't use
         any version control at all. Many others don't use it well, and end 
         up experiencing time-consuming problems.
      </p>},
    :image_url => '/images/svn.jpg',
    :price => 28.50)
    # . . .
  end

    
  def self.down
    Product.delete_all
  end
end
rake db:migrate
mv 003_add_test_data.rb 20080601000003_add_test_data.rb
(in /home/rubys/git/awdwr/work/depot)
==  AddTestData: migrating ====================================================
==  AddTestData: migrated (0.0350s) ===========================================
 
edit app/views/layouts/products.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Products: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold', 'depot' %>
</head>
edit app/views/products/index.html.erb
<div id="product-list">
  <h1>Listing products</h1>
 
  <table>
  <% for product in @products %>
    <tr class="<%= cycle('list-line-odd', 'list-line-even') %>">
 
      <td>
        <%= image_tag product.image_url, :class => 'list-image' %>
      </td>
 
      <td class="list-description">
        <dl>
          <dt><%=h product.title %></dt>
          <dd><%=h truncate(product.description.gsub(/<.*?>/,''),
                 :length => 80) %></dd>
        </dl>
      </td>
 
      <td class="list-actions">
        <%= link_to 'Show', product %><br/>
        <%= link_to 'Edit', edit_product_path(product) %><br/>
        <%= link_to 'Destroy', product, 
                    :confirm => 'Are you sure?',
                    :method => :delete %>
      </td>
    </tr>
  <% end %>
  </table>
</div>
 
<br />
 
<%= link_to 'New product', new_product_path %>
cp -v /home/rubys/git/awdwr/data/images/* public/images/
`/home/rubys/git/awdwr/data/images/auto.jpg' -> `public/images/auto.jpg'
`/home/rubys/git/awdwr/data/images/logo.png' -> `public/images/logo.png'
`/home/rubys/git/awdwr/data/images/rails.png' -> `public/images/rails.png'
`/home/rubys/git/awdwr/data/images/svn.jpg' -> `public/images/svn.jpg'
`/home/rubys/git/awdwr/data/images/utc.jpg' -> `public/images/utc.jpg'
cp -v /home/rubys/git/awdwr/data/depot.css public/stylesheets
`/home/rubys/git/awdwr/data/depot.css' -> `public/stylesheets/depot.css'
get /products

Listing products

Auto
Pragmatic Project Automation
Pragmatic Project Automation shows you how to improve the con...
Show
Edit
Destroy
Svn
Pragmatic Version Control
This book is a recipe-based approach to using Subversion that will ...
Show
Edit
Destroy
Utc
Pragmatic Unit Testing (C#)
Pragmatic programmers use feedback to drive their development and ...
Show
Edit
Destroy

New product

7.1 Iteration B1: Create the Catalog Listing

ruby script/generate controller store index
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/store
      exists  test/functional/
      exists  test/unit/helpers/
      create  app/controllers/store_controller.rb
      create  test/functional/store_controller_test.rb
      create  app/helpers/store_helper.rb
      create  test/unit/helpers/store_helper_test.rb
      create  app/views/store/index.html.erb

restart

get /store

Store#index

Find me in app/views/store/index.html.erb

edit app/controllers/store_controller.rb
class StoreController < ApplicationController
  def index
    @products = Product.find_products_for_sale
  end
 
end
edit app/models/product.rb
class Product < ActiveRecord::Base
 
  def self.find_products_for_sale
    find(:all, :order => "title")
  end
 
  # validation stuff...
 
 
  validates_presence_of :title, :description, :image_url
  validates_numericality_of :price
  validate :price_must_be_at_least_a_cent
  validates_uniqueness_of :title
  validates_format_of :image_url,
                      :with    => %r{\.(gif|jpg|png)$}i,
                      :message => 'must be a URL for GIF, JPG ' +
                                  'or PNG image.'
 
protected
  def price_must_be_at_least_a_cent
    errors.add(:price, 'should be at least 0.01') if price.nil? ||
                       price < 0.01
  end
 
end
edit app/views/store/index.html.erb
<h1>Your Pragmatic Catalog</h1>

    
<% for product in @products -%>
  <div class="entry">
    <%= image_tag(product.image_url) %>
    <h3><%=h product.title %></h3>
    <%= product.description %>
    <div class="price-line">
    <span class="price"><%= product.price %></span>
    </div>
  </div>
<% end %>
get /store

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28.5

7.2 Iteration B2: Add a Page Layout

edit app/views/layouts/store.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <title>Pragprog Books Online Store</title>
  <%= stylesheet_link_tag "depot", :media => "all" %><!-- <label id="code.slt"/> -->
</head>
<body id="store">
  <div id="banner">
    <%= image_tag("logo.png") %>
    <%= @page_title || "Pragmatic Bookshelf" %><!-- <label id="code.depot.e.title"/> -->
  </div>
  <div id="columns">
    <div id="side">
      <a href="http://www....">Home</a><br />
      <a href="http://www..../faq">Questions</a><br />
      <a href="http://www..../news">News</a><br />
      <a href="http://www..../contact">Contact</a><br />
    </div>
    <div id="main">
      <%= yield :layout %><!-- <label id="code.depot.e.include"/> -->
    </div>
  </div>
</body>
</html>
edit public/stylesheets/depot.css
/* Styles for main page */
 
#banner {
  background: #9c9;
  padding-top: 10px;
  padding-bottom: 10px;
  border-bottom: 2px solid;
  font: small-caps 40px/40px "Times New Roman", serif;
  color: #282;
  text-align: center;
}
 
#banner img {
  float: left;
}
 
#columns {
  background: #141;
}
 
#main {
  margin-left: 13em;
  padding-top: 4ex;
  padding-left: 2em;
  background: white;
}
 
#side {
  float: left;
  padding-top: 1em;
  padding-left: 1em;
  padding-bottom: 1em;
  width: 12em;
  background: #141;
}
 
#side a {
  color: #bfb;
  font-size: small;
}
get /store

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28.5

7.3 Iteration B3: Use a Helper to Format the Price

edit app/views/store/index.html.erb
<h1>Your Pragmatic Catalog</h1>
 
<% for product in @products -%>
  <div class="entry">
    <%= image_tag(product.image_url) %>
    <h3><%=h product.title %></h3>
    <%= product.description %>
    <div class="price-line">
    <span class="price"><%= number_to_currency(product.price) %></span>
    </div>
  </div>
<% end %>
get /store

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50

7.4 Iteration B4: Linking to the Cart

edit app/views/store/index.html.erb
    <%= button_to "Add to Cart" %>
edit public/stylesheets/depot.css
#store .entry form, #store .entry form div {
  display: inline;
}
get /store

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50

8.1 Sessions

rake db:sessions:create
(in /home/rubys/git/awdwr/work/depot)
      exists  db/migrate
      create  db/migrate/20090515180338_create_sessions.rb
rake db:migrate
mv 20090515180338_create_sessions.rb 20080601000004_create_sessions.rb
(in /home/rubys/git/awdwr/work/depot)
==  CreateSessions: migrating =================================================
-- create_table(:sessions)
   -> 0.0030s
-- add_index(:sessions, :session_id)
   -> 0.0009s
-- add_index(:sessions, :updated_at)
   -> 0.0007s
==  CreateSessions: migrated (0.0050s) ========================================
 
sqlite3 db/development.sqlite3 .schema
CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "description" text, "image_url" varchar(255), "created_at" datetime, "updated_at" datetime, "price" decimal(8,2) DEFAULT 0);
CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
CREATE TABLE "sessions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "session_id" varchar(255) NOT NULL, "data" text, "created_at" datetime, "updated_at" datetime);
CREATE INDEX "index_sessions_on_session_id" ON "sessions" ("session_id");
CREATE INDEX "index_sessions_on_updated_at" ON "sessions" ("updated_at");
CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
edit config/initializers/session_store.rb
# Be sure to restart your server when you modify this file.
 
# Your secret key for verifying cookie session data integrity.
# If you change this key, all old sessions will become invalid!
# Make sure the secret is at least 30 characters and all random, 
# no regular words or you'll be exposed to dictionary attacks.
ActionController::Base.session = {
  :key         => '_depot_session',
  :secret      => '131a619434a07a778947c7eeaffb6e0eeac2417df1f44e54a73aef7dd5d6adb848723150104a5d0e622bb926455e40514e4747b53839ffdd95231ab64338eade'
}
 
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rake db:sessions:create")
ActionController::Base.session_store = :active_record_store

restart

edit app/controllers/application_controller.rb
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
 
class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
 
  # Scrub sensitive parameters from your log
  # filter_parameter_logging :password
end
edit app/controllers/store_controller.rb
private
 
  def find_cart
    session[:cart] ||= Cart.new
  end

8.2 Iteration C1: Creating a Cart

edit app/models/cart.rb
class Cart
  attr_reader :items   # <wtf linkend="wtf.attr.accessor">attr_reader</wtf>
  
  def initialize
    @items = []
  end
  
  def add_product(product)
    @items << product
  end
end
edit app/views/store/index.html.erb
    <%= button_to "Add to Cart", :action => 'add_to_cart', :id => product %>
edit app/controllers/store_controller.rb
  def add_to_cart
    product = Product.find(params[:id]) # <label id="code.depot.f.find"/>
    @cart = find_cart                   # <label id="code.depot.f.find2"/>
    @cart.add_product(product)          # <label id="code.depot.f.add"/>
  end
get /store/add_to_cart/2
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Action Controller: Exception caught</title>
  <style>
    body { background-color: #fff; color: #333; }

      
    body, p, ol, ul, td {
      font-family: verdana, arial, helvetica, sans-serif;
      font-size:   13px;
      line-height: 18px;
    }

      
    pre {
      background-color: #eee;
      padding: 10px;
      font-size: 11px;
    }

      
    a { color: #000; }
    a:visited { color: #666; }
    a:hover { color: #fff; background-color:#000; }
  </style>
</head>
<body>

      
<h1>Template is missing</h1>
<p>Missing template store/add_to_cart - {:locales=&gt;[:en], :formats=&gt;[:html, :all]} - partial: false.erb in view path /home/rubys/git/awdwr/work/depot/app/views</p>

      

      
</body>
</html>
edit app/views/store/add_to_cart.html.erb
<h2>Your Pragmatic Cart</h2>
<ul>
  <% for item in @cart.items %>
    <li><%=h item.title %></li>
  <% end %>
</ul>
get /store/add_to_cart/2

Your Pragmatic Cart

  • Pragmatic Project Automation
get /store/add_to_cart/3

Your Pragmatic Cart

  • Pragmatic Project Automation
  • Pragmatic Version Control

8.3 Iteration C2: Creating a Smarter Cart

edit app/models/cart_item.rb
class CartItem

    
  attr_reader :product, :quantity
  
  def initialize(product)
    @product = product
    @quantity = 1
  end
  
  def increment_quantity
    @quantity += 1
  end
  
  def title
    @product.title
  end
  
  def price
    @product.price * @quantity
  end
end
edit app/models/cart.rb
  def add_product(product)
    current_item = @items.find {|item| item.product == product}
    if current_item
      current_item.increment_quantity
    else
      @items << CartItem.new(product)
    end
  end
edit app/views/store/add_to_cart.html.erb
<h2>Your Pragmatic Cart</h2>
<ul>
  <% for item in @cart.items %>
    <li><%= item.quantity %> &times; <%=h item.title %></li>
  <% end %>
</ul>
get /store/add_to_cart/2
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Action Controller: Exception caught</title>
  <style>
    body { background-color: #fff; color: #333; }

      
    body, p, ol, ul, td {
      font-family: verdana, arial, helvetica, sans-serif;
      font-size:   13px;
      line-height: 18px;
    }

      
    pre {
      background-color: #eee;
      padding: 10px;
      font-size: 11px;
    }

      
    a { color: #000; }
    a:visited { color: #666; }
    a:hover { color: #fff; background-color:#000; }
  </style>
</head>
<body>

      
<h1>
  NoMethodError
  
    in StoreController#add_to_cart
  
</h1>
<pre>undefined method `product' for #&lt;Product:0xb6cf7bf8&gt;</pre>

      

      

      
<p><code>RAILS_ROOT: /home/rubys/git/awdwr/work/depot</code></p>

      
<div id="traces">
  
    
    <a href="#" onclick="document.getElementById('Framework-Trace').style.display='none';document.getElementById('Full-Trace').style.display='none';document.getElementById('Application-Trace').style.display='block';; return false;">Application Trace</a> |
  
    
    <a href="#" onclick="document.getElementById('Application-Trace').style.display='none';document.getElementById('Full-Trace').style.display='none';document.getElementById('Framework-Trace').style.display='block';; return false;">Framework Trace</a> |
  
    
    <a href="#" onclick="document.getElementById('Application-Trace').style.display='none';document.getElementById('Framework-Trace').style.display='none';document.getElementById('Full-Trace').style.display='block';; return false;">Full Trace</a> 
  

      
  
    <div id="Application-Trace" style="display: block;">
      <pre><code>/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:266:in `method_missing'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `add_product'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/dependencies.rb:391:in `find'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `each'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `find'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `add_product'
/home/rubys/git/awdwr/work/depot/app/controllers/store_controller.rb:11:in `add_to_cart'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
makedepot.rb:2300:in `restart_server'
makedepot.rb:346
makedepot.rb:2374:in `call'
makedepot.rb:2374
makedepot.rb:2371:in `each'
makedepot.rb:2371
makedepot.rb:2334
makedepot.rb:2307</code></pre>
    </div>
  
    <div id="Framework-Trace" style="display: none;">
      <pre><code>/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:266:in `method_missing'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `add_product'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/dependencies.rb:391:in `find'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `each'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `find'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `add_product'
/home/rubys/git/awdwr/work/depot/app/controllers/store_controller.rb:11:in `add_to_cart'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'</code></pre>
    </div>
  
    <div id="Full-Trace" style="display: none;">
      <pre><code>/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/attribute_methods.rb:266:in `method_missing'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `add_product'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/dependencies.rb:391:in `find'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `each'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `find'
/home/rubys/git/awdwr/work/depot/app/models/cart.rb:10:in `add_product'
/home/rubys/git/awdwr/work/depot/app/controllers/store_controller.rb:11:in `add_to_cart'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
makedepot.rb:2300:in `restart_server'
makedepot.rb:346
makedepot.rb:2374:in `call'
makedepot.rb:2374
makedepot.rb:2371:in `each'
makedepot.rb:2371
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
makedepot.rb:2334
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
makedepot.rb:2307</code></pre>
    </div>
  
</div>

      

      

      

      

      
<h2 style="margin-top: 30px">Request</h2>
<p><b>Parameters</b>: <pre>{&quot;id&quot;=&gt;&quot;2&quot;}</pre></p>

      
<p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p>
<div id="session_dump" style="display:none"><pre class='debug_dump'>--- 
</pre></div>

      

      
<h2 style="margin-top: 30px">Response</h2>
<p><b>Headers</b>: <pre>None</pre></p>

      

      

      
</body>
</html>
rake db:sessions:clear
(in /home/rubys/git/awdwr/work/depot)

restart

get /store/add_to_cart/2

Your Pragmatic Cart

  • 1 × Pragmatic Project Automation
get /store/add_to_cart/2

Your Pragmatic Cart

  • 2 × Pragmatic Project Automation
get /store/add_to_cart/3

Your Pragmatic Cart

  • 2 × Pragmatic Project Automation
  • 1 × Pragmatic Version Control
get /store/add_to_cart/wibble

ActiveRecord::RecordNotFound in StoreController#add_to_cart

Couldn't find Product with ID=wibble

RAILS_ROOT: /home/rubys/git/awdwr/work/depot

Application Trace | Framework Trace | Full Trace
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/base.rb:1599:in `find_one'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/base.rb:1582:in `find_from_ids'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/base.rb:626:in `find'
/home/rubys/git/awdwr/work/depot/app/controllers/store_controller.rb:9:in `add_to_cart'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
makedepot.rb:2300:in `restart_server'
makedepot.rb:421
makedepot.rb:2374:in `call'
makedepot.rb:2374
makedepot.rb:2371:in `each'
makedepot.rb:2371
makedepot.rb:2334
makedepot.rb:2307

Request

Parameters:

{"id"=>"wibble"}

Show session dump

Response

Headers:

None

8.4 Iteration C3: Handling Errors

edit app/controllers/store_controller.rb
  def add_to_cart
    product = Product.find(params[:id])
    @cart = find_cart
    @cart.add_product(product)
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    flash[:notice] = "Invalid product"
    redirect_to :action => 'index'
  end
get /store/add_to_cart/wibble
You are being redirected.
get http://127.0.0.1:3000/store

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
tail -17 log/development.log
 
 
 
 
Processing StoreController#add_to_cart (for 127.0.0.1 at 2009-05-15 14:04:00) [GET]
  Parameters: {"id"=>"wibble"}
  *[4;36;1mProduct Load (0.3ms)*[0m   *[0;1mSELECT * FROM "products" WHERE ("products"."id" = 0) *[0m
Attempt to access invalid product wibble
Redirected to http://127.0.0.1:3000/store
Completed in 28ms (DB: 1) | 302 Found [http://127.0.0.1/store/add_to_cart/wibble]
 
 
Processing StoreController#index (for 127.0.0.1 at 2009-05-15 14:04:00) [GET]
  *[4;35;1mProduct Load (1.1ms)*[0m   *[0mSELECT * FROM "products" ORDER BY title*[0m
Rendering /home/rubys/git/awdwr/work/depot/app/views/store/index.html.erb
Rendering template within /home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb
Completed in 276ms (View: 260, DB: 3) | 200 OK [http://127.0.0.1/store]
edit app/views/layouts/store.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <title>Pragprog Books Online Store</title>
  <%= stylesheet_link_tag "depot", :media => "all" %>
</head>
<body id="store">
  <div id="banner">
    <%= image_tag("logo.png") %>
    <%= @page_title || "Pragmatic Bookshelf" %>
  </div>
  <div id="columns">
    <div id="side">
      <a href="http://www....">Home</a><br />
      <a href="http://www..../faq">Questions</a><br />
      <a href="http://www..../news">News</a><br />
      <a href="http://www..../contact">Contact</a><br />
    </div>
    <div id="main">
      <% if flash[:notice] -%>
        <div id="notice"><%= flash[:notice] %></div>
      <% end -%>

    
      <%= yield :layout %>
    </div>
  </div>
</body>
</html>
edit public/stylesheets/depot.css
#notice {
  border: 2px solid red;
  padding: 1em;
  margin-bottom: 2em;
  background-color: #f0f0f0;
  font: bold smaller sans-serif;
}
get /store/add_to_cart/wibble
You are being redirected.
get http://127.0.0.1:3000/store
Invalid product

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50

8.5 Iteration C4: Finishing the Cart

edit app/views/store/add_to_cart.html.erb
<h2>Your Pragmatic Cart</h2>
<ul>
  <% for item in @cart.items %>
    <li><%= item.quantity %> &times; <%=h item.title %></li>
  <% end %>
</ul>

    
<%= button_to 'Empty cart', :action => 'empty_cart' %>
edit app/controllers/store_controller.rb
  def empty_cart
    session[:cart] = nil
    flash[:notice] = "Your cart is currently empty"
    redirect_to :action => 'index'
  end
get /store/empty_cart
You are being redirected.
get http://127.0.0.1:3000/store
Your cart is currently empty

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
edit app/controllers/store_controller.rb
  def add_to_cart
    product = Product.find(params[:id])
    @cart = find_cart
    @cart.add_product(product)
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    redirect_to_index("Invalid product")
  end
 
  def empty_cart
    session[:cart] = nil
    redirect_to_index("Your cart is currently empty")
  end
 
private
 
  def redirect_to_index(msg)
    flash[:notice] = msg
    redirect_to :action => 'index'
  end
edit app/views/store/add_to_cart.html.erb
<div class="cart-title">Your Cart</div>
<table>
  <% for item in @cart.items %>
    <tr>
      <td><%= item.quantity %>&times;</td>
      <td><%=h item.title %></td>
      <td class="item-price"><%= number_to_currency(item.price) %></td>
    </tr>
  <% end %>  
  
  <tr class="total-line">
    <td colspan="2">Total</td>
    <td class="total-cell"><%= number_to_currency(@cart.total_price) %></td>
  </tr>
 
</table>
  
<%= button_to "Empty cart", :action => :empty_cart %>
edit public/stylesheets/depot.css
/* Styles for the cart in the main page */
 
.cart-title {
  font: 120% bold;
}
 
.item-price, .total-line {
  text-align: right;
}
 
.total-line .total-cell {
  font-weight: bold;
  border-top: 1px solid #595;
}
edit app/models/cart.rb
class Cart
  attr_reader :items   # <wtf linkend="wtf.attr.accessor">attr_reader</wtf>
  
  def initialize
    @items = []
  end
  
  def add_product(product)
    current_item = @items.find {|item| item.product == product}
    if current_item
      current_item.increment_quantity
    else
      @items << CartItem.new(product)
    end
  end

    
  def total_price
    @items.sum { |item| item.price }
  end
end

restart

get /store/add_to_cart/2
Your Cart
Pragmatic Project Automation $29.95
Total $29.95
get /store/add_to_cart/2
Your Cart
Pragmatic Project Automation $59.90
Total $59.90
get /store/add_to_cart/3
Your Cart
Pragmatic Project Automation $59.90
Pragmatic Version Control $28.50
Total $88.40

9.1 Iteration D1: Moving the Cart

edit app/views/store/add_to_cart.html.erb
<div class="cart-title">Your Cart</div>
<table>
  <%= render(:partial => "cart_item", :collection => @cart.items) %>  
  
  <tr class="total-line">
    <td colspan="2">Total</td>
    <td class="total-cell"><%= number_to_currency(@cart.total_price) %></td>
  </tr>
 
</table>
  
<%= button_to "Empty cart", :action => :empty_cart %>
edit app/views/store/_cart_item.html.erb
<tr>
  <td><%= cart_item.quantity %>&times;</td>
  <td><%=h cart_item.title %></td>
  <td class="item-price"><%= number_to_currency(cart_item.price) %></td>
</tr>
cp app/views/store/add_to_cart.html.erb app/views/store/_cart.html.erb
edit app/views/store/_cart.html.erb
<div class="cart-title">Your Cart</div>
<table>
  <%= render(:partial => "cart_item", :collection => cart.items) %>  
  
  <tr class="total-line">
    <td colspan="2">Total</td>
    <td class="total-cell"><%= number_to_currency(cart.total_price) %></td>
  </tr>
 
</table>
  
<%= button_to "Empty cart", :action => :empty_cart %>
edit app/views/layouts/store.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <title>Pragprog Books Online Store</title>
  <%= stylesheet_link_tag "depot", :media => "all" %>
</head>
<body id="store">
  <div id="banner">
    <%= image_tag("logo.png") %>
    <%= @page_title || "Pragmatic Bookshelf" %>
  </div>
  <div id="columns">
    <div id="side">
      <div id="cart">
        <%= render(:partial => "cart", :object => @cart) %>
      </div>
 
      <a href="http://www....">Home</a><br />
      <a href="http://www..../faq">Questions</a><br />
      <a href="http://www..../news">News</a><br />
      <a href="http://www..../contact">Contact</a><br />
    </div>
    <div id="main">
      <% if flash[:notice] -%>
        <div id="notice"><%= flash[:notice] %></div>
      <% end -%>
 
      <%= yield :layout %>
    </div>
  </div>
</body>
</html>
edit app/controllers/store_controller.rb
  def index
    @products = Product.find_products_for_sale
    @cart = find_cart
  end
edit public/stylesheets/depot.css
/* Styles for the cart in the sidebar */
 
#cart, #cart table {
  font-size: smaller;
  color:     white;
}
 
#cart table {
  border-top:    1px dotted #595;
  border-bottom: 1px dotted #595;
  margin-bottom: 10px;
}
get /store
Your Cart
Pragmatic Project Automation $59.90
Pragmatic Version Control $28.50
Total $88.40
Home
Questions
News
Contact

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
edit app/controllers/store_controller.rb
  def add_to_cart
    product = Product.find(params[:id])
    @cart = find_cart
    @cart.add_product(product)
    redirect_to_index
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    redirect_to_index("Invalid product")
  end
edit app/controllers/store_controller.rb
  def redirect_to_index(msg = nil)
    flash[:notice] = msg if msg
    redirect_to :action => 'index'
  end
rm app/views/store/add_to_cart.html.erb
get /store/add_to_cart/3
You are being redirected.
get http://127.0.0.1:3000/store
Your Cart
Pragmatic Project Automation $59.90
Pragmatic Version Control $57.00
Total $116.90
Home
Questions
News
Contact

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50

9.2 Iteration D2: Creating an AJAX-Based Cart

edit app/views/store/index.html.erb
    <% form_remote_tag :url => { :action => 'add_to_cart', :id => product } do %>
      <%= submit_tag "Add to Cart" %>
    <% end %>
edit app/views/layouts/store.html.erb
<html>
<head>
  <title>Pragprog Books Online Store</title>
  <%= stylesheet_link_tag "depot", :media => "all" %>
  <%= javascript_include_tag :defaults %>
</head>
edit app/controllers/store_controller.rb
  def add_to_cart
    product = Product.find(params[:id])
    @cart = find_cart
    @cart.add_product(product)
    respond_to do |format|
      format.js
    end
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    redirect_to_index("Invalid product")
  end
edit app/views/store/add_to_cart.js.rjs
page.replace_html("cart", :partial => "cart", :object => @cart)

9.3 Iteration D3: Highlighting Changes

edit app/models/cart.rb
class Cart
  attr_reader :items   # <wtf linkend="wtf.attr.accessor">attr_reader</wtf>
  
  def initialize
    @items = []
  end
  
  def add_product(product)
    current_item = @items.find {|item| item.product == product}
    if current_item
      current_item.increment_quantity
    else
      current_item = CartItem.new(product)
      @items << current_item 
    end
    current_item
  end
 
  def total_price
    @items.sum { |item| item.price }
  end
end
edit app/controllers/store_controller.rb
  def add_to_cart
    product = Product.find(params[:id])
    @cart = find_cart
    @current_item = @cart.add_product(product)
    respond_to do |format|
      format.js
    end
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    redirect_to_index("Invalid product")
  end
edit app/views/store/_cart_item.html.erb
<% if cart_item == @current_item %>
  <tr id="current_item">
<% else %>
  <tr>
<% end %>
  <td><%= cart_item.quantity %>&times;</td>
  <td><%=h cart_item.title %></td>
  <td class="item-price"><%= number_to_currency(cart_item.price) %></td>
</tr>
edit app/views/store/add_to_cart.js.rjs
page.replace_html("cart", :partial => "cart", :object => @cart)

    
page[:current_item].visual_effect :highlight,
                                  :startcolor => "#88ff88",
                                  :endcolor => "#114411"

9.4 Iteration D4: Hide an Empty Cart

edit app/views/store/add_to_cart.js.rjs
page.replace_html("cart", :partial => "cart", :object => @cart)
 
page[:cart].visual_effect :blind_down if @cart.total_items == 1
 
page[:current_item].visual_effect :highlight,
                                  :startcolor => "#88ff88",
                                  :endcolor => "#114411"
edit app/models/cart.rb
class Cart
  attr_reader :items   # <wtf linkend="wtf.attr.accessor">attr_reader</wtf>
  
  def initialize
    @items = []
  end
  
  def add_product(product)
    current_item = @items.find {|item| item.product == product}
    if current_item
      current_item.increment_quantity
    else
      current_item = CartItem.new(product)
      @items << current_item 
    end
    current_item
  end
 
  def total_price
    @items.sum { |item| item.price }
  end
 
  def total_items
    @items.sum { |item| item.quantity }
  end
end
ls -p app
controllers/
helpers/
models/
views/
ls -p app/helpers
application_helper.rb
products_helper.rb
store_helper.rb
edit app/views/layouts/store.html.erb
      <% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
        <%= render(:partial => "cart", :object => @cart) %>
      <% end %>
edit app/helpers/store_helper.rb
module StoreHelper
  def hidden_div_if(condition, attributes = {}, &block)
    if condition
      attributes["style"] = "display: none"
    end
    content_tag("div", attributes, &block)
  end
end
edit app/controllers/store_controller.rb
  def empty_cart
    session[:cart] = nil
    redirect_to_index
  end

9.5 Iteration D5: Degrading If Javascript Is Disabled

edit app/controllers/store_controller.rb
  def add_to_cart
    product = Product.find(params[:id])
    @cart = find_cart
    @current_item = @cart.add_product(product)
    respond_to do |format|
      format.js if request.xhr?
      format.html {redirect_to_index}
    end
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    redirect_to_index("Invalid product")
  end
get /store/empty_cart
You are being redirected.
get http://127.0.0.1:3000/store
Home
Questions
News
Contact

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
get /store/add_to_cart/3
You are being redirected.
get http://127.0.0.1:3000/store
Your Cart
Pragmatic Version Control $28.50
Total $28.50
Home
Questions
News
Contact

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50

10.1 Iteration E1: Capturing an Order

ruby script/generate scaffold order name:string address:text email:string pay_type:string
      exists  app/models/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/orders
      exists  app/views/layouts/
      exists  test/functional/
      exists  test/unit/
      exists  test/unit/helpers/
      exists  public/stylesheets/
      create  app/views/orders/index.html.erb
      create  app/views/orders/show.html.erb
      create  app/views/orders/new.html.erb
      create  app/views/orders/edit.html.erb
      create  app/views/layouts/orders.html.erb
   identical  public/stylesheets/scaffold.css
      create  app/controllers/orders_controller.rb
      create  test/functional/orders_controller_test.rb
      create  app/helpers/orders_helper.rb
      create  test/unit/helpers/orders_helper_test.rb
       route  map.resources :orders
  dependency  model
      exists    app/models/
      exists    test/unit/
      exists    test/fixtures/
      create    app/models/order.rb
      create    test/unit/order_test.rb
      create    test/fixtures/orders.yml
      exists    db/migrate
      create    db/migrate/20090515180418_create_orders.rb
ruby script/generate scaffold line_item product_id:integer order_id:integer quantity:integer total_price:decimal
      exists  app/models/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/line_items
      exists  app/views/layouts/
      exists  test/functional/
      exists  test/unit/
      exists  test/unit/helpers/
      exists  public/stylesheets/
      create  app/views/line_items/index.html.erb
      create  app/views/line_items/show.html.erb
      create  app/views/line_items/new.html.erb
      create  app/views/line_items/edit.html.erb
      create  app/views/layouts/line_items.html.erb
   identical  public/stylesheets/scaffold.css
      create  app/controllers/line_items_controller.rb
      create  test/functional/line_items_controller_test.rb
      create  app/helpers/line_items_helper.rb
      create  test/unit/helpers/line_items_helper_test.rb
       route  map.resources :line_items
  dependency  model
      exists    app/models/
      exists    test/unit/
      exists    test/fixtures/
      create    app/models/line_item.rb
      create    test/unit/line_item_test.rb
      create    test/fixtures/line_items.yml
      exists    db/migrate
      create    db/migrate/20090515180420_create_line_items.rb
edit db/migrate/20090515180418_create_orders.rb
  def self.up
    create_table :orders do |t|
      t.string :name
      t.text :address
      t.string :email
      t.string :pay_type, :limit => 10
 
      t.timestamps
    end
  end
edit db/migrate/20090515180420_create_line_items.rb
class CreateLineItems < ActiveRecord::Migration
  def self.up
    create_table :line_items do |t|
      t.integer :product_id,  :null => false, :options =>
        "CONSTRAINT fk_line_item_products REFERENCES products(id)"
      t.integer :order_id,    :null => false, :options =>
        "CONSTRAINT fk_line_item_orders REFERENCES orders(id)"
      t.integer :quantity,    :null => false
      t.decimal :total_price, :null => false, :precision => 8, :scale => 2
 
      t.timestamps
    end
  end
 
  def self.down
    drop_table :line_items
  end
end
rake db:migrate
mv 20090515180418_create_orders.rb 20080601000005_create_orders.rb
mv 20090515180420_create_line_items.rb 20080601000006_create_line_items.rb
(in /home/rubys/git/awdwr/work/depot)
==  CreateOrders: migrating ===================================================
-- create_table(:orders)
   -> 0.0027s
==  CreateOrders: migrated (0.0029s) ==========================================
 
==  CreateLineItems: migrating ================================================
-- create_table(:line_items)
   -> 0.0310s
==  CreateLineItems: migrated (0.0316s) =======================================
 
sqlite3 db/development.sqlite3 .schema
CREATE TABLE "line_items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_id" integer NOT NULL, "order_id" integer NOT NULL, "quantity" integer NOT NULL, "total_price" decimal(8,2) NOT NULL, "created_at" datetime, "updated_at" datetime);
CREATE TABLE "orders" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "address" text, "email" varchar(255), "pay_type" varchar(10), "created_at" datetime, "updated_at" datetime);
CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "description" text, "image_url" varchar(255), "created_at" datetime, "updated_at" datetime, "price" decimal(8,2) DEFAULT 0);
CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
CREATE TABLE "sessions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "session_id" varchar(255) NOT NULL, "data" text, "created_at" datetime, "updated_at" datetime);
CREATE INDEX "index_sessions_on_session_id" ON "sessions" ("session_id");
CREATE INDEX "index_sessions_on_updated_at" ON "sessions" ("updated_at");
CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
edit app/models/order.rb
class Order < ActiveRecord::Base
  has_many :line_items
end
edit app/models/product.rb
class Product < ActiveRecord::Base
  has_many :line_items
  # ...
edit app/models/line_item.rb
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
end
edit app/views/store/_cart.html.erb
<div class="cart-title">Your Cart</div>
<table>
  <%= render(:partial => "cart_item", :collection => cart.items) %>  
  
  <tr class="total-line">
    <td colspan="2">Total</td>
    <td class="total-cell"><%= number_to_currency(cart.total_price) %></td>
  </tr>
 
</table>
  
<%= button_to "Checkout", :action => 'checkout' %>
<%= button_to "Empty cart", :action => :empty_cart %>
edit app/controllers/store_controller.rb
  def checkout
    @cart = find_cart
    if @cart.items.empty?
      redirect_to_index("Your cart is empty")
    else
      @order = Order.new
    end
  end
edit app/views/store/checkout.html.erb
<div class="depot-form">
  
  <%= error_messages_for 'order' %>
  
  <% form_for :order, :url => { :action => :save_order } do |form| %>
    <fieldset>
      <legend>Please Enter Your Details</legend>

    
      <div>
        <%= form.label :name, "Name:" %>
        <%= form.text_field :name, :size => 40 %>
      </div>

    
      <div>
        <%= form.label :address, "Address:" %>
        <%= form.text_area :address, :rows => 3, :cols => 40 %>
      </div>

    
      <div>
        <%= form.label :email, "E-Mail:" %>
        <%= form.text_field :email, :size => 40 %>
      </div>

    
      <div>
        <%= form.label :pay_type, "Pay with:" %>
        <%=
          form.select :pay_type,
                       Order::PAYMENT_TYPES, 
                      :prompt => "Select a payment method"
        %>
      </div>
    
      <%= submit_tag "Place Order", :class => "submit" %>
    </fieldset>
  <% end %>  
</div>
edit app/models/order.rb
class Order < ActiveRecord::Base
  PAYMENT_TYPES = [
    #  Displayed       stored in db
    [ "Check",          "check" ],
    [ "Credit card",    "cc" ],
    [ "Purchase order", "po" ]
  ]

    
  # ...
edit public/stylesheets/depot.css
/* Styles for order form */
 
.depot-form fieldset {
  background: #efe;
}
 
.depot-form legend {
  color: #dfd;
  background: #141;
  font-family: sans-serif;
  padding: 0.2em 1em;
}
 
.depot-form label {
  width: 5em;
  float: left;
  text-align: right;
  padding-top: 0.2em;
  margin-right: 0.1em;
  display: block;
}
 
.depot-form select, .depot-form textarea, .depot-form input {
  margin-left: 0.5em;
}
 
.depot-form .submit {
  margin-left: 4em;
}
 
.depot-form div {
  margin: 0.5em 0;
}
get /store/checkout
Your Cart
Pragmatic Version Control $28.50
Total $28.50
Home
Questions
News
Contact
Please Enter Your Details
get /store/save_order

Unknown action

No action responded to save_order. Actions: add_to_cart, checkout, empty_cart, and index

edit app/models/order.rb
class Order < ActiveRecord::Base
  PAYMENT_TYPES = [
    #  Displayed       stored in db
    [ "Check",          "check" ],
    [ "Credit card",    "cc" ],
    [ "Purchase order", "po" ]
  ]
 
  validates_presence_of :name, :address, :email, :pay_type
  validates_inclusion_of :pay_type, :in => 
    PAYMENT_TYPES.map {|disp, value| value}
 
  # ...
edit app/controllers/store_controller.rb
  def save_order
    @cart = find_cart
    @order = Order.new(params[:order]) # <label id="code.p.new.order"/>
    @order.add_line_items_from_cart(@cart) # <label id="code.p.append.li"/>
    if @order.save                     # <label id="code.p.save"/>
      session[:cart] = nil
      redirect_to_index("Thank you for your order")
    else
      render :action => 'checkout'
    end
  end
edit app/models/order.rb
class Order < ActiveRecord::Base
  PAYMENT_TYPES = [
    #  Displayed       stored in db
    [ "Check",          "check" ],
    [ "Credit card",    "cc" ],
    [ "Purchase order", "po" ]
  ]
 
  # ...
  validates_presence_of :name, :address, :email, :pay_type
  validates_inclusion_of :pay_type, :in => 
    PAYMENT_TYPES.map {|disp, value| value}
 
  # ...
 
 
  has_many :line_items
 
  def add_line_items_from_cart(cart)
    cart.items.each do |item|
      li = LineItem.from_cart_item(item)
      line_items << li
    end
  end
end
edit app/models/line_item.rb
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
 
  def self.from_cart_item(cart_item)
    li = self.new
    li.product     = cart_item.product
    li.quantity    = cart_item.quantity
    li.total_price = cart_item.price
    li
  end
 
end
sqlite3> select * from orders
sqlite3> select * from line_items
get /store/save_order
Your Cart
Pragmatic Version Control $28.50
Total $28.50
Home
Questions
News
Contact

5 errors prohibited this order from being saved

There were problems with the following fields:

  • Address can't be blank
  • Name can't be blank
  • Pay type can't be blank
  • Pay type is not included in the list
  • Email can't be blank
Please Enter Your Details
get /store/checkout
Your Cart
Pragmatic Version Control $28.50
Total $28.50
Home
Questions
News
Contact
Please Enter Your Details
post /store/save_order
  • order[pay_type] => check
  • order[address] => 123 Main St
  • order[email] => customer@pragprog.com
  • order[name] => Dave Thomas
You are being redirected.
get http://127.0.0.1:3000/store
Home
Questions
News
Contact
Thank you for your order

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
sqlite3> select * from orders
        id = 1
      name = Dave Thomas
   address = 123 Main St
     email = customer@pragprog.com
  pay_type = check
created_at = 2009-05-15 18:04:27.374846
updated_at = 2009-05-15 18:04:27.374846
sqlite3> select * from line_items
         id = 1
 product_id = 3
   order_id = 1
   quantity = 1
total_price = 28.5
 created_at = 2009-05-15 18:04:27.380043
 updated_at = 2009-05-15 18:04:27.380043
edit app/views/store/add_to_cart.js.rjs
page.select("div#notice").each { |div| div.hide }
 
page.replace_html("cart", :partial => "cart", :object => @cart)
 
page[:cart].visual_effect :blind_down if @cart.total_items == 1
 
page[:current_item].visual_effect :highlight,
                                  :startcolor => "#88ff88",
                                  :endcolor => "#114411"

11.1 Iteration F1: Adding Users

ruby script/generate scaffold user name:string hashed_password:string salt:string
      exists  app/models/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/users
      exists  app/views/layouts/
      exists  test/functional/
      exists  test/unit/
      exists  test/unit/helpers/
      exists  public/stylesheets/
      create  app/views/users/index.html.erb
      create  app/views/users/show.html.erb
      create  app/views/users/new.html.erb
      create  app/views/users/edit.html.erb
      create  app/views/layouts/users.html.erb
   identical  public/stylesheets/scaffold.css
      create  app/controllers/users_controller.rb
      create  test/functional/users_controller_test.rb
      create  app/helpers/users_helper.rb
      create  test/unit/helpers/users_helper_test.rb
       route  map.resources :users
  dependency  model
      exists    app/models/
      exists    test/unit/
      exists    test/fixtures/
      create    app/models/user.rb
      create    test/unit/user_test.rb
      create    test/fixtures/users.yml
      exists    db/migrate
      create    db/migrate/20090515180430_create_users.rb

restart

cat db/migrate/20090515180430_create_users.rb
class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :name
      t.string :hashed_password
      t.string :salt
 
      t.timestamps
    end
  end
 
  def self.down
    drop_table :users
  end
end
rake db:migrate
mv 20090515180430_create_users.rb 20080601000007_create_users.rb
(in /home/rubys/git/awdwr/work/depot)
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0035s
==  CreateUsers: migrated (0.0037s) ===========================================
 
edit app/models/user.rb
require 'digest/sha1'

    
class User < ActiveRecord::Base
  
  validates_presence_of     :name
  validates_uniqueness_of   :name
 
  attr_accessor :password_confirmation
  validates_confirmation_of :password

    
  validate :password_non_blank
  
  def self.authenticate(name, password)
    user = self.find_by_name(name)
    if user
      expected_password = encrypted_password(password, user.salt)
      if user.hashed_password != expected_password
        user = nil
      end
    end
    user
  end
  
  # 'password' is a virtual attribute
  def password
    @password
  end
  
  def password=(pwd)
    @password = pwd
    return if pwd.blank?
    create_new_salt
    self.hashed_password = User.encrypted_password(self.password, self.salt)
  end
  
private

    
  def password_non_blank
    errors.add(:password, "Missing password") if hashed_password.blank?
  end
  
  def create_new_salt
    self.salt = self.object_id.to_s + rand.to_s
  end
  
  def self.encrypted_password(password, salt)
    string_to_hash = password + "wibble" + salt
    Digest::SHA1.hexdigest(string_to_hash)
  end
end
edit app/controllers/users_controller.rb
class UsersController < ApplicationController
  # GET /users
  # GET /users.xml
  def index
    @users = User.all(:order => :name)
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
    end
  end
 
  # GET /users/1
  # GET /users/1.xml
  def show
    @user = User.find(params[:id])
 
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @user }
    end
  end
 
  # GET /users/new
  # GET /users/new.xml
  def new
    @user = User.new
 
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @user }
    end
  end
 
  # GET /users/1/edit
  def edit
    @user = User.find(params[:id])
  end
 
  # POST /users
  # POST /users.xml
  def create
    @user = User.new(params[:user])
 
    respond_to do |format|
      if @user.save
        flash[:notice] = "User #{@user.name} was successfully created."
        format.html { redirect_to(:action=>'index') }
        format.xml  { render :xml => @user, :status => :created,
                             :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors,
                             :status => :unprocessable_entity }
      end
    end
  end
 
  # PUT /users/1
  # PUT /users/1.xml
  def update
    @user = User.find(params[:id])
 
    respond_to do |format|
      if @user.update_attributes(params[:user])
        flash[:notice] = "User #{@user.name} was successfully updated."
        format.html { redirect_to(:action=>'index') }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @user.errors,
                             :status => :unprocessable_entity }
      end
    end
  end
 
  # DELETE /users/1
  # DELETE /users/1.xml
  def destroy
    @user = User.find(params[:id])
    @user.destroy
 
    respond_to do |format|
      format.html { redirect_to(users_url) }
      format.xml  { head :ok }
    end
  end
end
edit app/views/users/index.html.erb
<h1>Listing users</h1>
 
<table>
  <tr>
    <th>Name</th>
  </tr>
 
<% @users.each do |user| %>
  <tr>
    <td><%=h user.name %></td>
    <td><%= link_to 'Show', user %></td>
    <td><%= link_to 'Edit', edit_user_path(user) %></td>
    <td><%= link_to 'Destroy', user, :confirm => 'Are you sure?',
                                        :method => :delete %></td>
  </tr>
<% end %>
</table>
 
<br />
 
<%= link_to 'New user', new_user_path %>
edit app/views/users/new.html.erb
<div class="depot-form">
 
<% form_for(@user) do |f| %>
  <%= f.error_messages %>
 
  <fieldset>
  <legend>Enter User Details</legend>
 
  <div>
    <%= f.label :name %>:
    <%= f.text_field :name, :size => 40 %>
  </div>
 
  <div>
    <%= f.label :password, 'Password' %>:
    <%= f.password_field :password, :size => 40 %>
  </div>
 
  <div>
    <%= f.label :password_confirmation, 'Confirm' %>:
    <%= f.password_field :password_confirmation, :size => 40 %>
  </div>
 
  <div>
    <%= f.submit "Add User", :class => "submit" %>
  </div>
 
  </fieldset>
<% end %>
 
</div>
edit app/views/layouts/users.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Users: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold', 'depot' %>
</head>
get /users

Listing users

Name

New user
get /users/new

Enter User Details
:
:
:
post /users
  • user[password_confirmation] => secret
  • user[name] => dave
  • user[password] => secret
You are being redirected.
get http://127.0.0.1:3000/users

User dave was successfully created.

Listing users

Name
dave Show Edit Destroy

New user
sqlite3> select * from users
             id = 1
           name = dave
hashed_password = 101c265c0ffb132b32c8ef8bb9e738c42eee2107
           salt = -6154718780.432159014901808
     created_at = 2009-05-15 18:04:42.678521
     updated_at = 2009-05-15 18:04:42.678521

11.2 Iteration F2: Logging in

ruby script/generate controller admin login logout index
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/admin
      exists  test/functional/
      exists  test/unit/helpers/
      create  app/controllers/admin_controller.rb
      create  test/functional/admin_controller_test.rb
      create  app/helpers/admin_helper.rb
      create  test/unit/helpers/admin_helper_test.rb
      create  app/views/admin/login.html.erb
      create  app/views/admin/logout.html.erb
      create  app/views/admin/index.html.erb

restart

edit app/controllers/admin_controller.rb
class AdminController < ApplicationController
 
  # just display the form and wait for user to
  # enter a name and password
  def login
    if request.post?
      user = User.authenticate(params[:name], params[:password])
      if user
        session[:user_id] = user.id
        redirect_to(:action => "index")
      else
        flash.now[:notice] = "Invalid user/password combination"
      end
    end
  end
 
  def logout
    session[:user_id] = nil
    flash[:notice] = "Logged out"
    redirect_to(:action => "login")
  end
 
  def index
    @total_orders = Order.count
  end
end
edit app/views/admin/login.html.erb
<div class="depot-form">
  <% form_tag do %>
    <fieldset>
      <legend>Please Log In</legend>

    
      <div>
        <label for="name">Name:</label>
        <%= text_field_tag :name, params[:name] %>
      </div>

    
      <div>
        <label for="password">Password:</label>
        <%= password_field_tag :password, params[:password] %>
      </div>
  
      <div>
        <%= submit_tag "Login" %>
      </div>
    </fieldset>
  <% end %>
</div>
edit app/views/admin/index.html.erb
<h1>Welcome</h1>

    
It's <%= Time.now %>
We have <%= pluralize(@total_orders, "order") %>.
get /admin/login
Please Log In
post /admin/login
  • name => dave
  • password => secret
You are being redirected.
get http://127.0.0.1:3000/admin

Welcome

It's Fri May 15 14:04:54 -0400 2009 We have 1 order.

11.3 Iteration F3: Limiting Access

edit app/controllers/application_controller.rb
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
 
class ApplicationController < ActionController::Base
  before_filter :authorize, :except => :login
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
 
  # Scrub sensitive parameters from your log
  # filter_parameter_logging :password
    
protected
  def authorize
    unless User.find_by_id(session[:user_id])
      flash[:notice] = "Please log in"
      redirect_to :controller => 'admin', :action => 'login'
    end
  end
end
edit app/controllers/store_controller.rb
class StoreController < ApplicationController
  def index
    @products = Product.find_products_for_sale
    @cart = find_cart
  end
 
 
  def add_to_cart
    product = Product.find(params[:id])
    @cart = find_cart
    @current_item = @cart.add_product(product)
    respond_to do |format|
      format.js if request.xhr?
      format.html {redirect_to_index}
    end
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    redirect_to_index("Invalid product")
  end
 
  def checkout
    @cart = find_cart
    if @cart.items.empty?
      redirect_to_index("Your cart is empty")
    else
      @order = Order.new
    end
  end
 
  def save_order
    @cart = find_cart
    @order = Order.new(params[:order])
    @order.add_line_items_from_cart(@cart)
    if @order.save
      session[:cart] = nil
      redirect_to_index("Thank you for your order")
    else
      render :action => 'checkout'
    end
  end
 
  def empty_cart
    session[:cart] = nil
    redirect_to_index
  end
 
private
 
  def redirect_to_index(msg = nil)
    flash[:notice] = msg if msg
    redirect_to :action => 'index'
  end
 
  def find_cart
    session[:cart] ||= Cart.new
  end
 
end
edit app/controllers/store_controller.rb
class StoreController < ApplicationController
  #...
protected
 
  def authorize
  end
end
rake db:sessions:clear
(in /home/rubys/git/awdwr/work/depot)
get /admin/logout
You are being redirected.
get http://127.0.0.1:3000/admin/login
Please Log In
get /store
Home
Questions
News
Contact
Please log in

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
get /products
You are being redirected.
get http://127.0.0.1:3000/admin/login
Please Log In
get /admin/login
Please Log In
post /admin/login
  • name => dave
  • password => secret
You are being redirected.
get http://127.0.0.1:3000/admin

Welcome

It's Fri May 15 14:04:59 -0400 2009 We have 1 order.
get /products

Please log in

Listing products

Auto
Pragmatic Project Automation
Pragmatic Project Automation shows you how to improve the con...
Show
Edit
Destroy
Svn
Pragmatic Version Control
This book is a recipe-based approach to using Subversion that will ...
Show
Edit
Destroy
Utc
Pragmatic Unit Testing (C#)
Pragmatic programmers use feedback to drive their development and ...
Show
Edit
Destroy

New product

11.4 Iteration F4: Adding a Sidebar, More Administration

edit app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  layout "store"
  #...
get /admin
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Action Controller: Exception caught</title>
  <style>
    body { background-color: #fff; color: #333; }

      
    body, p, ol, ul, td {
      font-family: verdana, arial, helvetica, sans-serif;
      font-size:   13px;
      line-height: 18px;
    }

      
    pre {
      background-color: #eee;
      padding: 10px;
      font-size: 11px;
    }

      
    a { color: #000; }
    a:visited { color: #666; }
    a:hover { color: #fff; background-color:#000; }
  </style>
</head>
<body>

      
<h1>
  NoMethodError in
  Admin#index
</h1>

      
<p>
  Showing <i>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb</i> where line <b>#24</b> raised:
  <pre><code>You have a nil object when you didn't expect it!
The error occurred while evaluating nil.items</code></pre>
</p>

      
<p>Extracted source (around line <b>#24</b>):
<pre><code>21:     &lt;div id=&quot;side&quot;&gt;
22:       &lt;!-- START_HIGHLIGHT --&gt;
23:       &lt;!-- START:hidden_div --&gt;
24:       &lt;% hidden_div_if(@cart.items.empty?, :id =&gt; &quot;cart&quot;) do %&gt;
25:         &lt;%= render(:partial =&gt; &quot;cart&quot;, :object =&gt; @cart) %&gt;
26:       &lt;% end %&gt;
27:     &lt;!-- END:hidden_div --&gt;
</code></pre></p>

      
<p></p>

      

      

      

      
<p><code>RAILS_ROOT: /home/rubys/git/awdwr/work/depot</code></p>

      
<div id="traces">
  
    
    <a href="#" onclick="document.getElementById('Framework-Trace').style.display='none';document.getElementById('Full-Trace').style.display='none';document.getElementById('Application-Trace').style.display='block';; return false;">Application Trace</a> |
  
    
    <a href="#" onclick="document.getElementById('Application-Trace').style.display='none';document.getElementById('Full-Trace').style.display='none';document.getElementById('Framework-Trace').style.display='block';; return false;">Framework Trace</a> |
  
    
    <a href="#" onclick="document.getElementById('Application-Trace').style.display='none';document.getElementById('Framework-Trace').style.display='none';document.getElementById('Full-Trace').style.display='block';; return false;">Full Trace</a> 
  

      
  
    <div id="Application-Trace" style="display: block;">
      <pre><code>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb:24:in `_render_template_200425620__616596408_0'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:69:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/base.rb:261:in `with_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:65:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:58:in `_render_content_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:117:in `_render_template_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:391:in `render_for_parts'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:278:in `render_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:865:in `default_render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:875:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
makedepot.rb:2300:in `restart_server'
makedepot.rb:999
makedepot.rb:2374:in `call'
makedepot.rb:2374
makedepot.rb:2371:in `each'
makedepot.rb:2371
makedepot.rb:2334
makedepot.rb:2307</code></pre>
    </div>
  
    <div id="Framework-Trace" style="display: none;">
      <pre><code>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb:24:in `_render_template_200425620__616596408_0'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:69:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/base.rb:261:in `with_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:65:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:58:in `_render_content_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:117:in `_render_template_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:391:in `render_for_parts'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:278:in `render_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:865:in `default_render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:875:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'</code></pre>
    </div>
  
    <div id="Full-Trace" style="display: none;">
      <pre><code>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb:24:in `_render_template_200425620__616596408_0'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:69:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/base.rb:261:in `with_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:65:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:58:in `_render_content_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:117:in `_render_template_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:391:in `render_for_parts'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:278:in `render_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:865:in `default_render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:875:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
makedepot.rb:2300:in `restart_server'
makedepot.rb:999
makedepot.rb:2374:in `call'
makedepot.rb:2374
makedepot.rb:2371:in `each'
makedepot.rb:2371
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
makedepot.rb:2334
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
makedepot.rb:2307</code></pre>
    </div>
  
</div>

      

      

      

      

      

      

      
<h2 style="margin-top: 30px">Request</h2>
<p><b>Parameters</b>: <pre>None</pre></p>

      
<p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p>
<div id="session_dump" style="display:none"><pre class='debug_dump'>--- 
</pre></div>

      

      
<h2 style="margin-top: 30px">Response</h2>
<p><b>Headers</b>: <pre>None</pre></p>

      

      

      
</body>
</html>
get /users
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Action Controller: Exception caught</title>
  <style>
    body { background-color: #fff; color: #333; }

      
    body, p, ol, ul, td {
      font-family: verdana, arial, helvetica, sans-serif;
      font-size:   13px;
      line-height: 18px;
    }

      
    pre {
      background-color: #eee;
      padding: 10px;
      font-size: 11px;
    }

      
    a { color: #000; }
    a:visited { color: #666; }
    a:hover { color: #fff; background-color:#000; }
  </style>
</head>
<body>

      
<h1>
  NoMethodError in
  Users#index
</h1>

      
<p>
  Showing <i>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb</i> where line <b>#24</b> raised:
  <pre><code>You have a nil object when you didn't expect it!
The error occurred while evaluating nil.items</code></pre>
</p>

      
<p>Extracted source (around line <b>#24</b>):
<pre><code>21:     &lt;div id=&quot;side&quot;&gt;
22:       &lt;!-- START_HIGHLIGHT --&gt;
23:       &lt;!-- START:hidden_div --&gt;
24:       &lt;% hidden_div_if(@cart.items.empty?, :id =&gt; &quot;cart&quot;) do %&gt;
25:         &lt;%= render(:partial =&gt; &quot;cart&quot;, :object =&gt; @cart) %&gt;
26:       &lt;% end %&gt;
27:     &lt;!-- END:hidden_div --&gt;
</code></pre></p>

      
<p></p>

      

      

      

      
<p><code>RAILS_ROOT: /home/rubys/git/awdwr/work/depot</code></p>

      
<div id="traces">
  
    
    <a href="#" onclick="document.getElementById('Framework-Trace').style.display='none';document.getElementById('Full-Trace').style.display='none';document.getElementById('Application-Trace').style.display='block';; return false;">Application Trace</a> |
  
    
    <a href="#" onclick="document.getElementById('Application-Trace').style.display='none';document.getElementById('Full-Trace').style.display='none';document.getElementById('Framework-Trace').style.display='block';; return false;">Framework Trace</a> |
  
    
    <a href="#" onclick="document.getElementById('Application-Trace').style.display='none';document.getElementById('Framework-Trace').style.display='none';document.getElementById('Full-Trace').style.display='block';; return false;">Full Trace</a> 
  

      
  
    <div id="Application-Trace" style="display: block;">
      <pre><code>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb:24:in `_render_template_200425620__616239488_0'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:69:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/base.rb:261:in `with_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:65:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:58:in `_render_content_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:117:in `_render_template_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:391:in `render_for_parts'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:400:in `render_for_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:242:in `render_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:132:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:132:in `custom'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:176:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:176:in `respond'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:170:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:170:in `respond'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:107:in `respond_to'
/home/rubys/git/awdwr/work/depot/app/controllers/users_controller.rb:9:in `index'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
makedepot.rb:2300:in `restart_server'
makedepot.rb:999
makedepot.rb:2374:in `call'
makedepot.rb:2374
makedepot.rb:2371:in `each'
makedepot.rb:2371
makedepot.rb:2334
makedepot.rb:2307</code></pre>
    </div>
  
    <div id="Framework-Trace" style="display: none;">
      <pre><code>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb:24:in `_render_template_200425620__616239488_0'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:69:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/base.rb:261:in `with_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:65:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:58:in `_render_content_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:117:in `_render_template_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:391:in `render_for_parts'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:400:in `render_for_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:242:in `render_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:132:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:132:in `custom'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:176:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:176:in `respond'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:170:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:170:in `respond'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:107:in `respond_to'
/home/rubys/git/awdwr/work/depot/app/controllers/users_controller.rb:9:in `index'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'</code></pre>
    </div>
  
    <div id="Full-Trace" style="display: none;">
      <pre><code>/home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb:24:in `_render_template_200425620__616239488_0'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/template/template.rb:21:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:69:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/base.rb:261:in `with_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:65:in `_render_template'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:58:in `_render_content_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_view/render/rendering.rb:117:in `_render_template_with_layout'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:391:in `render_for_parts'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:400:in `render_for_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/render.rb:242:in `render_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:51:in `render'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:132:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:132:in `custom'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:176:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:176:in `respond'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:170:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:170:in `respond'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/mime_responds.rb:107:in `respond_to'
/home/rubys/git/awdwr/work/depot/app/controllers/users_controller.rb:9:in `index'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:870:in `perform_action_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:617:in `call_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:610:in `perform_action_without_benchmark'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/benchmarking.rb:68:in `perform_action_without_rescue'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/rescue.rb:45:in `perform_action_without_flash'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/flash.rb:141:in `perform_action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `send'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:531:in `process_without_filters'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/chained/filters.rb:606:in `process'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:375:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/base/base.rb:383:in `action'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:433:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/head.rb:9:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/methodoverride.rb:24:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/params_parser.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb:144:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/rescue.rb:8:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/show_exceptions.rb:44:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/middleware/failsafe.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `synchronize'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/lock.rb:11:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/dispatch/dispatcher.rb:64:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:46:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `each'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/urlmap.rb:40:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/content_length.rb:13:in `call'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:46:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/vendor/rack-1.1.pre/rack/handler/webrick.rb:13:in `run'
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib/commands/server.rb:110
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
makedepot.rb:2300:in `restart_server'
makedepot.rb:999
makedepot.rb:2374:in `call'
makedepot.rb:2374
makedepot.rb:2371:in `each'
makedepot.rb:2371
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
makedepot.rb:2334
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `call'
/usr/lib/ruby/1.8/builder/xmlbase.rb:133:in `_nested_structures'
/usr/lib/ruby/1.8/builder/xmlbase.rb:57:in `method_missing'
makedepot.rb:2307</code></pre>
    </div>
  
</div>

      

      

      

      

      

      

      
<h2 style="margin-top: 30px">Request</h2>
<p><b>Parameters</b>: <pre>None</pre></p>

      
<p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p>
<div id="session_dump" style="display:none"><pre class='debug_dump'>--- 
</pre></div>

      

      
<h2 style="margin-top: 30px">Response</h2>
<p><b>Headers</b>: <pre>None</pre></p>

      

      

      
</body>
</html>
edit app/views/layouts/store.html.erb
      <% if @cart %>
        <% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
          <%= render(:partial => "cart", :object => @cart) %>
        <% end %>
      <% end %>
get /admin

Welcome

It's Fri May 15 14:05:02 -0400 2009 We have 1 order.
get /users
rm app/views/layouts/products.html.erb
rm app/views/layouts/users.html.erb
rm app/views/layouts/orders.html.erb
get /users
edit app/models/user.rb
require 'digest/sha1'
 
class User < ActiveRecord::Base
  
  validates_presence_of     :name
  validates_uniqueness_of   :name
 
  attr_accessor :password_confirmation
  validates_confirmation_of :password
 
  validate :password_non_blank
  
  def self.authenticate(name, password)
    user = self.find_by_name(name)
    if user
      expected_password = encrypted_password(password, user.salt)
      if user.hashed_password != expected_password
        user = nil
      end
    end
    user
  end
  
  # 'password' is a virtual attribute
  def password
    @password
  end
  
  def password=(pwd)
    @password = pwd
    return if pwd.blank?
    create_new_salt
    self.hashed_password = User.encrypted_password(self.password, self.salt)
  end
  
  def after_destroy
    if User.count.zero?
      raise "Can't delete last user"
    end
  end     
 
private
 
  def password_non_blank
    errors.add(:password, "Missing password") if hashed_password.blank?
  end
  
  def create_new_salt
    self.salt = self.object_id.to_s + rand.to_s
  end
  
  def self.encrypted_password(password, salt)
    string_to_hash = password + "wibble" + salt
    Digest::SHA1.hexdigest(string_to_hash)
  end
end
edit app/controllers/users_controller.rb
class UsersController < ApplicationController
  # GET /users
  # GET /users.xml
  def index
    @users = User.all(:order => :name)
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
    end
  end
 
  # GET /users/1
  # GET /users/1.xml
  def show
    @user = User.find(params[:id])
 
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @user }
    end
  end
 
  # GET /users/new
  # GET /users/new.xml
  def new
    @user = User.new
 
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @user }
    end
  end
 
  # GET /users/1/edit
  def edit
    @user = User.find(params[:id])
  end
 
  # POST /users
  # POST /users.xml
  def create
    @user = User.new(params[:user])
 
    respond_to do |format|
      if @user.save
        flash[:notice] = "User #{@user.name} was successfully created."
        format.html { redirect_to(:action=>'index') }
        format.xml  { render :xml => @user, :status => :created,
                             :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors,
                             :status => :unprocessable_entity }
      end
    end
  end
 
  # PUT /users/1
  # PUT /users/1.xml
  def update
    @user = User.find(params[:id])
 
    respond_to do |format|
      if @user.update_attributes(params[:user])
        flash[:notice] = "User #{@user.name} was successfully updated."
        format.html { redirect_to(:action=>'index') }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @user.errors,
                             :status => :unprocessable_entity }
      end
    end
  end
 
  # DELETE /users/1
  # DELETE /users/1.xml
  def destroy
    @user = User.find(params[:id])
    begin
      @user.destroy
      flash[:notice] = "User #{@user.name} deleted"
    rescue Exception => e
      flash[:notice] = e.message
    end
 
    respond_to do |format|
      format.html { redirect_to(users_url) }
      format.xml  { head :ok }
    end
  end
end
edit app/controllers/store_controller.rb
      def find_cart
        @cart = (session[:cart] ||= Cart.new)
      end
edit app/controllers/store_controller.rb
      before_filter :find_cart, :except => :empty_cart
echo "Product.new" | ruby script/console
>> Product.new
=> #<Product id: nil, title: nil, description: nil, image_url: nil, created_at: nil, updated_at: nil, price: #<BigDecimal:b74bea58,'0.0',4(8)>>
>> 

12.1 Generating the XML Feed

edit app/models/product.rb
class Product < ActiveRecord::Base
  has_many :orders, :through => :line_items
  has_many :line_items
  # ...
ruby script/generate controller info who_bought
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/info
      exists  test/functional/
      exists  test/unit/helpers/
      create  app/controllers/info_controller.rb
      create  test/functional/info_controller_test.rb
      create  app/helpers/info_helper.rb
      create  test/unit/helpers/info_helper_test.rb
      create  app/views/info/who_bought.html.erb
edit app/controllers/info_controller.rb
class InfoController < ApplicationController
  def who_bought
    @product = Product.find(params[:id])
    @orders  = @product.orders
    respond_to do |format|
      format.xml { render :layout => false }
    end
  end
 
protected
 
  def authorize
  end
end
edit app/views/info/who_bought.xml.builder
xml.order_list(:for_product => @product.title) do
  for o in @orders
    xml.order do
      xml.name(o.name)
      xml.email(o.email)
    end
  end
end
curl --silent http://localhost:3000/info/who_bought/3
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Action Controller: Exception caught</title>
  <style>
    body { background-color: #fff; color: #333; }
 
    body, p, ol, ul, td {
      font-family: verdana, arial, helvetica, sans-serif;
      font-size:   13px;
      line-height: 18px;
    }
 
    pre {
      background-color: #eee;
      padding: 10px;
      font-size: 11px;
    }
 
    a { color: #000; }
    a:visited { color: #666; }
    a:hover { color: #fff; background-color:#000; }
  </style>
</head>
<body>
 
<h1>Routing Error</h1>
<p><pre>No route matches &quot;/info/who_bought/3&quot; with {:method=&gt;:get}</pre></p>
 
 
 
</body>
</html>

restart

curl --silent http://localhost:3000/info/who_bought/3
<h1>Info#who_bought</h1>
<p>Find me in app/views/info/who_bought.html.erb</p>
sqlite3> select * from products
         id = 2
      title = Pragmatic Project Automation
description = <p>
       <em>Pragmatic Project Automation</em> shows you how to improve the 
       consistency and repeatability of your project's procedures using 
       automation to reduce risk and errors.
      </p>
      <p>
        Simply put, we're going to put this thing called a computer to work 
        for you doing the mundane (but important) project stuff. That means 
        you'll have more time and energy to do the really 
        exciting---and difficult---stuff, like writing quality code.
      </p>
  image_url = /images/auto.jpg
 created_at = 2009-05-15 18:03:23.779521
 updated_at = 2009-05-15 18:03:23.779521
      price = 29.95
 
         id = 3
      title = Pragmatic Version Control
description = <p>
         This book is a recipe-based approach to using Subversion that will 
         get you up and running quickly---and correctly. All projects need
         version control: it's a foundational piece of any project's 
         infrastructure. Yet half of all project teams in the U.S. don't use
         any version control at all. Many others don't use it well, and end 
         up experiencing time-consuming problems.
      </p>
  image_url = /images/svn.jpg
 created_at = 2009-05-15 18:03:23.785702
 updated_at = 2009-05-15 18:03:23.785702
      price = 28.5
 
         id = 4
      title = Pragmatic Unit Testing (C#)
description = <p>
        Pragmatic programmers use feedback to drive their development and 
        personal processes. The most valuable feedback you can get while 
        coding comes from unit testing.
      </p>
      <p>
        Without good tests in place, coding can become a frustrating game of 
        "whack-a-mole." That's the carnival game where the player strikes at a 
        mechanical mole; it retreats and another mole pops up on the opposite side 
        of the field. The moles pop up and down so fast that you end up flailing 
        your mallet helplessly as the moles continue to pop up where you least 
        expect them.
      </p>
  image_url = /images/utc.jpg
 created_at = 2009-05-15 18:03:23.790964
 updated_at = 2009-05-15 18:03:23.790964
      price = 27.75
sqlite3> select * from line_items
         id = 1
 product_id = 3
   order_id = 1
   quantity = 1
total_price = 28.5
 created_at = 2009-05-15 18:04:27.380043
 updated_at = 2009-05-15 18:04:27.380043
curl --silent http://localhost:3000/info/who_bought/3
<h1>Info#who_bought</h1>
<p>Find me in app/views/info/who_bought.html.erb</p>
edit app/views/info/who_bought.html.erb
<h3>People Who Bought <%= @product.title %></h3>

    
<ul>
  <% for order in @orders  -%>
    <li>
        <%= mail_to order.email, order.name %>
    </li>
  <%  end -%>
</ul>
edit app/controllers/info_controller.rb
class InfoController < ApplicationController
  def who_bought
    @product = Product.find(params[:id])
    @orders  = @product.orders
    respond_to do |format|
      format.html
      format.xml { render :layout => false }
    end
  end
 
protected
 
  def authorize
  end
end
curl --silent -H "Accept: text/html" http://localhost:3000/info/who_bought/3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- START:jit -->
<html>
<head>
  <title>Pragprog Books Online Store</title>
<!-- START:stylesheet -->
  <link href="/stylesheets/depot.css?1242410663" media="all" rel="stylesheet" type="text/css" />
<!-- END:stylesheet -->
  <script src="/javascripts/prototype.js?1242410564" type="text/javascript"></script>
<script src="/javascripts/effects.js?1242410564" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1242410564" type="text/javascript"></script>
<script src="/javascripts/controls.js?1242410564" type="text/javascript"></script>
<script src="/javascripts/application.js?1242410564" type="text/javascript"></script>
</head>
<!-- END:jit -->
<body id="store">
  <div id="banner">
    <img alt="Logo" src="/images/logo.png?1242410603" />
    Pragmatic Bookshelf
  </div>
  <div id="columns">
    <div id="side">
      <!-- START:hidden_div -->
<!-- START_HIGHLIGHT -->
 
<!-- END_HIGHLIGHT -->
    <!-- END:hidden_div -->
 
      <a href="http://www....">Home</a><br />
      <a href="http://www..../faq">Questions</a><br />
      <a href="http://www..../news">News</a><br />
      <a href="http://www..../contact">Contact</a><br />
 
      <!-- START_HIGHLIGHT -->
 
      <!-- END_HIGHLIGHT -->
    </div>
    <div id="main">
      <!-- START:flash -->
            <!-- END:flash -->
 
      <h3>People Who Bought Pragmatic Version Control</h3>
 
<ul>
      <li>
        <a href="mailto:customer@pragprog.com">Dave Thomas</a>
    </li>
  </ul>
 
    </div>
  </div>
</body>
</html>
curl --silent -H "Accept: application/xml" http://localhost:3000/info/who_bought/3
<order_list for_product="Pragmatic Version Control">
  <order>
    <name>Dave Thomas</name>
    <email>customer@pragprog.com</email>
  </order>
</order_list>
cp app/controllers/info_controller.rb app/controllers/info_controller.save
edit app/controllers/info_controller.rb
class InfoController < ApplicationController
  def who_bought
    @product = Product.find(params[:id])
    @orders  = @product.orders
    respond_to do |format|
      format.html
      format.xml { render :layout => false ,
                   :xml => @product.to_xml(:include => :orders) }
    end
  end
 
protected
 
  def authorize
  end
end
curl --silent http://localhost:3000/info/who_bought/3.xml
<?xml version="1.0" encoding="UTF-8"?>
<product>
  <created-at type="datetime">2009-05-15T18:03:23Z</created-at>
  <description>&lt;p&gt;
         This book is a recipe-based approach to using Subversion that will 
         get you up and running quickly---and correctly. All projects need
         version control: it's a foundational piece of any project's 
         infrastructure. Yet half of all project teams in the U.S. don't use
         any version control at all. Many others don't use it well, and end 
         up experiencing time-consuming problems.
      &lt;/p&gt;</description>
  <id type="integer">3</id>
  <image-url>/images/svn.jpg</image-url>
  <price type="decimal">28.5</price>
  <title>Pragmatic Version Control</title>
  <updated-at type="datetime">2009-05-15T18:03:23Z</updated-at>
  <orders type="array">
    <order>
      <address>123 Main St</address>
      <created-at type="datetime">2009-05-15T18:04:27Z</created-at>
      <email>customer@pragprog.com</email>
      <id type="integer">1</id>
      <name>Dave Thomas</name>
      <pay-type>check</pay-type>
      <updated-at type="datetime">2009-05-15T18:04:27Z</updated-at>
    </order>
  </orders>
</product>
edit app/views/info/who_bought.atom.builder
atom_feed do |feed|
  feed.title "Who bought #{@product.title}"
  feed.updated @orders.first.created_at

    
  for order in @orders
    feed.entry(order) do |entry|
      entry.title "Order #{order.id}"
      entry.summary :type => 'xhtml' do |xhtml|
        xhtml.p "Shipped to #{order.address}"

    
        xhtml.table do
          xhtml.tr do
            xhtml.th 'Product'
            xhtml.th 'Quantity'
            xhtml.th 'Total Price'
          end
          for item in order.line_items
            xhtml.tr do
              xhtml.td item.product.title
              xhtml.td item.quantity
              xhtml.td number_to_currency item.total_price
            end
          end
          xhtml.tr do
            xhtml.th 'total', :colspan => 2
            xhtml.th number_to_currency \
              order.line_items.map(&:total_price).sum
          end
        end

    
        xhtml.p "Paid by #{order.pay_type}"
      end
      entry.author do |author|
        entry.name order.name
        entry.email order.email
      end
    end
  end
end
edit app/controllers/info_controller.rb
class InfoController < ApplicationController
  def who_bought
    @product = Product.find(params[:id])
    @orders  = @product.orders
    respond_to do |format|
      format.html
      format.atom { render :layout => false }
      format.xml { render :layout => false ,
                   :xml => @product.to_xml(:include => :orders) }
    end
  end
 
protected
 
  def authorize
  end
end
curl --silent http://localhost:3000/info/who_bought/3.atom
<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:localhost,2005:/info/who_bought/3</id>
  <link type="text/html" href="http://localhost:3000" rel="alternate"/>
  <link type="application/atom+xml" href="http://localhost:3000/info/who_bought/3.atom" rel="self"/>
  <title>Who bought Pragmatic Version Control</title>
  <updated>2009-05-15T18:04:27Z</updated>
  <entry>
    <id>tag:localhost,2005:Order/1</id>
    <published>2009-05-15T18:04:27Z</published>
    <updated>2009-05-15T18:04:27Z</updated>
    <link type="text/html" href="http://localhost:3000/orders/1" rel="alternate"/>
    <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>Pragmatic Version Control</td>
            <td>1</td>
            <td>$28.50</td>
          </tr>
          <tr>
            <th colspan="2">total</th>
            <th>$28.50</th>
          </tr>
        </table>
        <p>Paid by check</p>
      </div>
    </summary>
    <author>
      <name>Dave Thomas</name>
      <email>customer@pragprog.com</email>
    </author>
  </entry>
</feed>
edit app/controllers/info_controller.rb
class InfoController < ApplicationController
  def who_bought
    @product = Product.find(params[:id])
    @orders  = @product.orders
    respond_to do |format|
      format.html
      format.atom { render :layout => false }
      format.xml { render :layout => false ,
                   :xml => @product.to_xml(:include => :orders) }
      format.json { render :layout => false ,
                   :json => @product.to_json(:include => :orders) }
    end
  end
 
protected
 
  def authorize
  end
end
curl --silent -H "Accept: application/json" http://localhost:3000/info/who_bought/3
{"product":{"price":28.5,"created_at":"2009-05-15T18:03:23Z","title":"Pragmatic Version Control","image_url":"/images/svn.jpg","updated_at":"2009-05-15T18:03:23Z","id":3,"orders":[{"name":"Dave Thomas","address":"123 Main St","created_at":"2009-05-15T18:04:27Z","updated_at":"2009-05-15T18:04:27Z","pay_type":"check","id":1,"email":"customer@pragprog.com"}],"description":"<p>\n         This book is a recipe-based approach to using Subversion that will \n         get you up and running quickly---and correctly. All projects need\n         version control: it's a foundational piece of any project's \n         infrastructure. Yet half of all project teams in the U.S. don't use\n         any version control at all. Many others don't use it well, and end \n         up experiencing time-consuming problems.\n      </p>"}}
mv app/controllers/info_controller.save app/controllers/info_controller.rb
rake doc:app
rm -r doc/app

    
                     README_FOR_APP: 
                 products_helper.rb: m
                   orders_helper.rb: m
               line_items_helper.rb: m
              application_helper.rb: m
                    store_helper.rb: m.
                     info_helper.rb: m
                    users_helper.rb: m
                    admin_helper.rb: m
                users_controller.rb: c.......
               orders_controller.rb: c.......
             products_controller.rb: c.......
                store_controller.rb: c........
           line_items_controller.rb: c.......
                 info_controller.rb: c..
                admin_controller.rb: c...
          application_controller.rb: c.
                            cart.rb: c....
                         product.rb: c..
                            user.rb: c.......
                           order.rb: c.
                       cart_item.rb: c....
                       line_item.rb: c.
Generating HTML...
(in /home/rubys/git/awdwr/work/depot)
 
Files:   23
Classes: 14
Modules: 8
Methods: 62
Elapsed: 1.826s
rake stats
(in /home/rubys/git/awdwr/work/depot)
+----------------------+-------+-------+---------+---------+-----+-------+
| Name                 | Lines |   LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Controllers          |   516 |   344 |       8 |      42 |   5 |     6 |
| Helpers              |    23 |    22 |       0 |       1 |   0 |    20 |
| Models               |   229 |   129 |       6 |      19 |   3 |     4 |
| Libraries            |     0 |     0 |       0 |       0 |   0 |     0 |
| Integration tests    |     0 |     0 |       0 |       0 |   0 |     0 |
| Functional tests     |   204 |   162 |       7 |       0 |   0 |     0 |
| Unit tests           |    60 |    45 |      11 |       0 |   0 |     0 |
+----------------------+-------+-------+---------+---------+-----+-------+
| Total                |  1032 |   702 |      32 |      62 |   1 |     9 |
+----------------------+-------+-------+---------+---------+-----+-------+
  Code LOC: 495     Test LOC: 207     Code to Test Ratio: 1:0.4
 

13 Task I: Internationalization

get /store/empty_cart
You are being redirected.
get http://127.0.0.1:3000/store

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
cp /home/rubys/git/awdwr/data/i18n/initializer.rb config/initializers/i18n.rb

restart

edit app/views/layouts/store.html.erb
  <% form_tag '', :method => 'GET', :class => 'locale' do %>
    <%= select_tag 'locale', options_for_select(LANGUAGES, I18n.locale),
      :onchange => 'this.form.submit()' %>
    <%= submit_tag 'submit' %>
    <%= javascript_tag "$$('.locale input').each(Element.hide)" %>
  <% end %>
get /store?locale=en

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
edit app/controllers/application_controller.rb
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
 
class ApplicationController < ActionController::Base
  layout "store"
  #...
  before_filter :authorize, :except => :login
  before_filter :set_locale
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
 
  # Scrub sensitive parameters from your log
  # filter_parameter_logging :password
    
protected
  def authorize
    unless User.find_by_id(session[:user_id])
      flash[:notice] = "Please log in"
      redirect_to :controller => 'admin', :action => 'login'
    end
  end
 
  def set_locale
    session[:locale] = params[:locale] if params[:locale]
    I18n.locale = session[:locale] || I18n.default_locale
 
    locale_path = "#{LOCALES_DIRECTORY}#{I18n.locale}.yml"
 
    unless I18n.load_path.include? locale_path
      I18n.load_path << locale_path
      I18n.backend.send(:init_translations)
    end
 
  rescue Exception => err
    logger.error err
    flash.now[:notice] = "#{I18n.locale} translation not available"
 
    I18n.load_path -= [locale_path]
    I18n.locale = session[:locale] = I18n.default_locale
  end
end
edit public/stylesheets/depot.css
.locale {
        float:right;
        padding-top: 0.2em
}

restart

get /store?locale=es
es translation not available

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

$27.75
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

$28.50
edit app/views/layouts/store.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <title>Pragprog Books Online Store</title>
  <%= stylesheet_link_tag "depot", :media => "all" %>
  <%= javascript_include_tag :defaults %>
</head>
<body id="store">
  <div id="banner">
  <% form_tag '', :method => 'GET', :class => 'locale' do %>
    <%= select_tag 'locale', options_for_select(LANGUAGES, I18n.locale),
      :onchange => 'this.form.submit()' %>
    <%= submit_tag 'submit' %>
    <%= javascript_tag "$$('.locale input').each(Element.hide)" %>
  <% end %>
    <%= image_tag("logo.png") %>
    <%= @page_title || I18n.t('layout.title') %>
  </div>
  <div id="columns">
    <div id="side">
      <% if @cart %>
        <% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
          <%= render(:partial => "cart", :object => @cart) %>
        <% end %>
      <% end %>
 
      <a href="http://www...."><%= I18n.t 'layout.side.home' %></a><br />
      <a href="http://www..../faq"><%= I18n.t 'layout.side.questions' %></a><br />
      <a href="http://www..../news"><%= I18n.t 'layout.side.news' %></a><br />
      <a href="http://www..../contact"><%= I18n.t 'layout.side.contact' %></a><br />
      <% if session[:user_id] %>
        <br />
        <%= link_to 'Orders',   :controller => 'orders' %><br />
        <%= link_to 'Products', :controller => 'products' %><br />
        <%= link_to 'Users',    :controller => 'users'    %><br />
        <br />
        <%= link_to 'Logout', :controller => 'admin', :action => 'logout' %>
      <% end %>
    </div>
    <div id="main">
      <% if flash[:notice] -%>
        <div id="notice"><%= flash[:notice] %></div>
      <% end -%>
 
      <%= yield :layout %>
    </div>
  </div>
</body>
</html>
cp -r /home/rubys/git/awdwr/data/i18n/*.yml config/locales
get /store?locale=es

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29,95 $US
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27,75 $US
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28,50 $US
edit app/views/store/index.html.erb
<h1><%= I18n.t 'main.title' %></h1>
 
<% for product in @products -%>
  <div class="entry">
    <%= image_tag(product.image_url) %>
    <h3><%=h product.title %></h3>
    <%= product.description %>
    <div class="price-line">
    <span class="price"><%= number_to_currency(product.price) %></span>
    <% form_remote_tag :url => {:action => 'add_to_cart', :id => product} do %>
      <%= submit_tag I18n.t('main.button.add') %>
    <% end %>
    </div>
  </div>
<% end %>
get /store?locale=es

Su Catálogo de Pragmatic

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29,95 $US
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27,75 $US
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28,50 $US
edit app/views/store/_cart.html.erb
<div class="cart-title"><%= I18n.t 'layout.cart.title' %></div>
<table>
  <%= render(:partial => "cart_item", :collection => cart.items) %>  
  
  <tr class="total-line">
    <td colspan="2">Total</td>
    <td class="total-cell"><%= number_to_currency(cart.total_price) %></td>
  </tr>
 
</table>
  
<%= button_to I18n.t('layout.cart.button.checkout'), :action => 'checkout' %>
<%= button_to I18n.t('layout.cart.button.empty'), :action => :empty_cart %>
get /store/add_to_cart/2
You are being redirected.
get http://127.0.0.1:3000/store
Carrito de la Compra
Pragmatic Project Automation 29,95 $US
Total 29,95 $US
Inicio
Preguntas
Noticias
Contacto

Orders
Products
Users

Logout

Su Catálogo de Pragmatic

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29,95 $US
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27,75 $US
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28,50 $US
edit app/views/store/checkout.html.erb
<div class="depot-form">
  
  <%= error_messages_for 'order' %>
  
  <% form_for :order, :url => { :action => :save_order } do |form| %>
    <fieldset>
      <legend><%= I18n.t 'checkout.legend' %></legend>
 
      <div>
        <%= form.label :name, I18n.t('checkout.name') + ":" %>
        <%= form.text_field :name, :size => 40 %>
      </div>
 
      <div>
        <%= form.label :address, I18n.t('checkout.address') + ":" %>
        <%= form.text_area :address, :rows => 3, :cols => 40 %>
      </div>
 
      <div>
        <%= form.label :email, I18n.t('checkout.email') + ":" %>
        <%= form.text_field :email, :size => 40 %>
      </div>
 
      <div>
        <%= form.label :pay_type, I18n.t('checkout.pay_type') + ":" %>
        <%=
          form.select :pay_type,
                       Order::PAYMENT_TYPES, 
                      :prompt => I18n.t('checkout.pay_prompt')
        %>
      </div>
    
      <%= submit_tag I18n.t('checkout.submit'), :class => "submit" %>
    </fieldset>
  <% end %>  
</div>
edit app/controllers/store_controller.rb
class StoreController < ApplicationController
      before_filter :find_cart, :except => :empty_cart
  def index
    @products = Product.find_products_for_sale
  end
 
 
  def add_to_cart
    product = Product.find(params[:id])
    @current_item = @cart.add_product(product)
    respond_to do |format|
      format.js if request.xhr?
      format.html {redirect_to_index}
    end
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")
    redirect_to_index("Invalid product")
  end
 
  def checkout
    if @cart.items.empty?
      redirect_to_index("Your cart is empty")
    else
      @order = Order.new
    end
  end
 
  def save_order
    @order = Order.new(params[:order])
    @order.add_line_items_from_cart(@cart)
    if @order.save
      session[:cart] = nil
      redirect_to_index(I18n.t('flash.thanks'))
    else
      render :action => 'checkout'
    end
  end
 
  def empty_cart
    session[:cart] = nil
    redirect_to_index
  end
 
private
 
  def redirect_to_index(msg = nil)
    flash[:notice] = msg if msg
    redirect_to :action => 'index'
  end
 
      def find_cart
        @cart = (session[:cart] ||= Cart.new)
      end
 
  #...
protected
 
  def authorize
  end
end
get /store?locale=es
Carrito de la Compra
Pragmatic Project Automation 29,95 $US
Total 29,95 $US
Inicio
Preguntas
Noticias
Contacto

Orders
Products
Users

Logout

Su Catálogo de Pragmatic

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29,95 $US
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27,75 $US
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28,50 $US
get /store/add_to_cart/2
You are being redirected.
get http://127.0.0.1:3000/store
Carrito de la Compra
Pragmatic Project Automation 59,90 $US
Total 59,90 $US
Inicio
Preguntas
Noticias
Contacto

Orders
Products
Users

Logout

Su Catálogo de Pragmatic

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29,95 $US
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27,75 $US
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28,50 $US
get /store/checkout
Carrito de la Compra
Pragmatic Project Automation 59,90 $US
Total 59,90 $US
Inicio
Preguntas
Noticias
Contacto

Orders
Products
Users

Logout
Por favor, introduzca sus datos
get /store/save_order
Carrito de la Compra
Pragmatic Project Automation 59,90 $US
Total 59,90 $US
Inicio
Preguntas
Noticias
Contacto

Orders
Products
Users

Logout

5 errores han impedido que este pedido se guarde

Hay problemas con los siguientes campos:

  • Direcci&oacute;n no puede quedar en blanco
  • Nombre no puede quedar en blanco
  • Forma de pago no puede quedar en blanco
  • Forma de pago no est&aacute; incluido en la lista
  • E-mail no puede quedar en blanco
Por favor, introduzca sus datos
get /store/save_order
Carrito de la Compra
Pragmatic Project Automation 59,90 $US
Total 59,90 $US
Inicio
Preguntas
Noticias
Contacto

Orders
Products
Users

Logout

5 errores han impedido que este pedido se guarde

Hay problemas con los siguientes campos:

  • Direcci&oacute;n no puede quedar en blanco
  • Nombre no puede quedar en blanco
  • Forma de pago no puede quedar en blanco
  • Forma de pago no est&aacute; incluido en la lista
  • E-mail no puede quedar en blanco
Por favor, introduzca sus datos
post /store/save_order
  • order[pay_type] => check
  • order[address] => 123 Main St., Anytown USA
  • order[email] => juser@hotmail.com
  • order[name] => Joe User
You are being redirected.
get http://127.0.0.1:3000/store
Inicio
Preguntas
Noticias
Contacto

Orders
Products
Users

Logout
Gracias por su pedido

Su Catálogo de Pragmatic

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

29,95 $US
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole." That's the carnival game where the player strikes at a mechanical mole; it retreats and another mole pops up on the opposite side of the field. The moles pop up and down so fast that you end up flailing your mallet helplessly as the moles continue to pop up where you least expect them.

27,75 $US
Svn

Pragmatic Version Control

This book is a recipe-based approach to using Subversion that will get you up and running quickly---and correctly. All projects need version control: it's a foundational piece of any project's infrastructure. Yet half of all project teams in the U.S. don't use any version control at all. Many others don't use it well, and end up experiencing time-consuming problems.

28,50 $US
get /store?locale=en

Your Pragmatic Catalog

Auto

Pragmatic Project Automation

Pragmatic Project Automation shows you how to improve the consistency and repeatability of your project's procedures using automation to reduce risk and errors.

Simply put, we're going to put this thing called a computer to work for you doing the mundane (but important) project stuff. That means you'll have more time and energy to do the really exciting---and difficult---stuff, like writing quality code.

$29.95
Utc

Pragmatic Unit Testing (C#)

Pragmatic programmers use feedback to drive their development and personal processes. The most valuable feedback you can get while coding comes from unit testing.

Without good tests in place, coding can become a frustrating game of "whack-a-mole."