The Depot Application

The Depot Application

Table of Contents

4 Instant Gratification

erubis -r /home/rubys/git/awdwr/work/erbshim -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:  Tue Feb 02 14:51:55 -0500 2010 </li>
</ul>
erubis -r /home/rubys/git/awdwr/work/erbshim -T - < /home/rubys/git/awdwr/data/code/erb/ex2.html.erb | sed 's/<!--.*-->//'
 
Ho!<br />
 
Ho!<br />
 
Ho!<br />
Merry Christmas!
erubis -r /home/rubys/git/awdwr/work/erbshim -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 |  
         erubis -r /home/rubys/git/awdwr/work/erbshim -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  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
Depot::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end

6.2 Creating the Products Model and Maintenance Application

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

Start the server.

edit app/views/products/_form.html.erb
<% form_for(@product) do |f| %>
  <%= f.error_messages %>
 
  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :description %><br />
    <%= f.text_area :description, :rows => 6 %>
  </div>
  <div class="field">
    <%= f.label :image_url %><br />
    <%= f.text_field :image_url %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
get /products

Listing products

Title Description Image url

New product
get /products/new

New product




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

Product was successfully created.

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
(in /home/rubys/git/awdwr/work/depot)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.
Finished in 0.749 seconds.
 
1 tests, 1 assertions, 0 failures, 0 errors
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.......
Finished in 2.387 seconds.
 
7 tests, 10 assertions, 0 failures, 0 errors

6.3 Iteration A2: Add a Missing Column

ruby script/generate migration add_price_to_product price:decimal
      invoke  active_record
      create    db/migrate/20100202185410_add_price_to_product.rb
cat db/migrate/20100202185410_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/20100202185410_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 20100202185410_add_price_to_product.rb 20100301000002_add_price_to_product.rb
(in /home/rubys/git/awdwr/work/depot)
==  AddPriceToProduct: migrating ==============================================
-- add_column(:products, :price, :decimal, {:precision=>8, :default=>0, :scale=>2})
   -> 0.0470s
==  AddPriceToProduct: migrated (0.0470s) =====================================
 
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>
    <th></th>
    <th></th>
    <th></th>
  </tr>
 
<% @products.each do |product| %>
  <tr>
    <td><%= product.title %></td>
    <td><%= product.description %></td>
    <td><%= product.image_url %></td>
    <td><%= 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/_form.html.erb
<% form_for(@product) do |f| %>
  <%= f.error_messages %>
 
  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :description %><br />
    <%= f.text_area :description, :rows => 6 %>
  </div>
  <div class="field">
    <%= f.label :image_url %><br />
    <%= f.text_field :image_url %>
  </div>
  <div class="field">
    <%= f.label :price %><br />
    <%= f.text_field :price %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
edit app/views/products/show.html.erb
<p>
  <b>Title:</b>
  <%= @product.title %>
</p>
 
<p>
  <b>Description:</b>
  <%= @product.description %>
</p>
 
<p>
  <b>Image url:</b>
  <%= @product.image_url %>
</p>
 
<p>
  <b>Price:</b>
  <%= @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
(in /home/rubys/git/awdwr/work/depot)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.
Finished in 0.765 seconds.
 
1 tests, 1 assertions, 0 failures, 0 errors
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.......
Finished in 2.403 seconds.
 
7 tests, 10 assertions, 0 failures, 0 errors
edit app/views/products/show.html.erb
<p>
  <b>Title:</b>
  <%= @product.title %>
</p>
 
<p>
  <b>Description:</b>
  <%= @product.description %>
</p>
 
<p>
  <b>Image url:</b>
  <%= @product.image_url %>
</p>
 
<p>
  <b>Price:</b>
  <%= @product.price %>
</p>
 
<%= link_to 'Edit', edit_product_path(@product) %> |
<%= link_to 'Back', products_path %>
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

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

New product

3 errors prohibited this product from being saved

There were problems with the following fields:

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




Back
get /products/new

New product





Back
post /products

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 20100301000003_add_test_data.rb
(in /home/rubys/git/awdwr/work/depot)
==  AddTestData: migrating ====================================================
==  AddTestData: migrated (0.1090s) ===========================================
 
edit app/views/layouts/products.html.erb
<!DOCTYPE html>
<html>
<head>
  <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>
  <% @products.each do |product| %>
    <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
      create  app/controllers/store_controller.rb
      invoke  erb
      create    app/views/store
      create    app/views/store/index.html.erb
      invoke  test_unit
      create    test/functional/store_controller_test.rb
      invoke  helper
      create    app/helpers/store_helper.rb
      invoke    test_unit
      create      test/unit/helpers/store_helper_test.rb
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>
 
<% @products.each do |product| -%>
  <div class="entry">
    <%= image_tag(product.image_url) %>
    <h3><%=h product.title %></h3>
    <%=raw 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>
 
<% @products.each do |product| -%>
  <div class="entry">
    <%= image_tag(product.image_url) %>
    <h3><%=h product.title %></h3>
    <%=raw 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)
      invoke  active_record
      create    db/migrate/20100202185619_add_sessions_table.rb
rake db:migrate
mv 20100202185619_add_sessions_table.rb 20100301000004_add_sessions_table.rb
(in /home/rubys/git/awdwr/work/depot)
==  AddSessionsTable: migrating ===============================================
-- create_table(:sessions)
   -> 0.0000s
-- add_index(:sessions, :session_id)
   -> 0.0000s
-- add_index(:sessions, :updated_at)
   -> 0.0000s
==  AddSessionsTable: migrated (0.0000s) ======================================
 
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 => '0b2ee3eb7e7590a64375ddabef82e8e146e97070740cc1ddd10c42f235d531f7ca121766606043161a8381ec4da5deb4d7735dbc762b64ba1204791bc2ae9ae2'
}
 
# 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 the server.

edit app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery
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

Template is missing

Missing template store/add_to_cart with {:formats=>[:html]} in view path /home/rubys/git/awdwr/work/depot/app/views

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; <%= item.title %></li>
  <% end %>
</ul>
get /store/add_to_cart/2

NoMethodError in StoreController#add_to_cart

undefined method `product' for #<Product:0x7e3f8d78>

Rails.root: /home/rubys/git/awdwr/work/depot

Application Trace | Framework Trace | Full Trace
app/models/cart.rb:10:in `add_product'
app/models/cart.rb:10:in `each'
app/models/cart.rb:10:in `find'
app/models/cart.rb:10:in `add_product'
app/controllers/store_controller.rb:11:in `add_to_cart'

Request

Parameters:

{"id"=>"2"}

Show session dump

Show env dump

Response

Headers:

None

rake db:sessions:clear
(in /home/rubys/git/awdwr/work/depot)
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
app/controllers/store_controller.rb:9:in `add_to_cart'

Request

Parameters:

{"id"=>"wibble"}

Show session dump

Show env 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://localhost: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 -99 log/development.log
  SQL (0.0ms)  PRAGMA index_info('index_sessions_on_session_id')
 
 
Started GET "/store/add_to_cart/2" for 127.0.0.1 at 2010-02-02 13:56:52
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"2"}
  Product Load (16.0ms)  SELECT "products".* FROM "products" WHERE ("products"."id" = 2) LIMIT 1
 
ActionView::MissingTemplate (Missing template store/add_to_cart with {:formats=>[:html]} in view path /home/rubys/git/awdwr/work/depot/app/views):
 
 
Rendered vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/missing_template.erb within vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb (0.0ms)
 
 
Started GET "/store/add_to_cart/2" for 127.0.0.1 at 2010-02-02 13:56:55
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"2"}
  Product Load (0.0ms)  SELECT "products".* FROM "products" WHERE ("products"."id" = 2) LIMIT 1
Rendered store/add_to_cart.html.erb within layouts/store.html.erb (16.0ms)
Completed in 47ms (Views: 31.0ms | ActiveRecord: 0.0ms) with 200
 
 
Started GET "/store/add_to_cart/3" for 127.0.0.1 at 2010-02-02 13:56:55
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"3"}
  Product Load (0.0ms)  *[1mSELECT "products".* FROM "products" WHERE ("products"."id" = 3) LIMIT 1*[0m
Rendered store/add_to_cart.html.erb within layouts/store.html.erb (16.0ms)
Completed in 32ms (Views: 32.0ms | ActiveRecord: 0.0ms) with 200
 
 
Started GET "/store/add_to_cart/2" for 127.0.0.1 at 2010-02-02 13:56:56
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"2"}
  Product Load (0.0ms)  SELECT "products".* FROM "products" WHERE ("products"."id" = 2) LIMIT 1
 
NoMethodError (undefined method `product' for #<Product:0x7e3f8d78>):
  app/models/cart.rb:10:in `add_product'
  app/models/cart.rb:10:in `each'
  app/models/cart.rb:10:in `find'
  app/models/cart.rb:10:in `add_product'
  app/controllers/store_controller.rb:11:in `add_to_cart'
 
Rendered vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.0ms)
Rendered vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (16.0ms)
Rendered vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb (141.0ms)
  SQL (16.0ms)  *[1mDELETE FROM sessions*[0m
 
 
Started GET "/store/add_to_cart/2" for 127.0.0.1 at 2010-02-02 13:57:12
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"2"}
  Product Load (0.0ms)  SELECT "products".* FROM "products" WHERE ("products"."id" = 2) LIMIT 1
Rendered store/add_to_cart.html.erb within layouts/store.html.erb (0.0ms)
Completed in 47ms (Views: 16.0ms | ActiveRecord: 0.0ms) with 200
 
 
Started GET "/store/add_to_cart/2" for 127.0.0.1 at 2010-02-02 13:57:12
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"2"}
  Product Load (0.0ms)  SELECT "products".* FROM "products" WHERE ("products"."id" = 2) LIMIT 1
Rendered store/add_to_cart.html.erb within layouts/store.html.erb (0.0ms)
Completed in 31ms (Views: 15.0ms | ActiveRecord: 0.0ms) with 200
 
 
Started GET "/store/add_to_cart/3" for 127.0.0.1 at 2010-02-02 13:57:13
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"3"}
  Product Load (0.0ms)  SELECT "products".* FROM "products" WHERE ("products"."id" = 3) LIMIT 1
Rendered store/add_to_cart.html.erb within layouts/store.html.erb (0.0ms)
Completed in 16ms (Views: 16.0ms | ActiveRecord: 0.0ms) with 200
 
 
Started GET "/store/add_to_cart/wibble" for 127.0.0.1 at 2010-02-02 13:57:13
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"wibble"}
  Product Load (0.0ms)  SELECT "products".* FROM "products" WHERE ("products"."id" = 0) LIMIT 1
 
ActiveRecord::RecordNotFound (Couldn't find Product with ID=wibble):
  app/controllers/store_controller.rb:9:in `add_to_cart'
 
Rendered vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.0ms)
Rendered vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (78.0ms)
Rendered vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within vendor/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb (203.0ms)
 
 
Started GET "/store/add_to_cart/wibble" for 127.0.0.1 at 2010-02-02 13:57:13
  Processing by StoreController#add_to_cart as HTML
  Parameters: {"id"=>"wibble"}
  Product Load (0.0ms)  *[1mSELECT "products".* FROM "products" WHERE ("products"."id" = 0) LIMIT 1*[0m
Attempt to access invalid product wibble
Redirected to http://localhost:3000/store
Completed in 16ms with 302
 
 
Started GET "/store" for 127.0.0.1 at 2010-02-02 13:57:14
  Processing by StoreController#index as */*
  Product Load (0.0ms)  *[1mSELECT "products".* FROM "products" ORDER BY title*[0m
Rendered store/index.html.erb within layouts/store.html.erb (16.0ms)
Completed in 47ms (Views: 47.0ms | ActiveRecord: 0.0ms) with 200
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://localhost: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; <%= 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://localhost: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
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><%= 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://localhost: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_tag({:action=>'add_to_cart', :id=>product}, :remote=>true) 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><%= 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://localhost: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://localhost: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
      invoke  active_record
      create    db/migrate/20100202185741_create_orders.rb
      create    app/models/order.rb
      invoke    test_unit
      create      test/unit/order_test.rb
      create      test/fixtures/orders.yml
       route  resources :orders
      invoke  scaffold_controller
      create    app/controllers/orders_controller.rb
      invoke    erb
      create      app/views/orders
      create      app/views/orders/index.html.erb
      create      app/views/orders/edit.html.erb
      create      app/views/orders/show.html.erb
      create      app/views/orders/new.html.erb
      create      app/views/orders/_form.html.erb
      create      app/views/layouts/orders.html.erb
      invoke    test_unit
      create      test/functional/orders_controller_test.rb
      invoke    helper
      create      app/helpers/orders_helper.rb
      invoke      test_unit
      create        test/unit/helpers/orders_helper_test.rb
      invoke  stylesheets
   identical    public/stylesheets/scaffold.css
ruby script/generate scaffold line_item product_id:integer order_id:integer quantity:integer total_price:decimal
      invoke  active_record
      create    db/migrate/20100202185759_create_line_items.rb
      create    app/models/line_item.rb
      invoke    test_unit
      create      test/unit/line_item_test.rb
      create      test/fixtures/line_items.yml
       route  resources :line_items
      invoke  scaffold_controller
      create    app/controllers/line_items_controller.rb
      invoke    erb
      create      app/views/line_items
      create      app/views/line_items/index.html.erb
      create      app/views/line_items/edit.html.erb
      create      app/views/line_items/show.html.erb
      create      app/views/line_items/new.html.erb
      create      app/views/line_items/_form.html.erb
      create      app/views/layouts/line_items.html.erb
      invoke    test_unit
      create      test/functional/line_items_controller_test.rb
      invoke    helper
      create      app/helpers/line_items_helper.rb
      invoke      test_unit
      create        test/unit/helpers/line_items_helper_test.rb
      invoke  stylesheets
   identical    public/stylesheets/scaffold.css
edit db/migrate/20100202185741_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/20100202185759_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 20100202185741_create_orders.rb 20100301000005_create_orders.rb
mv 20100202185759_create_line_items.rb 20100301000006_create_line_items.rb
(in /home/rubys/git/awdwr/work/depot)
==  CreateOrders: migrating ===================================================
-- create_table(:orders)
   -> 0.0000s
==  CreateOrders: migrated (0.0000s) ==========================================
 
==  CreateLineItems: migrating ================================================
-- create_table(:line_items)
   -> 0.0000s
==  CreateLineItems: migrated (0.0000s) =======================================
 
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

The action 'save_order' could not be found

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:

  • Name can't be blank
  • Address can't be blank
  • Email can't be blank
  • Pay type can't be blank
  • Pay type is not included in the list
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
You are being redirected.
get http://localhost: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@example.com
  pay_type = check
created_at = 2010-02-02 18:58:22.555600
updated_at = 2010-02-02 18:58:22.555600
sqlite3> select * from line_items
         id = 1
 product_id = 3
   order_id = 1
   quantity = 1
total_price = 28.5
 created_at = 2010-02-02 18:58:22.555600
 updated_at = 2010-02-02 18:58:22.555600
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
      invoke  active_record
      create    db/migrate/20100202185839_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/unit/user_test.rb
      create      test/fixtures/users.yml
       route  resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      create      app/views/layouts/users.html.erb
      invoke    test_unit
      create      test/functional/users_controller_test.rb
      invoke    helper
      create      app/helpers/users_helper.rb
      invoke      test_unit
      create        test/unit/helpers/users_helper_test.rb
      invoke  stylesheets
   identical    public/stylesheets/scaffold.css
cat db/migrate/20100202185839_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 20100202185839_create_users.rb 20100301000007_create_users.rb
(in /home/rubys/git/awdwr/work/depot)
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0000s
==  CreateUsers: migrated (0.0000s) ===========================================
 
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
        format.html { redirect_to(users_url,
                    :notice => "User #{@user.name} was successfully created.") }
        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])
        format.html { redirect_to(users_url,
                    :notice => "User #{@user.name} was successfully updated.") }
        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>
    <th></th>
    <th></th>
    <th></th>
  </tr>
 
<% @users.each do |user| %>
  <tr>
    <td><%= 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>
<html>
<head>
  <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
You are being redirected.
get http://localhost: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 = 24358e4f983aebb2a58f13a322a3e899cc05e167
           salt = 10599061400.871899299001394
     created_at = 2010-02-02 18:58:58.950600
     updated_at = 2010-02-02 18:58:58.950600

11.2 Iteration F2: Logging in

ruby script/generate controller admin login logout index
      create  app/controllers/admin_controller.rb
      invoke  erb
      create    app/views/admin
      create    app/views/admin/login.html.erb
      create    app/views/admin/logout.html.erb
      create    app/views/admin/index.html.erb
      invoke  test_unit
      create    test/functional/admin_controller_test.rb
      invoke  helper
      create    app/helpers/admin_helper.rb
      invoke    test_unit
      create      test/unit/helpers/admin_helper_test.rb
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
You are being redirected.
get http://localhost:3000/admin

Welcome

It's Tue Feb 02 13:59:16 -0500 2010 We have 1 order.

11.3 Iteration F3: Limiting Access

edit app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_filter :authorize, :except => :login
  protect_from_forgery
    
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://localhost:3000/admin/login
Please Log In
get /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 /products
You are being redirected.
get http://localhost:3000/admin/login
Please Log In
get /admin/login
Please Log In
post /admin/login
You are being redirected.
get http://localhost:3000/admin

Welcome

It's Tue Feb 02 13:59:35 -0500 2010 We have 1 order.
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

11.4 Iteration F4: Adding a Sidebar, More Administration

edit app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  layout "store"
  #...
get /admin

NoMethodError in Admin#index

Showing /home/rubys/git/awdwr/work/depot/app/views/layouts/store.html.erb where line #24 raised:

undefined method `items' for nil:NilClass

Extracted source (around line #24):

21:     <div id="side">
22:       <!-- START_HIGHLIGHT -->
23:       <!-- START:hidden_div -->
24:       <% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
25:         <%= render(:partial => "cart", :object => @cart) %>
26:       <% end %>
27:     <!-- END:hidden_div -->

Rails.root: /home/rubys/git/awdwr/work/depot

Application Trace | Framework Trace | Full Trace

Request

Parameters:

None

Show session dump

Show env dump

Response

Headers:

None

get /users

Listing users

Name
dave Show Edit Destroy

New user
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 Tue Feb 02 13:59:36 -0500 2010 We have 1 order.
get /users

Listing users

Name
dave Show Edit Destroy

New user
rm app/views/layouts/products.html.erb
rm app/views/layouts/users.html.erb
rm app/views/layouts/orders.html.erb
get /users

Listing users

Name
dave Show Edit Destroy

New user
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
  
  after_destroy :ensure_an_admin_remains
 
  def ensure_an_admin_remains
    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
        format.html { redirect_to(users_url,
                    :notice => "User #{@user.name} was successfully created.") }
        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])
        format.html { redirect_to(users_url,
                    :notice => "User #{@user.name} was successfully updated.") }
        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
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Product.new
=> #<Product id: nil, title: nil, description: nil, image_url: nil, created_at: nil, updated_at: nil, price: #<BigDecimal:7e5ef8e8,'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
      create  app/controllers/info_controller.rb
      invoke  erb
      create    app/views/info
      create    app/views/info/who_bought.html.erb
      invoke  test_unit
      create    test/functional/info_controller_test.rb
      invoke  helper
      create    app/helpers/info_helper.rb
      invoke    test_unit
      create      test/unit/helpers/info_helper_test.rb
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
<order_list for_product="Pragmatic Version Control">
  <order>
    <name>Dave Thomas</name>
    <email>customer@example.com</email>
  </order>
</order_list>
curl --silent http://localhost:3000/info/who_bought/3
<order_list for_product="Pragmatic Version Control">
  <order>
    <name>Dave Thomas</name>
    <email>customer@example.com</email>
  </order>
</order_list>
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 = 2010-02-02 18:55:43.420000
 updated_at = 2010-02-02 18:55:43.420000
      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 = 2010-02-02 18:55:43.420000
 updated_at = 2010-02-02 18:55:43.420000
      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 = 2010-02-02 18:55:43.420000
 updated_at = 2010-02-02 18:55:43.420000
      price = 27.75
sqlite3> select * from line_items
         id = 1
 product_id = 3
   order_id = 1
   quantity = 1
total_price = 28.5
 created_at = 2010-02-02 18:58:22.555600
 updated_at = 2010-02-02 18:58:22.555600
curl --silent http://localhost:3000/info/who_bought/3
<order_list for_product="Pragmatic Version Control">
  <order>
    <name>Dave Thomas</name>
    <email>customer@example.com</email>
  </order>
</order_list>
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?1265137098" media="all" rel="stylesheet" type="text/css" />
<!-- END:stylesheet -->
  <script src="/javascripts/prototype.js?1265136721" type="text/javascript"></script>
<script src="/javascripts/effects.js?1265136721" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1265136721" type="text/javascript"></script>
<script src="/javascripts/controls.js?1265136721" type="text/javascript"></script>
<script src="/javascripts/rails.js?1265136721" type="text/javascript"></script>
<script src="/javascripts/application.js?1265136721" type="text/javascript"></script>
</head>
<!-- END:jit -->
<body id="store">
  <div id="banner">
    <img alt="Logo" src="/images/logo.png?1265136943" />
    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@example.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@example.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">2010-02-02T18:55:43Z</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">2010-02-02T18:55:43Z</updated-at>
  <orders type="array">
    <order>
      <address>123 Main St</address>
      <created-at type="datetime">2010-02-02T18:58:22Z</created-at>
      <email>customer@example.com</email>
      <id type="integer">1</id>
      <name>Dave Thomas</name>
      <pay-type>check</pay-type>
      <updated-at type="datetime">2010-02-02T18:58:22Z</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" rel="alternate" href="http://localhost:3000"/>
  <link type="application/atom+xml" rel="self" href="http://localhost:3000/info/who_bought/3.atom"/>
  <title>Who bought Pragmatic Version Control</title>
  <updated>2010-02-02T18:58:22Z</updated>
  <entry>
    <id>tag:localhost,2005:Order/1</id>
    <published>2010-02-02T18:58:22Z</published>
    <updated>2010-02-02T18:58:22Z</updated>
    <link type="text/html" rel="alternate" href="http://localhost:3000/orders/1"/>
    <title>Order 1</title>
    <summary type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>Shipped to 123 Main St</p>
        <table>
          <tr>
            <th>Product</th>
            <th>Quantity</th>
            <th>Total Price</th>
          </tr>
          <tr>
            <td>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@example.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
{"price":28.5,"created_at":"2010-02-02T18:55:43Z","title":"Pragmatic Version Control","image_url":"/images/svn.jpg","updated_at":"2010-02-02T18:55:43Z","id":3,"orders":[{"name":"Dave Thomas","address":"123 Main St","created_at":"2010-02-02T18:58:22Z","updated_at":"2010-02-02T18:58:22Z","pay_type":"check","id":1,"email":"customer@example.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: 
                admin_controller.rb: c...
          application_controller.rb: c.
                 info_controller.rb: c..
           line_items_controller.rb: c.......
               orders_controller.rb: c.......
             products_controller.rb: c.......
                store_controller.rb: c........
                users_controller.rb: c.......
                    admin_helper.rb: m
              application_helper.rb: m
                     info_helper.rb: m
               line_items_helper.rb: m
                   orders_helper.rb: m
                 products_helper.rb: m
                    store_helper.rb: m.
                    users_helper.rb: m
                            cart.rb: c....
                       cart_item.rb: c....
                       line_item.rb: c.
                           order.rb: c.
                         product.rb: c..
                            user.rb: c.......
Generating HTML...
(in /home/rubys/git/awdwr/work/depot)
 
Files:   23
Classes: 14
Modules: 8
Methods: 62
Elapsed: 1.139s
rake stats
(in /home/rubys/git/awdwr/work/depot)
+----------------------+-------+-------+---------+---------+-----+-------+
| Name                 | Lines |   LOC | Classes | Methods | M/C | LOC/M |
+----------------------+-------+-------+---------+---------+-----+-------+
| Controllers          |   503 |   337 |       8 |      42 |   5 |     6 |
| Helpers              |    22 |    22 |       0 |       1 |   0 |    20 |
| Models               |   231 |   130 |       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                |  1020 |   696 |      32 |      62 |   1 |     9 |
+----------------------+-------+-------+---------+---------+-----+-------+
  Code LOC: 489     Test LOC: 207     Code to Test Ratio: 1:0.4
 

13 Task I: Internationalization

get /store/empty_cart
You are being redirected.
get http://localhost: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
edit config/initializers/i18n.rb
#encoding: utf-8
I18n.default_locale = 'en'
 
LOCALES_DIRECTORY = "#{Rails.root}/config/locales/"
 
LANGUAGES = {
  'English' => 'en',
  "Espa\xc3\xb1ol" => 'es'
}

Restart the server.

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
class ApplicationController < ActionController::Base
  layout "store"
  #...
  before_filter :authorize, :except => :login
  before_filter :set_locale
  protect_from_forgery
    
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
}
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>
edit config/locales/en.yml
en:
 
  number:
    currency:
      format:
        unit: "$"
        precision: 2
        separator: "."
        delimiter: ","
        format: "%u%n"
 
  layout:
    title:       "Pragmatic Bookshelf"
    side:
      home:      "Home"
      questions: "Questions"
      news:      "News"
      contact:   "Contact"
    cart:
      title:      "Your Cart"
      button:
        empty:    "Empty cart"
        checkout: "Checkout"
 
  main:
    title:       "Your Pragmatic Catalog"
    button:
      add:       "Add to Cart"
 
  checkout:
    legend:      "Please Enter your Details"
    name:        "Name"
    address:     "Address"
    email:       "E-mail"
    pay_type:    "Pay with"
    pay_prompt:  "Select a payment method"
    submit:      "Place Order"
 
  flash:
    thanks:      "Thank you for your order"
edit config/locales/es.yml
es:
 
  number:
    currency:
      format:
        unit: "$US"
        precision: 2
        separator: ","
        delimiter: "."
        format: "%n&nbsp;%u"
 
  activerecord:
    models:
      order: "pedido"
    attributes:
      order:
        address: "Direcci&oacute;n"
        name: "Nombre"
        email: "E-mail"
        pay_type: "Forma de pago"
    errors:
      messages:
        inclusion: "no est&aacute; incluido en la lista"
        blank:     "no puede quedar en blanco"
  errors:
    template:
      body: "Hay problemas con los siguientes campos:"
      header:
        one:   "1 error ha impedido que este {{model}} se guarde"
        other: "{{count}} errores han impedido que este {{model}} se guarde"
 
  layout:
    title:       "Publicaciones de Pragmatic"
    side:
      home:      "Inicio"
      questions: "Preguntas"
      news:      "Noticias"
      contact:   "Contacto"
    cart:
      title:      "Carrito de la Compra"
      button:
        empty:    "Vaciar Carrito"
        checkout: "Comprar"
 
  main:
    title:       "Su Cat&aacute;logo de Pragmatic"
    button:
      add:       "A&ntilde;adir al Carrito"
 
  checkout:
    legend:      "Por favor, introduzca sus datos"
    name:        "Nombre"
    address:     "Direcci&oacute;n"
    email:       "E-mail"
    pay_type:    "Pagar con"
    pay_prompt:  "Seleccione un m\xC3\xA9todo de pago"
    submit:      "Realizar Pedido"
 
  flash:
    thanks:      "Gracias por su pedido"
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><%=raw I18n.t('main.title') %></h1>
 
<% @products.each do |product| -%>
  <div class="entry">
    <%= image_tag(product.image_url) %>
    <h3><%=h product.title %></h3>
    <%=raw product.description %>
    <div class="price-line">
    <span class="price"><%=raw number_to_currency(product.price) %></span>
    <% form_tag({:action=>'add_to_cart', :id=>product}, :remote=>true) do %>
      <%= submit_tag I18n.t('main.button.add') %>
    <% end %>
    </div>
  </div>
<% 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"><%=raw number_to_currency(cart.total_price) %></td>
  </tr>
 
</table>
  
<%= button_to "Checkout", :action => 'checkout' %>
<%= button_to "Empty cart", :action => :empty_cart %>
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><%= cart_item.title %></td>
  <td class="item-price"><%=raw number_to_currency(cart_item.price) %></td>
</tr>
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"><%=raw 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://localhost: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://localhost: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:

  • Nombre no puede quedar en blanco
  • Direcci&oacute;n no puede quedar en blanco
  • E-mail no puede quedar en blanco
  • Forma de pago no puede quedar en blanco
  • Forma de pago no est&aacute; incluido en la lista
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:

  • Nombre no puede quedar en blanco
  • Direcci&oacute;n no puede quedar en blanco
  • E-mail no puede quedar en blanco
  • Forma de pago no puede quedar en blanco
  • Forma de pago no est&aacute; incluido en la lista
Por favor, introduzca sus datos
post /store/save_order
You are being redirected.
get http://localhost: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." 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

14.1 Tests Baked Right In

ls -p test
fixtures/
functional/
integration/
performance/
test_helper.rb
unit/
ls test/unit
helpers
line_item_test.rb
order_test.rb
product_test.rb
user_test.rb
ls test/functional
admin_controller_test.rb
info_controller_test.rb
line_items_controller_test.rb
orders_controller_test.rb
products_controller_test.rb
store_controller_test.rb
users_controller_test.rb

14.2 Unit Testing of Models

cat test/unit/product_test.rb
require 'test_helper'
 
class ProductTest < ActiveSupport::TestCase
  # Replace this with your real tests.
  test "the truth" do
    assert true
  end
end
ruby -Itest test/unit/product_test.rb
Loaded suite test/unit/product_test
Started
E
Finished in 0.718 seconds.
 
  1) Error:
test_the_truth(ProductTest):
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: users: DELETE FROM "users" WHERE 1=1
 
 
1 tests, 0 assertions, 0 failures, 1 errors
rake db:test:prepare
(in /home/rubys/git/awdwr/work/depot)
ruby -Itest test/unit/product_test.rb
Loaded suite test/unit/product_test
Started
.
Finished in 0.764 seconds.
 
1 tests, 1 assertions, 0 failures, 0 errors
rake test:units
(in /home/rubys/git/awdwr/work/depot)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
....
Finished in 0.843 seconds.
 
4 tests, 4 assertions, 0 failures, 0 errors
edit test/unit/product_test.rb
require 'test_helper'
 
class ProductTest < ActiveSupport::TestCase
  
  fixtures :products
  
  # Replace this with your real tests.
  test "the truth" do
    assert true
  end
 
  test "invalid with empty attributes" do
    product = Product.new
    assert !product.valid?
    assert product.errors[:title].any?
    assert product.errors[:description].any?
    assert product.errors[:price].any?
    assert product.errors[:image_url].any?
  end
 
  test "positive price" do
    product = Product.new(:title       => "My Book Title",
                          :description => "yyy",
                          :image_url   => "zzz.jpg")
    product.price = -1
    assert !product.valid?
    assert_equal "should be at least 0.01", product.errors[:price].join
 
    product.price = 0
    assert !product.valid?
    assert_equal "should be at least 0.01", product.errors[:price].join
 
    product.price = 1
    assert product.valid?
  end
 
  test "image url" do
    ok = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg
             http://a.b.c/x/y/z/fred.gif }
    bad = %w{ fred.doc fred.gif/more fred.gif.more }
    
    ok.each do |name|
      product = Product.new(:title       => "My Book Title",
                            :description => "yyy",
                            :price       => 1,
                            :image_url   => name)
      assert product.valid?, product.errors.full_messages
    end
 
    bad.each do |name|
      product = Product.new(:title => "My Book Title",
                            :description => "yyy",
                            :price => 1,
                            :image_url => name)
      assert !product.valid?, "saving #{name}"
    end
  end
 
  test "unique title" do
    product = Product.new(:title       => products(:ruby_book).title,
                          :description => "yyy", 
                          :price       => 1, 
                          :image_url   => "fred.gif")
 
    assert !product.save
    assert_equal "has already been taken", product.errors[:title].join
  end
 
  test "unique title1" do
    product = Product.new(:title       => products(:ruby_book).title,
                          :description => "yyy", 
                          :price       => 1, 
                          :image_url   => "fred.gif")
 
    assert !product.save
    assert_equal I18n.translate('activerecord.errors.messages.taken'),
                 product.errors[:title].join
  end
  
end
edit test/fixtures/products.yml
ruby_book:
  title:       Programming Ruby
  description: Dummy description
  price:       1234
  image_url:   ruby.png
 
rails_book:
  title:       Agile Web Development with Rails
  description: Dummy description
  price:       2345
  image_url:   rails.png
  
rake test:units
(in /home/rubys/git/awdwr/work/depot)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.........
Finished in 0.904 seconds.
 
9 tests, 27 assertions, 0 failures, 0 errors
edit test/unit/cart_test.rb
require 'test_helper'
 
class CartTest < ActiveSupport::TestCase
  fixtures :products
  test "add unique products" do
    cart = Cart.new
    rails_book = products(:rails_book)
    ruby_book  = products(:ruby_book)
    cart.add_product rails_book
    cart.add_product ruby_book
    assert_equal 2, cart.items.size
    assert_equal rails_book.price + ruby_book.price, cart.total_price
  end
  
  test "add_duplicate_product" do
    cart = Cart.new
    rails_book = products(:rails_book)
    cart.add_product rails_book
    cart.add_product rails_book
    assert_equal 2*rails_book.price, cart.total_price
    assert_equal 1, cart.items.size
    assert_equal 2, cart.items[0].quantity
  end 
end
ruby -I test test/unit/cart_test.rb
Loaded suite test/unit/cart_test
Started
..
Finished in 0.796 seconds.
 
2 tests, 5 assertions, 0 failures, 0 errors
edit test/unit/cart_test1.rb
require 'test_helper'
 
class CartTest < ActiveSupport::TestCase
  fixtures :products
 
  def setup
    @cart  = Cart.new
    @rails = products(:rails_book)
    @ruby  = products(:ruby_book)
  end
  
  test "add unique products" do
    @cart.add_product @rails
    @cart.add_product @ruby
    assert_equal 2, @cart.items.size
    assert_equal @rails.price + @ruby.price, @cart.total_price
  end
 
  test "add duplicate product" do
    @cart.add_product @rails
    @cart.add_product @rails
    assert_equal 2*@rails.price, @cart.total_price
    assert_equal 1, @cart.items.size
    assert_equal 2, @cart.items[0].quantity
  end 
end
ruby -I test test/unit/cart_test1.rb
Loaded suite test/unit/cart_test1
Started
..
Finished in 0.796 seconds.
 
2 tests, 5 assertions, 0 failures, 0 errors

14.3 Functional Testing of Controllers

edit app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  layout "store"
  before_filter :authorize, :except => :login
  #...
 
 
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 test/functional/admin_controller_test.rb
require 'test_helper'
 
class AdminControllerTest < ActionController::TestCase
 
  fixtures :users
  
  # Replace this with your real tests.
  test "the truth" do
    assert true
  end
  
  if false
    test "index" do
      get :index 
      assert_response :success 
    end
  end
 
  test "index without user" do
    get :index
    assert_redirected_to :action => "login"
    assert_equal "Please log in", flash[:notice]
  end
 
  test "index with user" do
    get :index, {}, { :user_id => users(:dave).id }
    assert_response :success
    assert_template "index"
  end
 
  test "login" do
    dave = users(:dave)
    post :login, :name => dave.name, :password => 'secret'
    assert_redirected_to :action => "index"
    assert_equal dave.id, session[:user_id]
  end
 
  test "bad password" do
    dave = users(:dave)
    post :login, :name => dave.name, :password => 'wrong'
    assert_template "login"
  end
end
edit test/fixtures/users.yml
<% SALT = "NaCl" unless defined?(SALT) %>
 
dave:
  name: dave
  salt: <%= SALT %>
  hashed_password: <%= User.encrypted_password('secret', SALT) %>
ruby -I test test/functional/admin_controller_test.rb
Loaded suite test/functional/admin_controller_test
Started
.....
Finished in 0.905 seconds.
 
5 tests, 8 assertions, 0 failures, 0 errors

14.4 Integration Testing of Applications

ruby script/generate integration_test user_stories
      invoke  test_unit
      create    test/integration/user_stories_test.rb
edit test/integration/user_stories_test.rb
require 'test_helper'
 
class UserStoriesTest < ActionController::IntegrationTest
  fixtures :products
 
  # A user goes to the index page. They select a product, adding it to their
  # cart, and check out, filling in their details on the checkout form. When
  # they submit, an order is created containing their information, along with a
  # single line item corresponding to the product they added to their cart.
  
  test "buying a product" do
    LineItem.delete_all
    Order.delete_all
    ruby_book = products(:ruby_book)
 
    get "/store/index"
    assert_response :success
    assert_template "index"
    
    xml_http_request :put, "/store/add_to_cart/#{ruby_book.id}"
    assert_response :success 
    
    cart = session[:cart]
    assert_equal 1, cart.items.size
    assert_equal ruby_book, cart.items[0].product
    
    post "/store/checkout"
    assert_response :success
    assert_template "checkout"
    
    post_via_redirect "/store/save_order",
                      :order => { :name     => "Dave Thomas",
                                 :address  => "123 The Street",
                                 :email    => "dave@example.com",
                                 :pay_type => "check" }
    assert_response :success
    assert_template "index"
    assert_equal 0, session[:cart].items.size
    
    orders = Order.find(:all)
    assert_equal 1, orders.size
    order = orders[0]
    
    assert_equal "Dave Thomas",       order.name
    assert_equal "123 The Street",    order.address
    assert_equal "dave@example.com", order.email
    assert_equal "check",             order.pay_type
    
    assert_equal 1, order.line_items.size
    line_item = order.line_items[0]
    assert_equal ruby_book, line_item.product
  end
end
ruby -I test test/integration/user_stories_test.rb
Loaded suite test/integration/user_stories_test
Started
.
Finished in 1.684 seconds.
 
1 tests, 17 assertions, 0 failures, 0 errors
edit test/integration/dsl_user_stories_test.rb
require 'test_helper'
 
class DslUserStoriesTest < ActionController::IntegrationTest
  fixtures :products
 
 
  DAVES_DETAILS = {
      :name     => "Dave Thomas",
      :address  => "123 The Street",
      :email    => "dave@example.com",
      :pay_type => "check"
  }
 
  MIKES_DETAILS = {
      :name     => "Mike Clark",
      :address  => "345 The Avenue",
      :email    => "mike@pragmaticstudio.com",
      :pay_type => "cc"
  }
  
  
    
  def setup
    LineItem.delete_all
    Order.delete_all
    @ruby_book = products(:ruby_book)
    @rails_book = products(:rails_book)
  end 
  
  # A user goes to the store index page. They select a product,
  # adding it to their cart. They then check out, filling in
  # their details on the checkout form. When they submit,
  # an order is created in the database containing
  # their information, along with a single line item
  # corresponding to the product they added to their cart.
  
  def test_buying_a_product
    dave = regular_user
    dave.get "/store/index"
    dave.is_viewing "index"
    dave.buys_a @ruby_book
    dave.has_a_cart_containing @ruby_book
    dave.checks_out DAVES_DETAILS
    dave.is_viewing "index"
    check_for_order DAVES_DETAILS, @ruby_book
  end
 
  def test_two_people_buying
    dave = regular_user
        mike = regular_user
    dave.buys_a @ruby_book
        mike.buys_a @rails_book
    dave.has_a_cart_containing @ruby_book
    dave.checks_out DAVES_DETAILS
        mike.has_a_cart_containing @rails_book
    check_for_order DAVES_DETAILS, @ruby_book
        mike.checks_out MIKES_DETAILS
        check_for_order MIKES_DETAILS, @rails_book
  end
  
  def regular_user
    open_session do |user|
      def user.is_viewing(page)
        assert_response :success
        assert_template page
      end
    
      def user.buys_a(product)
        xml_http_request :put, "/store/add_to_cart/#{product.id}"
        assert_response :success 
      end
    
      def user.has_a_cart_containing(*products)
        cart = session[:cart]
        assert_equal products.size, cart.items.size
        for item in cart.items
          assert products.include?(item.product)
        end
      end
    
      def user.checks_out(details)
        post "/store/checkout"
        assert_response :success
        assert_template "checkout"
 
        post_via_redirect "/store/save_order",
                          :order => { :name     => details[:name],
                                     :address  => details[:address],
                                     :email    => details[:email],
                                     :pay_type => details[:pay_type]
                                    }
        assert_response :success
        assert_template "index"
        assert_equal 0, session[:cart].items.size
      end
    end  
  end
  
  def check_for_order(details, *products)
    order = Order.find_by_name(details[:name])
    assert_not_nil order
    
    assert_equal details[:name],     order.name
    assert_equal details[:address],  order.address
    assert_equal details[:email],    order.email
    assert_equal details[:pay_type], order.pay_type
    
    assert_equal products.size, order.line_items.size
    for line_item in order.line_items
      assert products.include?(line_item.product)
    end
  end
end
ruby -I test test/integration/dsl_user_stories_test.rb
Loaded suite test/integration/dsl_user_stories_test
Started
..
Finished in 1.81 seconds.
 
2 tests, 49 assertions, 0 failures, 0 errors

14.5 Performance Testing

mkdir test/fixtures/performance/
edit test/fixtures/performance/products.yml
<% 1.upto(1000) do |i| %>
product_<%= i %>:
  id: <%= i %>
  title: Product Number <%= i %>
  description: My description
  image_url: product.gif
  price: 1234
<% end %>
edit test/performance/order_speed_test.rb
require 'test_helper'
require 'store_controller'
 
class OrderSpeedTest < ActionController::TestCase
  tests StoreController
  
  DAVES_DETAILS = {
      :name     => "Dave Thomas",
      :address  => "123 The Street",
      :email    => "dave@example.com",
      :pay_type => "check"
  }
  
  self.fixture_path = File.join(File.dirname(__FILE__), "../fixtures/performance")
  fixtures :products
  
 
  def test_100_orders
    Order.delete_all
    LineItem.delete_all
 
    @controller.logger.silence do
      elapsed_time = Benchmark.realtime do
        100.downto(1) do |prd_id|
          cart = Cart.new
          cart.add_product(Product.find(prd_id))
          post :save_order, 
               { :order => DAVES_DETAILS },
               { :cart  => cart }
          assert_redirected_to :action => :index
        end         
      end       
      assert_equal 100, Order.count
      assert elapsed_time < 3.00
    end
  end
end
ruby -I test test/performance/order_speed_test.rb
Loaded suite test/performance/order_speed_test
Started
.
Finished in 3.011 seconds.
 
1 tests, 102 assertions, 0 failures, 0 errors
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
  
  after_destroy :ensure_an_admin_remains
 
  def ensure_an_admin_remains
    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)
    100000.times { Math.sin(1)}
    string_to_hash = password + "wibble" + salt
    Digest::SHA1.hexdigest(string_to_hash)
  end
end
ruby script/performance/benchmarker "User.encrypted_password(\"secret\", \"salt\")"
            user     system      total        real
#1      0.172000   0.000000   0.172000 (  0.172000)
ruby script/performance/profiler "User.encrypted_password(\"secret\", \"salt\")"
Using the standard Ruby profiler.
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 77.10     4.69      4.69        1  4691.00  5772.00  Integer#times
 17.77     5.77      1.08   100000     0.01     0.01  Math.sin
  1.53     5.87      0.09        4    23.25    27.00  Array#select
  1.02     5.93      0.06       59     1.05     3.17  Array#each
  0.26     5.94      0.02        9     1.78     3.56  Array#map
  0.26     5.96      0.02      792     0.02     0.02  String#to_s
  0.26     5.97      0.02       12     1.33     1.33  Fixnum#to_s
  0.26     5.99      0.02       26     0.62     0.62  Kernel.is_a?
  0.26     6.01      0.02       37     0.43     0.43  Array#include?
  0.26     6.02      0.02        5     3.20     3.20  Array#reverse_each
  0.26     6.04      0.02       46     0.35     0.35  Array#<<
  0.25     6.05      0.02        5     3.00     6.20  ActiveSupport::Callbacks::Callback#_compile_per_key_options
  0.25     6.07      0.02        5     3.00    21.80  ActiveSupport::Callbacks::CallbackChain#compile
  0.25     6.08      0.01      792     0.02     0.02  Hash#key?
  0.00     6.08      0.00        1     0.00  6084.00  Object#profile_me
  0.00     6.08      0.00        4     0.00    27.00  Module#local_constants
  0.00     6.08      0.00        1     0.00   312.00  ActiveSupport::Dependencies.load_file
  0.00     6.08      0.00        9     0.00     0.00  Kernel.nil?
  0.00     6.08      0.00       11     0.00     0.00  Module#const_defined?
  0.00     6.08      0.00       10     0.00    14.00  Array#collect
  0.00     6.08      0.00        4     0.00     0.00  Kernel.Array
  0.00     6.08      0.00        1     0.00    94.00  ActiveModel::Validations::ClassMethods.validates_confirmation_of
  0.00     6.08      0.00       24     0.00     0.00  Array#wrap
  0.00     6.08      0.00      107     0.00     0.00  Hash#[]
  0.00     6.08      0.00       28     0.00     0.00  Module#constants
  0.00     6.08      0.00        1     0.00   312.00  ActiveSupport::Dependencies.require_or_load
  0.00     6.08      0.00        5     0.00     0.00  ActiveSupport::Callbacks::Callback#normalize_options!
  0.00     6.08      0.00       29     0.00     0.00  Hash#default
  0.00     6.08      0.00        2     0.00     0.00  Array#blank?
  0.00     6.08      0.00        2     0.00     0.00  ActiveSupport::Dependencies.autoloaded_constants
  0.00     6.08      0.00        2     0.00     0.00  Module#attr_accessor
  0.00     6.08      0.00       10     0.00     0.00  ActiveSupport::Callbacks::Callback#_compile_options
  0.00     6.08      0.00       13     0.00     1.23  Module#class_eval
  0.00     6.08      0.00        5     0.00     0.00  Kernel.block_given?
  0.00     6.08      0.00       13     0.00     0.00  ActiveRecord::Base#_removed_validate_callbacks
  0.00     6.08      0.00        7     0.00     0.00  Array#extract_options!
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.loadable_constants_for_path
  0.00     6.08      0.00        6     0.00     0.00  ActiveSupport::Dependencies.constant_watch_stack_mutex
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.to_constant_name
  0.00     6.08      0.00       11     0.00     0.00  ActiveRecord::DynamicScopeMatch#match
  0.00     6.08      0.00        1     0.00    16.00  ActiveRecord::Base#after_destroy
  0.00     6.08      0.00        2     0.00     0.00  Kernel.singleton_method_added
  0.00     6.08      0.00        1     0.00     0.00  String#size
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.warnings_on_first_load
  0.00     6.08      0.00      466     0.00     0.00  Kernel.==
  0.00     6.08      0.00        2     0.00     0.00  Kernel.equal?
  0.00     6.08      0.00        7     0.00     0.00  Array#delete_if
  0.00     6.08      0.00        4     0.00    35.00  Module#local_constant_names
  0.00     6.08      0.00        1     0.00     0.00  Symbol#===
  0.00     6.08      0.00        1     0.00     0.00  Digest::Base#update
  0.00     6.08      0.00        8     0.00     0.00  Object#duplicable?
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Inflector.camelize
  0.00     6.08      0.00        5     0.00     0.00  Hash#update
  0.00     6.08      0.00        1     0.00     0.00  String#underscore
  0.00     6.08      0.00        1     0.00     0.00  String#camelize
  0.00     6.08      0.00        5     0.00     0.00  Kernel.silence_warnings
  0.00     6.08      0.00        1     0.00     0.00  Kernel.require
  0.00     6.08      0.00        3     0.00     0.00  ActiveModel::Validator#initialize
  0.00     6.08      0.00        1     0.00     0.00  Digest::Class#digest
  0.00     6.08      0.00        1     0.00     0.00  Object#initialize
  0.00     6.08      0.00        4     0.00     0.00  ActiveRecord::Base#_destroy_superclass_callbacks
  0.00     6.08      0.00        2     0.00     0.00  Set#include?
  0.00     6.08      0.00        2     0.00     0.00  ActiveRecord::Base#_update_destroy_superclass_callbacks
  0.00     6.08      0.00        3     0.00    41.67  ActiveModel::Validations::ClassMethods.validates_with
  0.00     6.08      0.00       11     0.00     0.00  ActiveSupport::Callbacks::Callback#end
  0.00     6.08      0.00       14     0.00     0.00  Array#first
  0.00     6.08      0.00        9     0.00     0.00  ActiveSupport::Dependencies.logger
  0.00     6.08      0.00        6     0.00     0.00  Enumerable.inject
  0.00     6.08      0.00       13     0.00     0.00  Kernel.dup
  0.00     6.08      0.00       23     0.00     0.00  Module#===
  0.00     6.08      0.00        2     0.00     0.00  Digest::Base#reset
  0.00     6.08      0.00        3     0.00     0.00  Module#define_method
  0.00     6.08      0.00        1     0.00     0.00  Exception#initialize
  0.00     6.08      0.00        3     0.00     0.00  File#file?
  0.00     6.08      0.00        4     0.00     0.00  Array#flatten
  0.00     6.08      0.00        5     0.00     0.00  ActiveSupport::Dependencies.qualified_const_defined?
  0.00     6.08      0.00        6     0.00     0.00  Mutex#synchronize
  0.00     6.08      0.00        1     0.00     0.00  Array#shift
  0.00     6.08      0.00        4     0.00    35.00  ActiveModel::Validations::ClassMethods.validate
  0.00     6.08      0.00        5     0.00     0.00  Kernel.with_warnings
  0.00     6.08      0.00        1     0.00     0.00  String#downcase
  0.00     6.08      0.00        2     0.00   202.50  ActiveSupport::Dependencies.new_constants_in
  0.00     6.08      0.00        2     0.00     0.00  ActiveSupport::Dependencies.mechanism
  0.00     6.08      0.00       97     0.00     0.00  Symbol#to_s
  0.00     6.08      0.00        2     0.00     0.00  Array#to_ary
  0.00     6.08      0.00        5     0.00     0.00  Symbol#inspect
  0.00     6.08      0.00        5     0.00     9.40  ActiveSupport::Callbacks::Callback#initialize
  0.00     6.08      0.00       25     0.00     0.64  ActiveRecord::Callbacks::ClassMethods.method_added
  0.00     6.08      0.00       25     0.00     0.00  Symbol#to_sym
  0.00     6.08      0.00       25     0.00     0.00  Module#method_added
  0.00     6.08      0.00       16     0.00     0.00  ActiveRecord::Base#_validate_superclass_callbacks
  0.00     6.08      0.00        2     0.00     0.00  ActiveSupport::Dependencies.load?
  0.00     6.08      0.00        8     0.00     0.00  Hash#delete
  0.00     6.08      0.00        1     0.00     0.00  Hash#each
  0.00     6.08      0.00        9     0.00     0.00  Array#push
  0.00     6.08      0.00        1     0.00     0.00  TrueClass#duplicable?
  0.00     6.08      0.00        2     0.00     0.00  Set#<<
  0.00     6.08      0.00        5     0.00     0.00  ActiveSupport::Dependencies.log_call
  0.00     6.08      0.00        3     0.00     0.00  Class#inheritable_attributes
  0.00     6.08      0.00        4     0.00     0.00  ActiveSupport::Inflector.constantize
  0.00     6.08      0.00        7     0.00     2.29  ActiveSupport::Callbacks::Callback#_compile_filter
  0.00     6.08      0.00        1     0.00     0.00  Array#uniq
  0.00     6.08      0.00        1     0.00   265.00  Kernel.load_without_new_constant_marking
  0.00     6.08      0.00       11     0.00     0.00  ActiveSupport::Callbacks::Callback#start
  0.00     6.08      0.00        3     0.00     0.00  Array#*
  0.00     6.08      0.00        9     0.00     0.00  String#split
  0.00     6.08      0.00        1     0.00     0.00  Digest::Base#finish
  0.00     6.08      0.00        1     0.00   312.00  ActiveSupport::Dependencies::ModuleConstMissing.const_missing
  0.00     6.08      0.00        2     0.00     0.00  ActiveSupport::Dependencies.load_paths
  0.00     6.08      0.00        4     0.00     0.00  Hash#merge
  0.00     6.08      0.00       31     0.00     1.52  Class#new
  0.00     6.08      0.00        2     0.00     0.00  Class#inherited
  0.00     6.08      0.00        1     0.00    16.00  ActiveRecord::Validations::ClassMethods.validates_uniqueness_of
  0.00     6.08      0.00        3     0.00     0.00  ActiveSupport::Callbacks::Callback#name
  0.00     6.08      0.00        3     0.00     0.00  ActiveSupport::Callbacks::Callback#_normalize_legacy_filter
  0.00     6.08      0.00       20     0.00     0.00  Fixnum#+
  0.00     6.08      0.00        7     0.00     0.00  Regexp#escape
  0.00     6.08      0.00        7     0.00     0.00  Array#pop
  0.00     6.08      0.00        1     0.00  5772.00  User#encrypted_password
  0.00     6.08      0.00        1     0.00     0.00  Digest::Instance.digest
  0.00     6.08      0.00       20     0.00     0.00  Array#join
  0.00     6.08      0.00       12     0.00     0.00  ActiveSupport::Callbacks::Callback#next_id
  0.00     6.08      0.00       39     0.00     0.00  Kernel.respond_to?
  0.00     6.08      0.00        6     0.00     0.00  ActiveSupport::Dependencies.constant_watch_stack
  0.00     6.08      0.00       58     0.00     0.00  Fixnum#==
  0.00     6.08      0.00        1     0.00     0.00  Digest::Class#hexdigest
  0.00     6.08      0.00        7     0.00     0.00  ActiveRecord::Base#_destroy_callbacks
  0.00     6.08      0.00        3     0.00     0.00  ActiveModel::EachValidator#initialize
  0.00     6.08      0.00        3     0.00     0.00  String#[]
  0.00     6.08      0.00        3     0.00     0.00  ActiveModel::EachValidator#check_validity!
  0.00     6.08      0.00        3     0.00     0.00  ActiveModel::Validations::ClassMethods._merge_attributes
  0.00     6.08      0.00       11     0.00     0.00  ActiveRecord::Base#respond_to?
  0.00     6.08      0.00        2     0.00     0.00  String#+
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.load_once_path?
  0.00     6.08      0.00        5     0.00    31.20  ActiveSupport::Callbacks::ClassMethods.set_callback
  0.00     6.08      0.00        6     0.00     0.00  Module#private
  0.00     6.08      0.00       13     0.00     0.00  String#==
  0.00     6.08      0.00        1     0.00     0.00  Enumerable.any?
  0.00     6.08      0.00        5     0.00     0.00  NilClass#to_s
  0.00     6.08      0.00        1     0.00   109.00  ActiveSupport::Dependencies::Loadable.require
  0.00     6.08      0.00        4     0.00     0.00  Module#ancestors
  0.00     6.08      0.00        1     0.00   312.00  ActiveSupport::Dependencies::ClassConstMissing.const_missing
  0.00     6.08      0.00        1     0.00    15.00  ActiveModel::Validations::ClassMethods.validates_presence_of
  0.00     6.08      0.00        5     0.00     9.40  Array#map!
  0.00     6.08      0.00       29     0.00     0.00  Module#==
  0.00     6.08      0.00        2     0.00     0.00  Kernel.instance_variable_set
  0.00     6.08      0.00        1     0.00     0.00  String#upcase
  0.00     6.08      0.00        1     0.00   312.00  ActiveSupport::Dependencies.load_missing_constant
  0.00     6.08      0.00        5     0.00    21.80  ActiveSupport::Callbacks::ClassMethods.__define_runner
  0.00     6.08      0.00       32     0.00     0.00  Kernel.send
  0.00     6.08      0.00        8     0.00     0.00  ActiveRecord::Base#_update_validate_superclass_callbacks
  0.00     6.08      0.00        1     0.00     0.00  String#tr
  0.00     6.08      0.00       11     0.00     0.00  ActiveRecord::DynamicFinderMatch#match
  0.00     6.08      0.00       11     0.00     0.00  ActiveRecord::DynamicFinderMatch#initialize
  0.00     6.08      0.00        3     0.00     0.00  ActiveSupport::Dependencies.loaded
  0.00     6.08      0.00        1     0.00     0.00  ActiveRecord::Validations::UniquenessValidator#setup
  0.00     6.08      0.00        5     0.00     0.00  String#gsub
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.search_for_file
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Inflector.underscore
  0.00     6.08      0.00        1     0.00     0.00  Hash#reverse_merge
  0.00     6.08      0.00       25     0.00     0.00  ActiveRecord::Base#_validate_callbacks
  0.00     6.08      0.00        3     0.00     0.00  File#join
  0.00     6.08      0.00        6     0.00     0.00  Module#name
  0.00     6.08      0.00       20     0.00     0.00  NilClass#nil?
  0.00     6.08      0.00        1     0.00     0.00  NameError#initialize
  0.00     6.08      0.00       66     0.00     0.00  Kernel.object_id
  0.00     6.08      0.00        7     0.00     0.00  Array#initialize_copy
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.history
  0.00     6.08      0.00       27     0.00     0.00  Array#[]
  0.00     6.08      0.00        1     0.00     0.00  Array#unshift
  0.00     6.08      0.00        9     0.00     0.00  String#empty?
  0.00     6.08      0.00        1     0.00     0.00  Observable.notify_observers
  0.00     6.08      0.00       44     0.00     0.00  Class#superclass
  0.00     6.08      0.00       10     0.00     0.00  File#expand_path
  0.00     6.08      0.00        1     0.00     0.00  NilClass#to_a
  0.00     6.08      0.00        5     0.00     0.00  Module#method_defined?
  0.00     6.08      0.00       11     0.00     0.00  ActiveRecord::DynamicScopeMatch#initialize
  0.00     6.08      0.00        3     0.00     0.00  String#blank?
  0.00     6.08      0.00       33     0.00     0.00  Kernel.hash
  0.00     6.08      0.00       21     0.00     0.00  Module#const_get
  0.00     6.08      0.00        1     0.00     0.00  Array#uniq!
  0.00     6.08      0.00        1     0.00     0.00  ActiveModel::Validations::ConfirmationValidator#setup
  0.00     6.08      0.00        6     0.00     0.00  ActiveSupport::Callbacks::Callback#matches?
  0.00     6.08      0.00        1     0.00     0.00  ActiveRecord::Validations::UniquenessValidator#initialize
  0.00     6.08      0.00        8     0.00     0.00  Array#concat
  0.00     6.08      0.00       22     0.00     0.00  Array#-
  0.00     6.08      0.00        5     0.00    31.20  ActiveSupport::Callbacks::ClassMethods.__update_callbacks
  0.00     6.08      0.00        1     0.00     0.00  ActiveRecord::Base#inherited
  0.00     6.08      0.00        1     0.00     0.00  ActiveModel::Observing::ClassMethods.inherited
  0.00     6.08      0.00        1     0.00     0.00  Observable.changed
  0.00     6.08      0.00        2     0.00     0.00  Hash#include?
  0.00     6.08      0.00       37     0.00     0.00  Hash#[]=
  0.00     6.08      0.00       10     0.00     0.00  Array#+
  0.00     6.08      0.00        4     0.00     0.00  ActiveSupport::Dependencies.log
  0.00     6.08      0.00       10     0.00     0.00  Hash#initialize_copy
  0.00     6.08      0.00        7     0.00     0.00  ActiveSupport::Dependencies.uninherited_const_defined?
  0.00     6.08      0.00       29     0.00     0.00  Array#empty?
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.load_once_paths
  0.00     6.08      0.00        4     0.00     0.00  ActiveRecord::Base#_removed_destroy_callbacks
  0.00     6.08      0.00       44     0.00     0.00  Regexp#===
  0.00     6.08      0.00       16     0.00     0.00  Array#last
  0.00     6.08      0.00        1     0.00     0.00  Kernel.gem_original_require
  0.00     6.08      0.00        1     0.00     0.00  ActiveSupport::Dependencies.qualified_name_for
  0.00     6.08      0.00       18     0.00     0.00  Array#compact
  0.00     6.08      0.00        1     0.00  6084.00  #toplevel
edit app/models/user.rb

15 Rails In Depth

rake db:version
(in /home/rubys/git/awdwr/work/depot)
Current version: 20100301000007
edit lib/tasks/db_schema_migrations.rake
namespace :db do
  desc "Prints the migrated versions"
  task :schema_migrations => :environment do
    puts ActiveRecord::Base.connection.select_values(
      'select version from schema_migrations order by version' )
  end
end
rake db:schema_migrations
(in /home/rubys/git/awdwr/work/depot)
20100301000001
20100301000002
20100301000003
20100301000004
20100301000005
20100301000006
20100301000007
ls log
development.log
production.log
server.log
test.log
find script -type f
script/about
script/console
script/dbconsole
script/destroy
script/generate
script/performance/benchmarker
script/performance/profiler
script/plugin
script/runner
script/server
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> puts $:
/usr/lib/ruby/gems/1.8/gems/mail-2.1.2/lib/mail/vendor/treetop-1.4.3/lib
/home/rubys/git/awdwr/work/depot/app/controllers
/home/rubys/git/awdwr/work/depot/app/helpers
/home/rubys/git/awdwr/work/depot/app/models
/home/rubys/git/awdwr/work/depot/app/views
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/builtin/rails_info
/home/rubys/git/awdwr/work/depot/lib
/home/rubys/git/awdwr/work/depot/vendor
/home/rubys/git/awdwr/work/depot/vendor/rails/railties/lib
/home/rubys/git/awdwr/work/depot/vendor/rails/activesupport/lib
/home/rubys/git/awdwr/work/depot/vendor/rails/activeresource/lib
/home/rubys/git/awdwr/work/depot/vendor/rails/activerecord/lib
/home/rubys/git/awdwr/work/depot/vendor/rails/activemodel/lib
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib
/home/rubys/git/awdwr/work/depot/vendor/rails/actionmailer/lib
/home/rubys/git/gorp/lib
/home/rubys/git/arel/lib
/home/rubys/git/rack/lib
/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin
/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib
/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin
/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib
/usr/lib/ruby/gems/1.8/gems/rack-1.1.0/bin
/usr/lib/ruby/gems/1.8/gems/rack-1.1.0/lib
/usr/lib/ruby/gems/1.8/gems/rack-mount-0.4.5/bin
/usr/lib/ruby/gems/1.8/gems/rack-mount-0.4.5/lib
/usr/lib/ruby/gems/1.8/gems/mime-types-1.16/bin
/usr/lib/ruby/gems/1.8/gems/mime-types-1.16/lib
/usr/lib/ruby/gems/1.8/gems/mail-2.1.2/bin
/usr/lib/ruby/gems/1.8/gems/mail-2.1.2/lib
/usr/lib/ruby/gems/1.8/gems/abstract-1.0.0/bin
/usr/lib/ruby/gems/1.8/gems/abstract-1.0.0/lib
/usr/lib/ruby/gems/1.8/gems/erubis-2.6.5/bin
/usr/lib/ruby/gems/1.8/gems/erubis-2.6.5/lib
/usr/lib/ruby/site_ruby/1.8
/usr/lib/ruby/site_ruby/1.8/i386-cygwin
/usr/lib/ruby/site_ruby
/usr/lib/ruby/vendor_ruby/1.8
/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin
/usr/lib/ruby/vendor_ruby
/usr/lib/ruby/1.8
/usr/lib/ruby/1.8/i386-cygwin
.
/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner
/usr/lib/ruby/gems/1.8/gems/rack-mount-0.4.5/lib/rack/mount/vendor/multimap
/usr/lib/ruby/gems/1.8/gems/rack-mount-0.4.5/lib/rack/mount/vendor/reginald
=> nil
>> 

16 Active Support

ruby /home/rubys/git/rails/railties/bin/rails namelist
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
Namelist::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end

Restart the server.

ruby script/generate model person name:string
      invoke  active_record
      create    db/migrate/20100202190741_create_people.rb
      create    app/models/person.rb
      invoke    test_unit
      create      test/unit/person_test.rb
      create      test/fixtures/people.yml
rake db:migrate
mv 20100202190741_create_people.rb 20100301000001_create_people.rb
(in /home/rubys/git/awdwr/work/namelist)
==  CreatePeople: migrating ===================================================
-- create_table(:people)
   -> 0.0000s
==  CreatePeople: migrated (0.0000s) ==========================================
 
edit app/controllers/people_controller.rb
class PeopleController < ApplicationController
 
  def index
    @person = Person.new(params[:person])
    @person.save! if request.post?
    @people = Person.find(:all)
  end
end
edit app/views/layouts/people.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"></meta>
    <title>My Name List</title>
  </head>
  <body>
    <%= yield :layout %>
  </body>
</html>
mkdir app/views/people
edit app/views/people/index.html.erb
<table border="1">
  <tr>
    <th>Name</th><th>bytes</th><th>chars</th><th>reversed</th>
  </tr>
  <% for person in @people %>
    <tr>  
      <td><%=h person.name %></td>
      <td><%= person.name.length %></td>
      <td><%= person.name.chars.length %></td>
      <td><%=h person.name.chars.reverse %></td>
    </tr>
  <% end %>
</table>
 
<% form_for :person do |form| %>
  New name: <%= form.text_field :name %>
  <%= submit_tag "Add" %>
<% end %>
get /people
Namebytescharsreversed
New name:
post /people

NoMethodError in People#index

Showing /home/rubys/git/awdwr/work/namelist/app/views/people/index.html.erb where line #9 raised:

undefined method `length' for #<Enumerable::Enumerator:0x7e30068c>

Extracted source (around line #9):

6:     <tr>  
7:       <td><%=h person.name %></td>
8:       <td><%= person.name.length %></td>
9:       <td><%= person.name.chars.length %></td>
10:       <td><%=h person.name.chars.reverse %></td>
11:     </tr>
12:   <% end %>

Rails.root: /home/rubys/git/awdwr/work/namelist

Application Trace | Framework Trace | Full Trace

Request

Parameters:

{"person"=>{"name"=>"Dave"},
 "authenticity_token"=>"cy+g752tc1O1LoFQpfG+pfeicsL5vGCvHFKCsLyTcD0="}

Show session dump

Show env dump

Response

Headers:

None

get /people

NoMethodError in People#index

Showing /home/rubys/git/awdwr/work/namelist/app/views/people/index.html.erb where line #9 raised:

undefined method `length' for #<Enumerable::Enumerator:0x7e704b20>

Extracted source (around line #9):

6:     <tr>  
7:       <td><%=h person.name %></td>
8:       <td><%= person.name.length %></td>
9:       <td><%= person.name.chars.length %></td>
10:       <td><%=h person.name.chars.reverse %></td>
11:     </tr>
12:   <% end %>

Rails.root: /home/rubys/git/awdwr/work/namelist

Application Trace | Framework Trace | Full Trace

Request

Parameters:

None

Show session dump

Show env dump

Response

Headers:

None

sqlite3> select name,length(name) from people where name like 'G%'

17 Migration

ruby /home/rubys/git/rails/railties/bin/rails migration
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
Migration::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
cp -rpv /home/rubys/git/awdwr/plugins/* vendor/plugins/
`/home/rubys/git/awdwr/plugins/MANIFEST' -> `vendor/plugins/MANIFEST'
`/home/rubys/git/awdwr/plugins/acts_as_list' -> `vendor/plugins/acts_as_list'
`/home/rubys/git/awdwr/plugins/acts_as_list/init.rb' -> `vendor/plugins/acts_as_list/init.rb'
`/home/rubys/git/awdwr/plugins/acts_as_list/lib' -> `vendor/plugins/acts_as_list/lib'
`/home/rubys/git/awdwr/plugins/acts_as_list/lib/active_record' -> `vendor/plugins/acts_as_list/lib/active_record'
`/home/rubys/git/awdwr/plugins/acts_as_list/lib/active_record/acts' -> `vendor/plugins/acts_as_list/lib/active_record/acts'
`/home/rubys/git/awdwr/plugins/acts_as_list/lib/active_record/acts/list.rb' -> `vendor/plugins/acts_as_list/lib/active_record/acts/list.rb'
`/home/rubys/git/awdwr/plugins/acts_as_list/README' -> `vendor/plugins/acts_as_list/README'
`/home/rubys/git/awdwr/plugins/acts_as_list/test' -> `vendor/plugins/acts_as_list/test'
`/home/rubys/git/awdwr/plugins/acts_as_list/test/list_test.rb' -> `vendor/plugins/acts_as_list/test/list_test.rb'
`/home/rubys/git/awdwr/plugins/acts_as_tree' -> `vendor/plugins/acts_as_tree'
`/home/rubys/git/awdwr/plugins/acts_as_tree/init.rb' -> `vendor/plugins/acts_as_tree/init.rb'
`/home/rubys/git/awdwr/plugins/acts_as_tree/lib' -> `vendor/plugins/acts_as_tree/lib'
`/home/rubys/git/awdwr/plugins/acts_as_tree/lib/active_record' -> `vendor/plugins/acts_as_tree/lib/active_record'
`/home/rubys/git/awdwr/plugins/acts_as_tree/lib/active_record/acts' -> `vendor/plugins/acts_as_tree/lib/active_record/acts'
`/home/rubys/git/awdwr/plugins/acts_as_tree/lib/active_record/acts/tree.rb' -> `vendor/plugins/acts_as_tree/lib/active_record/acts/tree.rb'
`/home/rubys/git/awdwr/plugins/acts_as_tree/Rakefile' -> `vendor/plugins/acts_as_tree/Rakefile'
`/home/rubys/git/awdwr/plugins/acts_as_tree/README' -> `vendor/plugins/acts_as_tree/README'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test' -> `vendor/plugins/acts_as_tree/test'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test/abstract_unit.rb' -> `vendor/plugins/acts_as_tree/test/abstract_unit.rb'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test/acts_as_tree_test.rb' -> `vendor/plugins/acts_as_tree/test/acts_as_tree_test.rb'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test/database.yml' -> `vendor/plugins/acts_as_tree/test/database.yml'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test/fixtures' -> `vendor/plugins/acts_as_tree/test/fixtures'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test/fixtures/mixin.rb' -> `vendor/plugins/acts_as_tree/test/fixtures/mixin.rb'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test/fixtures/mixins.yml' -> `vendor/plugins/acts_as_tree/test/fixtures/mixins.yml'
`/home/rubys/git/awdwr/plugins/acts_as_tree/test/schema.rb' -> `vendor/plugins/acts_as_tree/test/schema.rb'
`/home/rubys/git/awdwr/plugins/annotate_models' -> `vendor/plugins/annotate_models'
`/home/rubys/git/awdwr/plugins/annotate_models/ChangeLog' -> `vendor/plugins/annotate_models/ChangeLog'
`/home/rubys/git/awdwr/plugins/annotate_models/lib' -> `vendor/plugins/annotate_models/lib'
`/home/rubys/git/awdwr/plugins/annotate_models/lib/annotate_models.rb' -> `vendor/plugins/annotate_models/lib/annotate_models.rb'
`/home/rubys/git/awdwr/plugins/annotate_models/README' -> `vendor/plugins/annotate_models/README'
`/home/rubys/git/awdwr/plugins/annotate_models/tasks' -> `vendor/plugins/annotate_models/tasks'
`/home/rubys/git/awdwr/plugins/annotate_models/tasks/annotate_models_tasks.rake' -> `vendor/plugins/annotate_models/tasks/annotate_models_tasks.rake'
`/home/rubys/git/awdwr/plugins/country_select' -> `vendor/plugins/country_select'
`/home/rubys/git/awdwr/plugins/country_select/init.rb' -> `vendor/plugins/country_select/init.rb'
`/home/rubys/git/awdwr/plugins/country_select/install.rb' -> `vendor/plugins/country_select/install.rb'
`/home/rubys/git/awdwr/plugins/country_select/lib' -> `vendor/plugins/country_select/lib'
`/home/rubys/git/awdwr/plugins/country_select/lib/country_select.rb' -> `vendor/plugins/country_select/lib/country_select.rb'
`/home/rubys/git/awdwr/plugins/country_select/MIT-LICENSE' -> `vendor/plugins/country_select/MIT-LICENSE'
`/home/rubys/git/awdwr/plugins/country_select/README' -> `vendor/plugins/country_select/README'
`/home/rubys/git/awdwr/plugins/country_select/uninstall.rb' -> `vendor/plugins/country_select/uninstall.rb'

Restart the server.

cp -v -r ../depot/db/* db/
`../depot/db/development.sqlite3' -> `db/development.sqlite3'
`../depot/db/migrate' -> `db/migrate'
`../depot/db/migrate/20100301000001_create_products.rb' -> `db/migrate/20100301000001_create_products.rb'
`../depot/db/migrate/20100301000002_add_price_to_product.rb' -> `db/migrate/20100301000002_add_price_to_product.rb'
`../depot/db/migrate/20100301000003_add_test_data.rb' -> `db/migrate/20100301000003_add_test_data.rb'
`../depot/db/migrate/20100301000004_add_sessions_table.rb' -> `db/migrate/20100301000004_add_sessions_table.rb'
`../depot/db/migrate/20100301000005_create_orders.rb' -> `db/migrate/20100301000005_create_orders.rb'
`../depot/db/migrate/20100301000006_create_line_items.rb' -> `db/migrate/20100301000006_create_line_items.rb'
`../depot/db/migrate/20100301000007_create_users.rb' -> `db/migrate/20100301000007_create_users.rb'
`../depot/db/schema.rb' -> `db/schema.rb'
`../depot/db/seeds.rb' -> `db/seeds.rb'
`../depot/db/test.sqlite3' -> `db/test.sqlite3'
cp -v -r ../depot/app/models/* app/models/
`../depot/app/models/cart.rb' -> `app/models/cart.rb'
`../depot/app/models/cart_item.rb' -> `app/models/cart_item.rb'
`../depot/app/models/line_item.rb' -> `app/models/line_item.rb'
`../depot/app/models/order.rb' -> `app/models/order.rb'
`../depot/app/models/product.rb' -> `app/models/product.rb'
`../depot/app/models/user.rb' -> `app/models/user.rb'
ruby script/generate model discount
      invoke  active_record
      create    db/migrate/20100202190839_create_discounts.rb
      create    app/models/discount.rb
      invoke    test_unit
      create      test/unit/discount_test.rb
      create      test/fixtures/discounts.yml
ruby script/generate migration add_status_to_user status:string
      invoke  active_record
      create    db/migrate/20100202190856_add_status_to_user.rb
rake db:migrate
mv 20100202190839_create_discounts.rb 20100301000008_create_discounts.rb
mv 20100202190856_add_status_to_user.rb 20100301000009_add_status_to_user.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  CreateDiscounts: migrating ================================================
-- create_table(:discounts)
   -> 0.0000s
==  CreateDiscounts: migrated (0.0000s) =======================================
 
==  AddStatusToUser: migrating ================================================
-- add_column(:users, :status, :string)
   -> 0.0000s
==  AddStatusToUser: migrated (0.0000s) =======================================
 
cp -v /home/rubys/git/awdwr/data/migrate/020* db/migrate
`/home/rubys/git/awdwr/data/migrate/020_add_email_to_orders.rb' -> `db/migrate/020_add_email_to_orders.rb'
rake db:migrate
mv 020_add_email_to_orders.rb 20100301000010_add_email_to_orders.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  AddEmailToOrders: migrating ===============================================
-- add_column(:orders, :e_mail, :string)
   -> 0.0160s
==  AddEmailToOrders: migrated (0.0160s) ======================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000010
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/021* db/migrate
`/home/rubys/git/awdwr/data/migrate/021_add_placed_at_to_orders.rb' -> `db/migrate/021_add_placed_at_to_orders.rb'
rake db:migrate
mv 021_add_placed_at_to_orders.rb 20100301000011_add_placed_at_to_orders.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  AddPlacedAtToOrders: migrating ============================================
-- add_column(:orders, :placed_at, :datetime, {:default=>Tue Feb 02 14:10:06 -0500 2010})
   -> 0.0470s
==  AddPlacedAtToOrders: migrated (0.0470s) ===================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000011
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/022* db/migrate
`/home/rubys/git/awdwr/data/migrate/022_add_columns_to_orders.rb' -> `db/migrate/022_add_columns_to_orders.rb'
rake db:migrate
mv 022_add_columns_to_orders.rb 20100301000012_add_columns_to_orders.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  AddColumnsToOrders: migrating =============================================
-- add_column(:orders, :attn, :string, {:limit=>100})
   -> 0.0160s
-- add_column(:orders, :order_type, :integer)
   -> 0.0000s
-- add_column(:orders, :ship_class, :string, {:default=>"priority", :null=>false})
   -> 0.0000s
-- add_column(:orders, :amount, :decimal, {:precision=>8, :scale=>2})
   -> 0.0000s
-- add_column(:orders, :state, :string, {:limit=>2})
   -> 0.0000s
==  AddColumnsToOrders: migrated (0.0160s) ====================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000012
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/023* db/migrate
`/home/rubys/git/awdwr/data/migrate/023_rename_email_column.rb' -> `db/migrate/023_rename_email_column.rb'
rake db:migrate
mv 023_rename_email_column.rb 20100301000013_rename_email_column.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  RenameEmailColumn: migrating ==============================================
-- rename_column(:orders, :e_mail, :customer_email)
   -> 0.0780s
==  RenameEmailColumn: migrated (0.0780s) =====================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000013
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/024* db/migrate
`/home/rubys/git/awdwr/data/migrate/024_change_order_type_to_string.rb' -> `db/migrate/024_change_order_type_to_string.rb'
rake db:migrate
mv 024_change_order_type_to_string.rb 20100301000014_change_order_type_to_string.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  ChangeOrderTypeToString: migrating ========================================
-- change_column(:orders, :order_type, :string)
   -> 0.0780s
==  ChangeOrderTypeToString: migrated (0.0780s) ===============================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000014
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/025* db/migrate
`/home/rubys/git/awdwr/data/migrate/025_create_order_histories.rb' -> `db/migrate/025_create_order_histories.rb'
rake db:migrate
mv 025_create_order_histories.rb 20100301000015_create_order_histories.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  CreateOrderHistories: migrating ===========================================
-- create_table(:order_histories)
   -> 0.0000s
==  CreateOrderHistories: migrated (0.0000s) ==================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000015
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/026* db/migrate
`/home/rubys/git/awdwr/data/migrate/026_create_table_tickets.rb' -> `db/migrate/026_create_table_tickets.rb'
rake db:migrate
mv 026_create_table_tickets.rb 20100301000016_create_table_tickets.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
rake aborted!
An error has occurred, this and all later migrations canceled:

    
SQLite3::SQLException: near "auto_increment": syntax error: CREATE TABLE "tickets" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "description" text, "text" text, "created_at" datetime, "updated_at" datetime) auto_increment = 10000

    
(See full trace by running task with --trace)
(in /home/rubys/git/awdwr/work/migration)
==  CreateTableTickets: migrating =============================================
-- create_table(:tickets, {:options=>"auto_increment = 10000"})
rm db/migrate/20100301000016_create_table_tickets.rb
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000015
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/027* db/migrate
`/home/rubys/git/awdwr/data/migrate/027_rename_order_histories.rb' -> `db/migrate/027_rename_order_histories.rb'
rake db:migrate
mv 027_rename_order_histories.rb 20100301000016_rename_order_histories.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  RenameOrderHistories: migrating ===========================================
-- rename_table(:order_histories, :order_notes)
   -> 0.0000s
==  RenameOrderHistories: migrated (0.0000s) ==================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000016
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/028* db/migrate
`/home/rubys/git/awdwr/data/migrate/028_create_order_histories2.rb' -> `db/migrate/028_create_order_histories2.rb'
rake db:migrate
mv 028_create_order_histories2.rb 20100301000017_create_order_histories2.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  CreateOrderHistories2: migrating ==========================================
-- create_table(:order_histories)
   -> 0.0000s
==  CreateOrderHistories2: migrated (0.0930s) =================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000017
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/029* db/migrate
`/home/rubys/git/awdwr/data/migrate/029_add_customer_name_index_to_orders.rb' -> `db/migrate/029_add_customer_name_index_to_orders.rb'
rake db:migrate
mv 029_add_customer_name_index_to_orders.rb 20100301000018_add_customer_name_index_to_orders.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  AddCustomerNameIndexToOrders: migrating ===================================
-- add_index(:orders, :name)
   -> 0.0000s
==  AddCustomerNameIndexToOrders: migrated (0.0000s) ==========================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000018
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/030* db/migrate
`/home/rubys/git/awdwr/data/migrate/030_create_author_book.rb' -> `db/migrate/030_create_author_book.rb'
rake db:migrate
mv 030_create_author_book.rb 20100301000019_create_author_book.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  CreateAuthorBook: migrating ===============================================
-- create_table(:authors_books, {:id=>false})
   -> 0.0000s
==  CreateAuthorBook: migrated (0.0000s) ======================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000019
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/031* db/migrate
`/home/rubys/git/awdwr/data/migrate/031_create_table_tickets.rb' -> `db/migrate/031_create_table_tickets.rb'
rake db:migrate
mv 031_create_table_tickets.rb 20100301000020_create_table_tickets.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  CreateTableTickets: migrating =============================================
-- create_table(:tickets, {:primary_key=>:number})
   -> 0.0160s
==  CreateTableTickets: migrated (0.0160s) ====================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000020
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/032* db/migrate
`/home/rubys/git/awdwr/data/migrate/032_test_discounts.rb' -> `db/migrate/032_test_discounts.rb'
rake db:migrate
mv 032_test_discounts.rb 20100301000021_test_discounts.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
rake aborted!
An error has occurred, this and all later migrations canceled:

    
uninitialized constant TestDiscounts::Sku

    
(See full trace by running task with --trace)
(in /home/rubys/git/awdwr/work/migration)
==  TestDiscounts: migrating ==================================================
==  TestDiscounts: reverting ==================================================
==  TestDiscounts: reverted (0.0310s) =========================================
 
rm db/migrate/20100301000021_test_discounts.rb
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000020
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
mkdir db/migrate/dev_data
cp /home/rubys/git/awdwr/data/migrate/users.yml db/migrate/dev_data
rake db:migrate
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000020
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/034* db/migrate
`/home/rubys/git/awdwr/data/migrate/034_load_user_data.rb' -> `db/migrate/034_load_user_data.rb'
rake db:migrate
mv 034_load_user_data.rb 20100301000021_load_user_data.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  LoadUserData: migrating ===================================================
==  LoadUserData: reverting ===================================================
==  LoadUserData: reverted (0.1090s) ==========================================
 
==  LoadUserData: migrated (0.1560s) ==========================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000021
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  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        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/035* db/migrate
`/home/rubys/git/awdwr/data/migrate/035_change_price_to_integer.rb' -> `db/migrate/035_change_price_to_integer.rb'
rake db:migrate
mv 035_change_price_to_integer.rb 20100301000022_change_price_to_integer.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  ChangePriceToInteger: migrating ===========================================
-- change_column(:line_items, :total_price, :integer)
   -> 0.0160s
==  ChangePriceToInteger: migrated (0.0940s) ==================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000022
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  product_id  :integer         not null
#  order_id    :integer         not null
#  quantity    :integer         not null
#  total_price :integer         not null
#  created_at  :datetime        
#  updated_at  :datetime        
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/036* db/migrate
`/home/rubys/git/awdwr/data/migrate/036_total_price_to_unit.rb' -> `db/migrate/036_total_price_to_unit.rb'
rake db:migrate
mv 036_total_price_to_unit.rb 20100301000023_total_price_to_unit.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  TotalPriceToUnit: migrating ===============================================
-- add_column(:line_items, :unit_price, :decimal, {:precision=>8, :scale=>2})
   -> 0.0000s
==  TotalPriceToUnit: migrated (0.0780s) ======================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000023
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  product_id  :integer         not null
#  order_id    :integer         not null
#  quantity    :integer         not null
#  total_price :integer         not null
#  created_at  :datetime        
#  updated_at  :datetime        
#  unit_price  :decimal(8, 2)   
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to
cp -v /home/rubys/git/awdwr/data/migrate/037* db/migrate
`/home/rubys/git/awdwr/data/migrate/037_add_foreign_key.rb' -> `db/migrate/037_add_foreign_key.rb'
cp -v /home/rubys/git/awdwr/data/migrate/migration_helpers.rb lib
`/home/rubys/git/awdwr/data/migrate/migration_helpers.rb' -> `lib/migration_helpers.rb'
rake db:migrate
mv 037_add_foreign_key.rb 20100301000024_add_foreign_key.rb
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
==  AddForeignKey: migrating ==================================================
-- execute("\n      CREATE TRIGGER fk_line_items_products_insert\n      BEFORE INSERT ON line_items\n      FOR EACH ROW BEGIN\n        SELECT \n\t  RAISE(ABORT, \"constraint violation: fk_line_items_products\")\n\tWHERE \n\t  (SELECT id FROM products WHERE id = NEW.product_id) IS NULL;\n      END;\n    ")
   -> 0.0000s
-- execute("\n      CREATE TRIGGER fk_line_items_products_update\n      BEFORE UPDATE ON line_items\n      FOR EACH ROW BEGIN\n        SELECT \n\t  RAISE(ABORT, \"constraint violation: fk_line_items_products\")\n\tWHERE \n\t  (SELECT id FROM products WHERE id = NEW.product_id) IS NULL;\n      END;\n    ")
   -> 0.0000s
-- execute("\n      CREATE TRIGGER fk_line_items_products_delete\n      BEFORE DELETE ON products\n      FOR EACH ROW BEGIN\n        SELECT \n\t  RAISE(ABORT, \"constraint violation: fk_line_items_products\")\n\tWHERE \n\t  (SELECT id FROM line_items WHERE product_id = OLD.id) IS NOT NULL;\n      END;\n    ")
   -> 0.0000s
-- execute("\n      CREATE TRIGGER fk_line_items_orders_insert\n      BEFORE INSERT ON line_items\n      FOR EACH ROW BEGIN\n        SELECT \n\t  RAISE(ABORT, \"constraint violation: fk_line_items_orders\")\n\tWHERE \n\t  (SELECT id FROM orders WHERE id = NEW.order_id) IS NULL;\n      END;\n    ")
   -> 0.0000s
-- execute("\n      CREATE TRIGGER fk_line_items_orders_update\n      BEFORE UPDATE ON line_items\n      FOR EACH ROW BEGIN\n        SELECT \n\t  RAISE(ABORT, \"constraint violation: fk_line_items_orders\")\n\tWHERE \n\t  (SELECT id FROM orders WHERE id = NEW.order_id) IS NULL;\n      END;\n    ")
   -> 0.0000s
-- execute("\n      CREATE TRIGGER fk_line_items_orders_delete\n      BEFORE DELETE ON orders\n      FOR EACH ROW BEGIN\n        SELECT \n\t  RAISE(ABORT, \"constraint violation: fk_line_items_orders\")\n\tWHERE \n\t  (SELECT id FROM line_items WHERE order_id = OLD.id) IS NOT NULL;\n      END;\n    ")
   -> 0.0000s
==  AddForeignKey: migrated (0.0000s) =========================================
 
rake annotate_models
DEPRECATION WARNING: Having rake tasks in PLUGIN_PATH/tasks or PLUGIN_PATH/rails/tasks is deprecated. Use to PLUGIN_PATH/lib/tasks instead. (called from load_tasks at /home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib/rails/plugin.rb:31)
(in /home/rubys/git/awdwr/work/migration)
Skipping Cart
Skipping CartItem
Annotating Discount
Annotating LineItem
Annotating Order
Annotating Product
Annotating User
cat app/models/line_item.rb
# == Schema Information
# Schema version: 20100301000024
#
# Table name: line_items
#
#  id          :integer         not null, primary key
#  product_id  :integer         not null
#  order_id    :integer         not null
#  quantity    :integer         not null
#  total_price :integer         not null
#  created_at  :datetime        
#  updated_at  :datetime        
#  unit_price  :decimal(8, 2)   
#
 
#START:belongs_to
class LineItem < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
#END:belongs_to
 
  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
 
#START:belongs_to
end
#END:belongs_to

18 Active Record: The Basics

IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Order.column_names
=> ["id", "name", "address", "email", "pay_type", "created_at", "updated_at", "customer_email", "placed_at", "attn", "order_type", "ship_class", "amount", "state"]
>> 
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Order.columns_hash["pay_type"]
=> #<ActiveRecord::ConnectionAdapters::SQLiteColumn:0x7e3d7830 @limit=10, @default=nil, @null=true, @scale=nil, @sql_type="varchar(10)", @precision=nil, @name="pay_type", @primary=false, @type=:string>
>> 
sqlite3> select * from orders limit 1
            id = 1
          name = Dave Thomas
       address = 123 Main St
         email = customer@example.com
      pay_type = check
    created_at = 2010-02-02 18:58:22.555600
    updated_at = 2010-02-02 18:58:22.555600
customer_email = 
     placed_at = 2010-02-02 19:10:06.583400
          attn = 
    order_type = 
    ship_class = priority
        amount = 
         state = 
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Product.find(:first).price_before_type_cast
=> "29.95"
>> 
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Product.find(:first).updated_at_before_type_cast
=> "2010-02-02 18:55:43.420000"
>> 
irb e1/ar/new_examples.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> class Order < ActiveRecord::Base
>> end
=> nil
 
?> an_order = Order.new
=> #<Order id: nil, name: nil, address: nil, email: nil, pay_type: nil, created_at: nil, updated_at: nil, customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
>> an_order.name     = "Dave Thomas"
=> "Dave Thomas"
>> an_order.email    = "dave@example.com"
=> "dave@example.com"
>> an_order.address  = "123 Main St"
=> "123 Main St"
>> an_order.pay_type = "check"
=> "check"
>> an_order.save
=> true
 
?> Order.new do |o|
?>   o.name     = "Dave Thomas"
>>   # . . .
?>   o.save
>> end
=> #<Order id: 4, name: "Dave Thomas", address: nil, email: nil, pay_type: nil, created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
 
?> an_order = Order.new(
?>   :name     => "Dave Thomas",
?>   :email    => "dave@example.com",
?>   :address  => "123 Main St",
?>   :pay_type => "check")
=> #<Order id: nil, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: nil, updated_at: nil, customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
>> an_order.save
=> true
 
?> an_order = Order.new
=> #<Order id: nil, name: nil, address: nil, email: nil, pay_type: nil, created_at: nil, updated_at: nil, customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
>> an_order.name = "Dave Thomas"
=> "Dave Thomas"
>> # ...
?> an_order.save
=> true
>> puts "The ID of this order is #{an_order.id}"
The ID of this order is 6
=> nil
 
?> an_order = Order.create(
?>   :name     => "Dave Thomas",
?>   :email    => "dave@example.com",
?>   :address  => "123 Main St",
?>   :pay_type => "check")
=> #<Order id: 7, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
 
?> orders = Order.create(
?>   [ { :name     => "Dave Thomas",
?>       :email    => "dave@example.com",
?>       :address  => "123 Main St",
?>       :pay_type => "check"
>>     },
?>     { :name     => "Andy Hunt",
?>       :email    => "andy@example.com",
?>       :address  => "456 Gentle Drive",
?>       :pay_type => "po"
>>     } ] )
=> [#<Order id: 8, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 9, name: "Andy Hunt", address: "456 Gentle Drive", email: "andy@example.com", pay_type: "po", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>]
>> >> => nil
irb e1/ar/find_examples.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> ActiveRecord::Base.logger = Logger.new(STDERR)
=> #<Logger:0x7e49c428 @progname=nil, @default_formatter=#<Logger::Formatter:0x7e49c400 @datetime_format=nil>, @level=0, @logdev=#<Logger::LogDevice:0x7e49c3d8 @shift_size=nil, @shift_age=nil, @filename=nil, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x7e49c3b0 @mon_entering_queue=[], @mon_count=0, @mon_owner=nil, @mon_waiting_queue=[]>, @dev=#<IO:0x10445920>>, @formatter=nil>
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
>> require "pp"
=> ["PP"]
 
>> @params = {}
=> {}
>> def params
>>   @params
>> end
=> nil
 
?> class Order < ActiveRecord::Base
>>   named_scope :check, :conditions => {:pay_type => 'check'}
>>   named_scope :cc,    :conditions => {:pay_type => 'cc'}
>>   named_scope :po,    :conditions => {:pay_type => 'po'}
>> end
=> #<Proc:0x7ed0a178@/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/named_scope.rb:116>
 
?> class Order < ActiveRecord::Base
>>   named_scope :recent, :conditions => ['created_at > ?', 1.week.ago]
>>   named_scope :since, lambda { |range| 
?>     { :conditions => ['created_at > ?', range] }
>>   }
>> end
=> #<Proc:0x7ed0a178@/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/named_scope.rb:116>
 
>> class LineItem < ActiveRecord::Base
>> end
=> nil
 
>> class Product < ActiveRecord::Base
>> end
=> nil
 
?> # return an arbitrary order
?> order = Order.find(:first)
  *[1m*[36mOrder Load (0.0ms)  *[1mSELECT "orders".* FROM "orders" LIMIT 1
=> #<Order id: 1, name: "Dave Thomas", address: "123 Main St", email: "customer@example.com", pay_type: "check", created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
 
>> # return an order for Dave
?> order = Order.find(:first, :conditions => "name = 'Dave Thomas'")
  *[1m*[35mOrder Load (0.0ms)  SELECT "orders".* FROM "orders" WHERE (name = 'Dave Thomas') LIMIT 1
  *[1m*[36mOrder Load (0.0ms)  *[1mSELECT "orders".* FROM "orders" WHERE (name = 'Dave Thomas') ORDER BY id DESC LIMIT 1
  *[1m*[35mLineItem Load (0.0ms)  select line_items.* from line_items, orders where order_id = orders.id and orders.name = 'Dave Thomas' 
=> #<Order id: 1, name: "Dave Thomas", address: "123 Main St", email: "customer@example.com", pay_type: "check", created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
 
>> # return the latest order for Dave
?> order = Order.find(:first,
?>                    :conditions => "name = 'Dave Thomas'", 
?>                    :order      => "id DESC")
=> #<Order id: 8, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
 
?> orders = LineItem.find_by_sql("select line_items.* from line_items, orders " +
?>                               " where order_id = orders.id                 " +
?>                               "   and orders.name = 'Dave Thomas'          ")
=> [#<LineItem id: 1, product_id: 3, order_id: 1, quantity: 1, total_price: 2850, created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", unit_price: #<BigDecimal:7e614468,'0.285E2',8(8)>>]
 
 
?> orders = Order.find_by_sql("select name, pay_type from orders")
  *[1m*[36mOrder Load (0.0ms)  *[1mselect name, pay_type from orders
=> [#<Order name: "Dave Thomas", pay_type: "check">, #<Order name: "Joe User", pay_type: "check">, #<Order name: "Dave Thomas", pay_type: "check">, #<Order name: "Dave Thomas", pay_type: nil>, #<Order name: "Dave Thomas", pay_type: "check">, #<Order name: "Dave Thomas", pay_type: nil>, #<Order name: "Dave Thomas", pay_type: "check">, #<Order name: "Dave Thomas", pay_type: "check">, #<Order name: "Andy Hunt", pay_type: "po">]
 
>> first = orders[0]
=> #<Order name: "Dave Thomas", pay_type: "check">
>> p first.attributes
{"name"=>"Dave Thomas", "pay_type"=>"check"}
=> nil
>> p first.attribute_names
["name", "pay_type"]
=> nil
>> p first.attribute_present?("address")
false
=> nil
 
 
?> p Order.all
  *[1m*[35mOrder Load (0.0ms)  SELECT "orders".* FROM "orders"
[#<Order id: 1, name: "Dave Thomas", address: "123 Main St", email: "customer@example.com", pay_type: "check", created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 2, name: "Joe User", address: "123 Main St., Anytown USA", email: "juser@hotmail.com", pay_type: "check", created_at: "2010-02-02 19:01:13", updated_at: "2010-02-02 19:01:13", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 3, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 4, name: "Dave Thomas", address: nil, email: nil, pay_type: nil, created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 5, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 6, name: "Dave Thomas", address: nil, email: nil, pay_type: nil, created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 7, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 8, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 9, name: "Andy Hunt", address: "456 Gentle Drive", email: "andy@example.com", pay_type: "po", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>]
=> nil
>> p Order.check(:order => "created_on desc").first
  *[1m*[36mOrder Load (0.0ms)  *[1mSELECT "orders".* FROM "orders" WHERE ("orders"."pay_type" = 'check') LIMIT 1
#<Order id: 1, name: "Dave Thomas", address: "123 Main St", email: "customer@example.com", pay_type: "check", created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
=> nil
>> p Order.po.recent.count
  *[1m*[35mSQL (15.0ms)  SELECT COUNT(*) AS count_id FROM "orders" WHERE ("orders"."pay_type" = 'po') AND (created_at > '2010-01-26 19:21:35.744800')
  *[1m*[36mOrder Load (0.0ms)  *[1mSELECT "orders".* FROM "orders" WHERE ("orders"."pay_type" = 'check') AND ("orders"."name" = 'Dave Thomas') LIMIT 1
  *[1m*[35mOrder Load (0.0ms)  SELECT "orders".* FROM "orders" WHERE ("orders"."pay_type" = 'po') AND (created_at > '2010-01-26 19:21:35.744800')
  *[1m*[36mOrder Load (0.0ms)  *[1mSELECT "orders".* FROM "orders" WHERE ("orders"."pay_type" = 'po') AND (created_at > '2010-01-26 19:21:38.271800')
1
=> nil
>> p Order.check.find_by_name('Dave Thomas')
#<Order id: 1, name: "Dave Thomas", address: "123 Main St", email: "customer@example.com", pay_type: "check", created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
=> nil
 
?> p Order.po.recent(:order => :created_at).to_a
[#<Order id: 9, name: "Andy Hunt", address: "456 Gentle Drive", email: "andy@example.com", pay_type: "po", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>]
=> nil
>> p Order.po.since(1.week.ago).to_a
[#<Order id: 9, name: "Andy Hunt", address: "456 Gentle Drive", email: "andy@example.com", pay_type: "po", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>]
=> nil
 
>> LineItem.delete_all
  *[1m*[35mSQL (0.0ms)  DELETE FROM "line_items" WHERE 1=1
=> 2
>> Product.delete_all
  *[1m*[36mSQL (15.0ms)  *[1mDELETE FROM "products" WHERE 1=1
  *[1m*[35mSQL (0.0ms)  INSERT INTO "products" ("created_at", "description", "image_url", "price", "title", "updated_at") VALUES ('2010-02-02 19:21:38.318800', NULL, NULL, 49.95, 'Programming Ruby', '2010-02-02 19:21:38.318800')
=> 3
>> p = Product.create(:title => "Programming Ruby", :price => 49.95)
=> #<Product id: 5, title: "Programming Ruby", description: nil, image_url: nil, created_at: "2010-02-02 19:21:38", updated_at: "2010-02-02 19:21:38", price: #<BigDecimal:7e5415a4,'0.4995E2',8(8)>>
>> LineItem.create(:quantity => 2, :unit_price => 49.95, :total_price => 99.90,
?>   :product_id => p.id, :order_id => first)
  *[1m*[36mSQL (0.0ms)  *[1mINSERT INTO "line_items" ("created_at", "order_id", "product_id", "quantity", "total_price", "unit_price", "updated_at") VALUES ('2010-02-02 19:21:38.349800', 1, 5, 2, 99, 49.95, '2010-02-02 19:21:38.349800')
=> #<LineItem id: 3, product_id: 5, order_id: 1, quantity: 2, total_price: 99, created_at: "2010-02-02 19:21:38", updated_at: "2010-02-02 19:21:38", unit_price: #<BigDecimal:7e4ffe74,'0.4995E2',8(8)>>
 
?> items = LineItem.find_by_sql("select *,                                  " +
?>                              "       quantity*unit_price as total_price, " +
?>                              "       products.title as title             " +
?>                              "  from line_items, products                " +
?>                              " where line_items.product_id = products.id ")
  *[1m*[35mLineItem Load (0.0ms)  select *, quantity*unit_price as total_price, products.title as title from line_items, products where line_items.product_id = products.id 
=> [#<LineItem id: 5, product_id: 5, order_id: 1, quantity: 2, total_price: 99, created_at: "2010-02-02 19:21:38", updated_at: "2010-02-02 19:21:38", unit_price: #<BigDecimal:7e4ebc30,'0.4995E2',8(8)>>]
>> li = items[0]
=> #<LineItem id: 5, product_id: 5, order_id: 1, quantity: 2, total_price: 99, created_at: "2010-02-02 19:21:38", updated_at: "2010-02-02 19:21:38", unit_price: #<BigDecimal:7e4e7c34,'0.4995E2',8(8)>>
>> puts "#{li.title}: #{li.quantity}x#{li.unit_price} => #{li.total_price}"
Programming Ruby: 2x49.95 => 99
=> nil
 
?> c1 = Order.count
  *[1m*[36mSQL (0.0ms)  *[1mSELECT COUNT(*) AS count_id FROM "orders"
=> 9
>> c2 = Order.count(:conditions => ["name = ?", "Dave Thomas"])
  *[1m*[35mSQL (0.0ms)  SELECT COUNT(*) AS count_id FROM "orders" WHERE (name = 'Dave Thomas')
  *[1m*[36mLineItem Count (0.0ms)  *[1mselect count(*) from line_items, orders where line_items.order_id = orders.id and orders.name = 'Dave Thomas' 
=> 7
>> c3 = LineItem.count_by_sql("select count(*)                        " +
?>                            "  from line_items, orders              " +
?>                            " where line_items.order_id = orders.id " +
?>                            "   and orders.name = 'Dave Thomas'     ")
=> 1
>> puts "Dave has #{c3} line items in #{c2} orders (#{c1} orders in all)"
Dave has 1 line items in 7 orders (9 orders in all)
=> nil
 
?> order  = Order.find_by_name("Dave Thomas")
  *[1m*[35mOrder Load (0.0ms)  SELECT "orders".* FROM "orders" WHERE ("orders"."name" = 'Dave Thomas') LIMIT 1
=> #<Order id: 1, name: "Dave Thomas", address: "123 Main St", email: "customer@example.com", pay_type: "check", created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>
>> orders = Order.find_all_by_name("Dave Thomas")
  *[1m*[36mOrder Load (0.0ms)  *[1mSELECT "orders".* FROM "orders" WHERE ("orders"."name" = 'Dave Thomas')
=> [#<Order id: 1, name: "Dave Thomas", address: "123 Main St", email: "customer@example.com", pay_type: "check", created_at: "2010-02-02 18:58:22", updated_at: "2010-02-02 18:58:22", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 3, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 4, name: "Dave Thomas", address: nil, email: nil, pay_type: nil, created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 5, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 6, name: "Dave Thomas", address: nil, email: nil, pay_type: nil, created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 7, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 8, name: "Dave Thomas", address: "123 Main St", email: "dave@example.com", pay_type: "check", created_at: "2010-02-02 19:21:20", updated_at: "2010-02-02 19:21:20", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>]
>> orders = Order.find_all_by_email(params['email'])
=> [#<Order id: 4, name: "Dave Thomas", address: nil, email: nil, pay_type: nil, created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>, #<Order id: 6, name: "Dave Thomas", address: nil, email: nil, pay_type: nil, created_at: "2010-02-02 19:21:19", updated_at: "2010-02-02 19:21:19", customer_email: nil, placed_at: "2010-02-02 19:10:06", attn: nil, order_type: nil, ship_class: "priority", amount: nil, state: nil>]
 
>> o = LineItem.find(:all,
?>                   :conditions => "pr.title = 'Programming Ruby'",
?>                   :joins => "inner join products as pr on line_items.product_id = pr.id")
=> [#<LineItem id: 3, product_id: 5, order_id: 1, quantity: 2, total_price: 99, created_at: "2010-02-02 19:21:38", updated_at: "2010-02-02 19:21:38", unit_price: #<BigDecimal:7e49180c,'0.4995E2',8(8)>>]
>> p o.size
1
=> nil
  *[1m*[35mOrder Load (0.0ms)  SELECT "orders".* FROM "orders" WHERE ("orders"."email" IS NULL)
  *[1m*[36mLineItem Load (0.0ms)  *[1mSELECT "line_items".* FROM "line_items" inner join products as pr on line_items.product_id = pr.id WHERE (pr.title = 'Programming Ruby')
  *[1m*[35mSQL (0.0ms)  DELETE FROM "line_items" WHERE 1=1
 
>> LineItem.delete_all
=> 1
 
>> res = Order.update_all("pay_type = 'wibble'")
  *[1m*[36mSQL (16.0ms)  *[1mUPDATE "orders" SET pay_type = 'wibble' 
  *[1m*[35mSQL (0.0ms)  DELETE FROM "orders" WHERE (pay_type = 'wibble')
=> 9
>> p res
9
=> nil
 
>> res = Order.delete_all(["pay_type = ?", "wibble"])
=> 9
>> p res
9
=> nil
 
irb e1/ar/dump_serialize_table.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require 'connect'
=> []
 
>> require 'rubygems'
=> []
>> require 'active_record'
=> []
>> require 'pp'
=> ["PP"]
 
>> ActiveRecord::Schema.define do
?>   create_table :purchases, :force => true do |t|
?>     t.string :name
>>     t.text   :last_five
>>   end
>> end
-- create_table(:purchases, {:force=>true})
   -> 0.8730s
=> nil
 
?> class Purchase < ActiveRecord::Base
>>   serialize :last_five
>>   # ...
?> end
=> Object
 
?> purchase = Purchase.new
=> #<Purchase id: nil, name: nil, last_five: nil>
>> purchase.name = "Dave Thomas"
=> "Dave Thomas"
>> purchase.last_five = [ 'shoes', 'shirt', 'socks', 'ski mask', 'shorts' ]
=> ["shoes", "shirt", "socks", "ski mask", "shorts"]
>> purchase.save
=> true
 
?> purchase = Purchase.find_by_name("Dave Thomas")
=> #<Purchase id: 1, name: "Dave Thomas", last_five: ["shoes", "shirt", "socks", "ski mask", "shorts"]>
>> pp purchase.last_five
["shoes", "shirt", "socks", "ski mask", "shorts"]
=> nil
>> pp purchase.last_five[3]
"ski mask"
=> nil
>> >> => nil
irb e1/ar/aggregation.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
>> require "pp"
=> ["PP"]
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> #require "rubygems"
?> #require_gem "active_record"
 
?> ActiveRecord::Schema.define do
?>   create_table :customers, :force => true do |t|
?>     t.datetime :created_at
>>     t.decimal  :credit_limit, :precision => 10, :scale => 2, :default => 100
>>     t.string   :first_name
>>     t.string   :initials
>>     t.string   :last_name
>>     t.datetime :last_purchase
>>     t.integer  :purchase_count, :default => 0
>>   end
>> end
-- create_table(:customers, {:force=>true})
   -> 0.9360s
=> nil
 
?> class LastFive
 
>>   attr_reader :list
 
>>   # Takes a string containing "a,b,c" and 
?>   # stores [ 'a', 'b', 'c' ]
?>   def initialize(list_as_string)
>>     @list = list_as_string.split(/,/)
>>   end
 
 
>>   # Returns our contents as a 
?>   # comma delimited string
?>   def last_five
>>     @list.join(',')
>>   end
>> end
=> nil
 
?> class Purchase < ActiveRecord::Base
>>   composed_of :last_five
>> end
=> #<ActiveRecord::Reflection::AggregateReflection:0x7e73f7e8 @active_record=Purchase(id: integer, name: string, last_five: text), @name=:last_five, @options={}, @macro=:composed_of>
 
>> Purchase.delete_all
=> 1
 
?> Purchase.create(:last_five => LastFive.new("3,4,5"))
=> #<Purchase id: 2, name: nil, last_five: "3,4,5">
 
>> purchase = Purchase.find(:first)
=> #<Purchase id: 2, name: nil, last_five: "3,4,5">
 
>> puts purchase.last_five.list[1]     #=>  4
4
=> nil
 
 
?> class Name
>>   attr_reader :first, :initials, :last
 
>>   def initialize(first, initials, last)
>>     @first = first
>>     @initials = initials
>>     @last = last
>>   end
 
>>   def to_s
>>     [ @first, @initials, @last ].compact.join(" ")
>>   end
>> end
=> nil
 
?> class Customer < ActiveRecord::Base
 
>>   composed_of :name,
?>               :class_name => "Name",
?>               :mapping => 
?>                  [ # database       ruby
?>                    %w[ first_name   first ],
?>                    %w[ initials     initials ],
?>                    %w[ last_name    last ] 
>>                  ]
>> end
=> #<ActiveRecord::Reflection::AggregateReflection:0x7e6e0c0c @active_record=Customer(id: integer, created_at: datetime, credit_limit: decimal, first_name: string, initials: string, last_name: string, last_purchase: datetime, purchase_count: integer), @name=:name, @options={:mapping=>[["first_name", "first"], ["initials", "initials"], ["last_name", "last"]], :class_name=>"Name"}, @macro=:composed_of>
 
>> Customer.delete_all
=> 0
 
?> name = Name.new("Dwight", "D", "Eisenhower")
=> #<Name:0x7e6d4524 @last="Eisenhower", @first="Dwight", @initials="D">
 
>> Customer.create(:credit_limit => 1000, :name => name)
=> #<Customer id: 1, created_at: "2010-02-02 19:22:11", credit_limit: #<BigDecimal:7e6b9c10,'0.1E4',4(8)>, first_name: "Dwight", initials: "D", last_name: "Eisenhower", last_purchase: nil, purchase_count: 0>
 
>> customer = Customer.find(:first)
=> #<Customer id: 1, created_at: "2010-02-02 19:22:11", credit_limit: #<BigDecimal:7e6b564c,'0.1E4',4(8)>, first_name: "Dwight", initials: "D", last_name: "Eisenhower", last_purchase: nil, purchase_count: 0>
>> puts customer.name.first    #=> Dwight
Dwight
=> nil
>> puts customer.name.last     #=> Eisenhower
Eisenhower
=> nil
>> puts customer.name.to_s     #=> Dwight D Eisenhower
Dwight D Eisenhower
=> nil
>> customer.name = Name.new("Harry", nil, "Truman")
=> #<Name:0x7e6aacd8 @last="Truman", @first="Harry", @initials=nil>
>> customer.save
=> true
 
>> >> => nil

19 ActiveRecord: Relationships Between Tables

irb e1/ar/associations.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> ActiveRecord::Schema.define do
 
?>   create_table :products, :force => true do |t|
?>     t.string   :title
>>     t.text     :description
>>     t.string   :image_url
>>     t.decimal  :price, :precision => 10, :scale => 2
>>     t.datetime :available_at
>>   end
 
>>   create_table :line_items, :force => true do |t|
?>     t.integer :product_id
>>     t.integer :order_id
>>     t.integer :quantity
>>     t.integer :unit_price, :precision => 8, :scale => 2
>>   end
>> end
-- create_table(:products, {:force=>true})
   -> 0.8260s
-- create_table(:line_items, {:force=>true})
   -> 0.0160s
=> nil
 
?> class Product < ActiveRecord::Base
>>   has_many :line_items
>> end
=> Product(id: integer, title: string, description: text, image_url: string, price: decimal, available_at: datetime)
 
>> class LineItem < ActiveRecord::Base
>>   belongs_to :product
>> end
=> nil
 
>> LineItem.delete_all
=> 0
 
>> p = Product.create(:title => "Programming Ruby", :available_at => Time.now)
=> #<Product id: 1, title: "Programming Ruby", description: nil, image_url: nil, price: nil, available_at: "2010-02-02 19:22:28">
>> l = LineItem.new
=> #<LineItem id: nil, product_id: nil, order_id: nil, quantity: nil, unit_price: nil>
>> l.id = 2
=> 2
>> l.product = p
=> #<Product id: 1, title: "Programming Ruby", description: nil, image_url: nil, price: nil, available_at: "2010-02-02 19:22:28">
>> l.save!
=> true
 
>> l = LineItem.new
=> #<LineItem id: nil, product_id: nil, order_id: nil, quantity: nil, unit_price: nil>
>> l.product = p
=> #<Product id: 1, title: "Programming Ruby", description: nil, image_url: nil, price: nil, available_at: "2010-02-02 19:22:28">
>> l.save!
=> true
 
>> puts "\n\nSimple Belongs to"

    

    
Simple Belongs to
=> nil
 
?> item = LineItem.find(2)
=> #<LineItem id: 2, product_id: 1, order_id: nil, quantity: nil, unit_price: nil>
 
>> # item.product is the associated Product object
?> puts "Current product is #{item.product.id}"
Current product is 1
=> nil
>> puts item.product.title
Programming Ruby
=> nil
 
>> item.product = Product.new(:title          => "Rails for Java Developers",
?>                            :description    => "...",
?>                            :image_url      => "http://....jpg",
?>                            :price          => 34.95,
?>                            :available_at   => Time.now)
=> #<Product id: nil, title: "Rails for Java Developers", description: "...", image_url: "http://....jpg", price: #<BigDecimal:7e5800ec,'0.3495E2',8(8)>, available_at: "2010-02-02 19:22:30">
>> item.save!
=> true
 
>> puts "New product is #{item.product.id}"
New product is 2
=> nil
>> puts item.product.title
Rails for Java Developers
=> nil
 
>> puts "\n\nCreate belongs to"

    

    
Create belongs to
=> nil
 
>> item = LineItem.find(2)
=> #<LineItem id: 2, product_id: 2, order_id: nil, quantity: nil, unit_price: nil>
 
>> # item.product is the associated Product object
?> puts "Current product is #{item.product.id}"
Current product is 2
=> nil
>> puts item.product.title
Rails for Java Developers
=> nil
 
?> item.create_product(:title          => "Rails Recipes",
?>                     :description    => "...",
?>                     :image_url      => "http://....jpg",
?>                     :price          => 32.95,
?>                     :available_at   => Time.now)
=> #<Product id: 3, title: "Rails Recipes", description: "...", image_url: "http://....jpg", price: #<BigDecimal:7e5455f0,'0.3295E2',8(8)>, available_at: "2010-02-02 19:22:30">
 
>> puts "New product is #{item.product.id}"
New product is 3
=> nil
>> puts item.product.title
Rails Recipes
=> nil
 
>> puts "\n\nproduct belongs to"

    

    
product belongs to
=> nil
>> item = LineItem.find(2)
=> #<LineItem id: 2, product_id: 2, order_id: nil, quantity: nil, unit_price: nil>
 
>> # item.product is the associated Product object
?> puts "Current product is #{item.product.id}"
Current product is 2
=> nil
>> puts item.product.title
Rails for Java Developers
=> nil
 
>> item = LineItem.new()
=> #<LineItem id: nil, product_id: nil, order_id: nil, quantity: nil, unit_price: nil>
 
>> item.create_product(:title          => "Advanced Rails", 
?>                     :description    => "...",
?>                     :image_url      => "http://....jpg",
?>                     :price          => 34.95,
?>                     :available_at   => Time.now)
=> #<Product id: 4, title: "Advanced Rails", description: "...", image_url: "http://....jpg", price: #<BigDecimal:7e5151fc,'0.3495E2',8(8)>, available_at: "2010-02-02 19:22:30">
 
>> puts "New product is #{item.product.id}"
New product is 4
=> nil
>> puts item.product.title
Advanced Rails
=> nil
>> item.save!
=> true
>> p item.product(true)
#<Product id: 4, title: "Advanced Rails", description: "...", image_url: "http://....jpg", price: #<BigDecimal:7e507958,'0.3495E2',8(8)>, available_at: "2010-02-02 19:22:30">
=> nil
 
>> puts "============="
=============
=> nil
 
>> prod = Product.find(item.product_id)
=> #<Product id: 4, title: "Advanced Rails", description: "...", image_url: "http://....jpg", price: #<BigDecimal:7e4ffd34,'0.3495E2',8(8)>, available_at: "2010-02-02 19:22:30">
>> p prod.line_items.size
1
=> nil
 
irb e1/ar/sti.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> ActiveRecord::Base.logger = Logger.new(STDERR)
=> #<Logger:0x7e49c428 @progname=nil, @default_formatter=#<Logger::Formatter:0x7e49c400 @datetime_format=nil>, @level=0, @logdev=#<Logger::LogDevice:0x7e49c3d8 @shift_size=nil, @shift_age=nil, @filename=nil, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x7e49c3b0 @mon_entering_queue=[], @mon_count=0, @mon_owner=nil, @mon_waiting_queue=[]>, @dev=#<IO:0x10445920>>, @formatter=nil>
 
>> ActiveRecord::Schema.define do
 
?>   create_table :people, :force => true do |t|
?>     t.string :type
 
>>     # common attributes
?>     t.string :name
>>     t.string :email
 
>>     # attributes for type=Customer
?>     t.decimal :balance, :precision => 10, :scale => 2
 
>>     # attributes for type=Employee
?>     t.integer :reports_to
>>     t.integer :dept
 
>>     # attributes for type=Manager
?>     # -- none -- 
?>   end
 
>> end
-- create_table(:people, {:force=>true})
  *[1m*[36mSQL (0.0ms)  *[1mselect sqlite_version(*)
  *[1m*[35mSQL (0.0ms)   SELECT name
 FROM sqlite_master
 WHERE type = 'table' AND NOT name = 'sqlite_sequence'

    
  *[1m*[36mSQL (0.0ms)  *[1mCREATE TABLE "people" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "email" varchar(255), "balance" decimal(10,2), "reports_to" integer, "dept" integer) 
   -> 0.8120s
=> nil
 
?> class Person < ActiveRecord::Base
>> end
=> nil
 
>> class Customer < Person
>> end
=> nil
 
>> class Employee < Person
>>   belongs_to :boss, :class_name => "Manager", :foreign_key => :reports_to
>> end
=> nil
 
>> class Manager < Employee
>> end
=> nil
 
?> Customer.create(:name => 'John Doe',    :email => "john@doe.com",    
?>                 :balance => 78.29)
  *[1m*[35mSQL (0.0ms)  INSERT INTO "people" ("balance", "dept", "email", "name", "reports_to", "type") VALUES (78.29, NULL, 'john@doe.com', 'John Doe', NULL, 'Customer')
=> #<Customer id: 1, type: "Customer", name: "John Doe", email: "john@doe.com", balance: #<BigDecimal:7e73d1dc,'0.7829E2',8(8)>, reports_to: nil, dept: nil>
 
>> wilma = Manager.create(:name  => 'Wilma Flint', :email => "wilma@here.com",  
?>                        :dept => 23)
  *[1m*[36mSQL (0.0ms)  *[1mINSERT INTO "people" ("balance", "dept", "email", "name", "reports_to", "type") VALUES (NULL, 23, 'wilma@here.com', 'Wilma Flint', NULL, 'Manager')
=> #<Manager id: 2, type: "Manager", name: "Wilma Flint", email: "wilma@here.com", balance: nil, reports_to: nil, dept: 23>
 
>> Customer.create(:name => 'Bert Public', :email => "b@public.net",    
?>                 :balance => 12.45)
  *[1m*[35mSQL (0.0ms)  INSERT INTO "people" ("balance", "dept", "email", "name", "reports_to", "type") VALUES (12.45, NULL, 'b@public.net', 'Bert Public', NULL, 'Customer')
=> #<Customer id: 3, type: "Customer", name: "Bert Public", email: "b@public.net", balance: #<BigDecimal:7e6f1d54,'0.1245E2',8(8)>, reports_to: nil, dept: nil>
 
>> barney = Employee.new(:name => 'Barney Rub',  :email => "barney@here.com", 
  *[1m*[36mSQL (0.0ms)  *[1mINSERT INTO "people" ("balance", "dept", "email", "name", "reports_to", "type") VALUES (NULL, 23, 'barney@here.com', 'Barney Rub', 2, 'Employee')
?>                       :dept => 23)
=> #<Employee id: nil, type: "Employee", name: "Barney Rub", email: "barney@here.com", balance: nil, reports_to: nil, dept: 23>
>> barney.boss = wilma
=> #<Manager id: 2, type: "Manager", name: "Wilma Flint", email: "wilma@here.com", balance: nil, reports_to: nil, dept: 23>
>> barney.save!
=> true
 
>> manager = Person.find_by_name("Wilma Flint")
  *[1m*[35mPerson Load (0.0ms)  SELECT "people".* FROM "people" WHERE ("people"."name" = 'Wilma Flint') LIMIT 1
=> #<Manager id: 2, type: "Manager", name: "Wilma Flint", email: "wilma@here.com", balance: nil, reports_to: nil, dept: 23>
>> puts manager.class    #=> Manager
Manager
=> nil
>> puts manager.email    #=> wilma@here.com
wilma@here.com
=> nil
>> puts manager.dept     #=> 23
23
=> nil
 
>> customer = Person.find_by_name("Bert Public")
  *[1m*[36mPerson Load (0.0ms)  *[1mSELECT "people".* FROM "people" WHERE ("people"."name" = 'Bert Public') LIMIT 1
  *[1m*[35mPerson Load (0.0ms)  SELECT "people".* FROM "people" WHERE ("people"."name" = 'Barney Rub') LIMIT 1
  *[1m*[36mManager Load (0.0ms)  *[1mSELECT "people".* FROM "people" WHERE ("people"."type" = 'Manager') AND ("people"."id" = 2) LIMIT 1
=> #<Customer id: 3, type: "Customer", name: "Bert Public", email: "b@public.net", balance: #<BigDecimal:7e6a08dc,'0.1245E2',8(8)>, reports_to: nil, dept: nil>
>> puts customer.class    #=> Customer
Customer
=> nil
>> puts customer.email    #=> b@public.net
b@public.net
=> nil
>> puts customer.balance  #=> 12.45
12.45
=> nil
 
>> b = Person.find_by_name("Barney Rub")
=> #<Employee id: 4, type: "Employee", name: "Barney Rub", email: "barney@here.com", balance: nil, reports_to: 2, dept: 23>
>> p b.boss
#<Manager id: 2, type: "Manager", name: "Wilma Flint", email: "wilma@here.com", balance: nil, reports_to: nil, dept: 23>
=> nil
 
irb e1/ar/polymorphic.rb 1
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> if ARGV.empty? or ARGV.first == '1'
>>   ActiveRecord::Schema.define do
 
?>     create_table :catalog_entries, :force => true do |t|
?>       t.string :name
>>       t.datetime :acquired_at
>>       t.integer :resource_id
>>       t.string :resource_type
>>     end
 
?>     create_table :articles, :force => true do |t|
?>       t.text :content
>>     end
 
>>     create_table :sounds, :force => true do |t|
?>       t.binary :content
>>     end
 
>>     create_table :images, :force => true do |t|
?>       t.binary :content
>>     end
 
>>   end
>> end
-- create_table(:catalog_entries, {:force=>true})
   -> 0.8270s
-- create_table(:articles, {:force=>true})
   -> 0.0000s
-- create_table(:sounds, {:force=>true})
   -> 0.0160s
-- create_table(:images, {:force=>true})
   -> 0.0780s
=> nil
 
?> class CatalogEntry < ActiveRecord::Base
>>   belongs_to :resource, :polymorphic => true
>> end
=> nil
 
?> class Article < ActiveRecord::Base
>>   has_one :catalog_entry, :as => :resource
>> end
=> nil
 
>> class Sound < ActiveRecord::Base
>>   has_one :catalog_entry, :as => :resource
>> end
=> nil
 
>> class Image < ActiveRecord::Base
>>   has_one :catalog_entry, :as => :resource
>> end
=> nil
 
>> case ARGV.shift
>> when "1"
>>   a = Article.new(:content => "This is my new article")
>>   c = CatalogEntry.new(:name => 'Article One', :acquired_at => Time.now)
>>   c.resource = a
>>   c.save!
?>   article = Article.find(1)
>>   p article.catalog_entry.name  #=> "Article One"
 
>>   cat = CatalogEntry.find(1)
>>   resource = cat.resource 
>>   p resource                    #=> #<Article:0x640d80 @attributes={"id"=>"1", 
>>                                 #     "content"=>"This is my new article"}>
 
?> when "2"
>>   c = CatalogEntry.new(:name => 'Article One', :acquired_at => Time.now)
>>   c.resource = Article.new(:content => "This is my new article")
>>   c.save!
 
>>   c = CatalogEntry.new(:name => 'Image One', :acquired_at => Time.now)
>>   c.resource = Image.new(:content => "some binary data")
>>   c.save!
 
>>   c = CatalogEntry.new(:name => 'Sound One', :acquired_at => Time.now)
>>   c.resource = Sound.new(:content => "more binary data")
>>   c.save!
 
?>   CatalogEntry.find(:all).each do |c|
?>     puts "#{c.name}:  #{c.resource.class}"
>>   end
>> else
?>   a = Sound.new(:content => "ding!")
>>   c = CatalogEntry.new(:name => 'Sound One', :acquired_at => Time.now)
>>   c.resource = a
 
>>   c.save!
 
>>   c = CatalogEntry.find 1
>>   p c.resource
 
>>   a = Sound.find :first
>>   p a.catalog_entry
>> end
"Article One"
#<Article id: 1, content: "This is my new article">
=> nil
 
sqlite3> select * from articles
     id = 1
content = This is my new article
sqlite3> select * from catalog_entries
           id = 1
         name = Article One
  acquired_at = 2010-02-02 19:23:03.448400
  resource_id = 1
resource_type = Article
sqlite3> delete from catalog_entries
irb e1/ar/polymorphic.rb 2
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> if ARGV.empty? or ARGV.first == '1'
>>   ActiveRecord::Schema.define do
 
?>     create_table :catalog_entries, :force => true do |t|
?>       t.string :name
>>       t.datetime :acquired_at
>>       t.integer :resource_id
>>       t.string :resource_type
>>     end
 
?>     create_table :articles, :force => true do |t|
?>       t.text :content
>>     end
 
>>     create_table :sounds, :force => true do |t|
?>       t.binary :content
>>     end
 
>>     create_table :images, :force => true do |t|
?>       t.binary :content
>>     end
 
>>   end
>> end
=> nil
 
?> class CatalogEntry < ActiveRecord::Base
>>   belongs_to :resource, :polymorphic => true
>> end
=> nil
 
?> class Article < ActiveRecord::Base
>>   has_one :catalog_entry, :as => :resource
>> end
=> nil
 
>> class Sound < ActiveRecord::Base
>>   has_one :catalog_entry, :as => :resource
>> end
=> nil
 
>> class Image < ActiveRecord::Base
>>   has_one :catalog_entry, :as => :resource
>> end
=> nil
 
>> case ARGV.shift
>> when "1"
>>   a = Article.new(:content => "This is my new article")
>>   c = CatalogEntry.new(:name => 'Article One', :acquired_at => Time.now)
>>   c.resource = a
>>   c.save!
?>   article = Article.find(1)
>>   p article.catalog_entry.name  #=> "Article One"
 
>>   cat = CatalogEntry.find(1)
>>   resource = cat.resource 
>>   p resource                    #=> #<Article:0x640d80 @attributes={"id"=>"1", 
>>                                 #     "content"=>"This is my new article"}>
 
?> when "2"
>>   c = CatalogEntry.new(:name => 'Article One', :acquired_at => Time.now)
>>   c.resource = Article.new(:content => "This is my new article")
>>   c.save!
 
>>   c = CatalogEntry.new(:name => 'Image One', :acquired_at => Time.now)
>>   c.resource = Image.new(:content => "some binary data")
>>   c.save!
 
>>   c = CatalogEntry.new(:name => 'Sound One', :acquired_at => Time.now)
>>   c.resource = Sound.new(:content => "more binary data")
>>   c.save!
 
?>   CatalogEntry.find(:all).each do |c|
?>     puts "#{c.name}:  #{c.resource.class}"
>>   end
>> else
?>   a = Sound.new(:content => "ding!")
>>   c = CatalogEntry.new(:name => 'Sound One', :acquired_at => Time.now)
>>   c.resource = a
 
>>   c.save!
 
>>   c = CatalogEntry.find 1
>>   p c.resource
 
>>   a = Sound.find :first
>>   p a.catalog_entry
>> end
Article One:  Article
Image One:  Image
Sound One:  Sound
=> [#<CatalogEntry id: 2, name: "Article One", acquired_at: "2010-02-02 19:23:21", resource_id: 2, resource_type: "Article">, #<CatalogEntry id: 3, name: "Image One", acquired_at: "2010-02-02 19:23:23", resource_id: 1, resource_type: "Image">, #<CatalogEntry id: 4, name: "Sound One", acquired_at: "2010-02-02 19:23:23", resource_id: 1, resource_type: "Sound">]
 
sqlite3> select * from articles
     id = 1
content = This is my new article
 
     id = 2
content = This is my new article
sqlite3> select * from images
     id = 1
content = some binary data
sqlite3> select * from sounds
     id = 1
content = more binary data
sqlite3> select * from catalog_entries
           id = 2
         name = Article One
  acquired_at = 2010-02-02 19:23:21.216800
  resource_id = 2
resource_type = Article
 
           id = 3
         name = Image One
  acquired_at = 2010-02-02 19:23:23.696800
  resource_id = 1
resource_type = Image
 
           id = 4
         name = Sound One
  acquired_at = 2010-02-02 19:23:23.712800
  resource_id = 1
resource_type = Sound
irb e1/ar/self_association.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> ActiveRecord::Schema.define do
?>   create_table :employees, :force => true do |t|
?>     t.string :name
>>     t.integer :manager_id
>>     t.integer :mentor_id
>>   end
>> end
-- create_table(:employees, {:force=>true})
   -> 0.8270s
=> nil
 
?> class Employee < ActiveRecord::Base
>>   belongs_to :manager,
?>              :class_name  => "Employee",
?>              :foreign_key => "manager_id"
 
>>   belongs_to :mentor,
?>              :class_name  => "Employee", 
?>              :foreign_key => "mentor_id"
 
>>   has_many   :mentored_employees,
?>              :class_name  => "Employee",
?>              :foreign_key => "mentor_id"
 
>>   has_many   :managed_employees,
?>              :class_name  => "Employee",
?>              :foreign_key => "manager_id"
>> end
=> Employee(id: integer, name: string, manager_id: integer, mentor_id: integer)
 
?> Employee.delete_all
=> 0
 
>> adam = Employee.create(:name => "Adam")
=> #<Employee id: 1, name: "Adam", manager_id: nil, mentor_id: nil>
>> beth = Employee.create(:name => "Beth")
=> #<Employee id: 2, name: "Beth", manager_id: nil, mentor_id: nil>
 
>> clem = Employee.new(:name => "Clem")
=> #<Employee id: nil, name: "Clem", manager_id: nil, mentor_id: nil>
>> clem.manager = adam
=> #<Employee id: 1, name: "Adam", manager_id: nil, mentor_id: nil>
>> clem.mentor  = beth
=> #<Employee id: 2, name: "Beth", manager_id: nil, mentor_id: nil>
>> clem.save!
=> true
 
>> dawn = Employee.new(:name => "Dawn")
=> #<Employee id: nil, name: "Dawn", manager_id: nil, mentor_id: nil>
>> dawn.manager = adam
=> #<Employee id: 1, name: "Adam", manager_id: nil, mentor_id: nil>
>> dawn.mentor  = clem
=> #<Employee id: 3, name: "Clem", manager_id: 1, mentor_id: 2>
>> dawn.save!
=> true
 
?> p adam.managed_employees.map {|e| e.name}  # => [ "Clem", "Dawn" ]
["Clem", "Dawn"]
=> nil
>> p adam.mentored_employees                  # => []
[]
=> nil
>> p dawn.mentor.name                         # => "Clem"
"Clem"
=> nil
 
 
>> >> => nil
irb e1/ar/acts_as_list.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
 
>> require "logger"
=> []
>> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> require "./vendor/plugins/acts_as_list/init"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> ActiveRecord::Base.connection.instance_eval do
 
?>   create_table :parents, :force => true do |t|
?>   end
 
>>   create_table :children, :force => true do |t|
?>     t.integer :parent_id
>>     t.string  :name
>>     t.integer :position
>>   end
>> end
=> []
 
 
?> class Parent < ActiveRecord::Base
>>   has_many :children, :order => :position
>> end
=> Parent(id: integer)
 
>> class Child < ActiveRecord::Base
>>   belongs_to :parent
>>   acts_as_list  :scope => :parent
>> end
=> Child(id: integer, parent_id: integer, name: string, position: integer)
 
 
?> parent = Parent.create
=> #<Parent id: 1>
>> %w{ One Two Three Four}.each do |name|
?>   parent.children.create(:name => name)
>> end
=> ["One", "Two", "Three", "Four"]
>> parent.save
=> true
 
?> def display_children(parent)
>>   puts parent.children(true).map {|child| child.name }.join(", ")
>> end
=> nil
 
?> display_children(parent)         #=> One, Two, Three, Four
One, Two, Three, Four
=> nil
 
>> puts parent.children[0].first?   #=> true
true
=> nil
 
>> two = parent.children[1]
=> #<Child id: 2, parent_id: 1, name: "Two", position: 2>
>> puts two.lower_item.name         #=> Three
Three
=> nil
>> puts two.higher_item.name        #=> One
One
=> nil
 
>> parent.children[0].move_lower
=> true
>> display_children(parent)         #=> Two, One, Three, Four
Two, One, Three, Four
=> nil
 
>> parent.children[2].move_to_top
=> true
>> display_children(parent)         #=> Three, Two, One, Four
Three, Two, One, Four
=> nil
 
>> parent.children[2].destroy
=> #<Child id: 1, parent_id: 1, name: "One", position: nil>
>> display_children(parent)         #=> Three, Two, Four
Three, Two, Four
=> nil
>> >> => nil
irb e1/ar/acts_as_tree.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
>> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> require "./vendor/plugins/acts_as_tree/lib/active_record/acts/tree.rb"
=> []
>> require "./vendor/plugins/acts_as_tree/init"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> ActiveRecord::Schema.define do
 
?>   create_table :categories, :force => true do |t|
?>     t.string  :name
>>     t.integer :parent_id
>>   end
>> end
-- create_table(:categories, {:force=>true})
   -> 0.8110s
=> nil
 
 
 
 
?> class Category < ActiveRecord::Base
>>   acts_as_tree  :order => "name"
>> end
=> nil
 
 
?> root        = Category.create(:name => "Books")
=> #<Category id: 1, name: "Books", parent_id: nil>
>> fiction     = root.children.create(:name => "Fiction")
=> #<Category id: 2, name: "Fiction", parent_id: 1>
>> non_fiction = root.children.create(:name => "Non Fiction")
=> #<Category id: 3, name: "Non Fiction", parent_id: 1>
 
>> non_fiction.children.create(:name => "Computers")
=> #<Category id: 4, name: "Computers", parent_id: 3>
>> non_fiction.children.create(:name => "Science")
=> #<Category id: 5, name: "Science", parent_id: 3>
>> non_fiction.children.create(:name => "Art History")
=> #<Category id: 6, name: "Art History", parent_id: 3>
 
>> fiction.children.create(:name => "Mystery")
=> #<Category id: 7, name: "Mystery", parent_id: 2>
>> fiction.children.create(:name => "Romance")
=> #<Category id: 8, name: "Romance", parent_id: 2>
>> fiction.children.create(:name => "Science Fiction")
=> #<Category id: 9, name: "Science Fiction", parent_id: 2>
 
>> def display_children(order)
>>   puts order.children.map {|child| child.name }.join(", ")
>> end
=> nil
 
?> display_children(root)             # Fiction, Non Fiction
Fiction, Non Fiction
=> nil
 
>> sub_category = root.children.first
=> #<Category id: 2, name: "Fiction", parent_id: 1>
>> puts sub_category.children.size    #=> 3
3
=> nil
>> display_children(sub_category)     #=> Mystery, Romance, Science Fiction
Mystery, Romance, Science Fiction
=> nil
 
>> non_fiction = root.children.find(:first, :conditions => "name = 'Non Fiction'")
=> #<Category id: 3, name: "Non Fiction", parent_id: 1>
 
>> display_children(non_fiction)      #=> Art History, Computers, Science
Art History, Computers, Science
=> nil
>> puts non_fiction.parent.name       #=> Books
Books
=> nil
>> >> => nil
irb e1/ar/one_to_one.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> ActiveRecord::Schema.define do
 
?>   create_table :invoices, :force => true do |t|
?>     t.integer :order_id
>>   end
 
>>   create_table :orders, :force => true do |t|
?>     t.string   :name
>>     t.string   :email
>>     t.text     :address
>>     t.string   :pay_type
>>     t.datetime :shipped_at
>>   end
 
>> end
-- create_table(:invoices, {:force=>true})
   -> 0.8120s
-- create_table(:orders, {:force=>true})
   -> 0.0310s
=> nil
 
?> class Order < ActiveRecord::Base
>>   has_one :invoice
>> end
=> nil
 
>> class Invoice < ActiveRecord::Base
>>   belongs_to :order
>> end
=> nil
 
>> Order.create(:name => "Dave", :email => "dave@xxx",
?>              :address => "123 Main St", :pay_type => "credit",
?>              :shipped_at => Time.now)
=> #<Order id: 1, name: "Dave", email: "dave@xxx", address: "123 Main St", pay_type: "credit", shipped_at: "2010-02-02 19:24:31">
 
 
 
>> order = Order.find(1)
=> #<Order id: 1, name: "Dave", email: "dave@xxx", address: "123 Main St", pay_type: "credit", shipped_at: "2010-02-02 19:24:31">
 
>> p order.invoice
nil
=> nil
 
>> invoice = Invoice.new
=> #<Invoice id: nil, order_id: nil>
>> if invoice.save
>>   order.invoice = invoice
>> else
?>   fail invoice.errors.to_s
>> end
=> #<Invoice id: 1, order_id: 1>
 
>> p order.invoice
#<Invoice id: 1, order_id: 1>
=> nil
 
>> o = Order.new
=> #<Order id: nil, name: nil, email: nil, address: nil, pay_type: nil, shipped_at: nil>
>> p o.id
nil
=> nil
>> invoice.order = o
=> #<Order id: nil, name: nil, email: nil, address: nil, pay_type: nil, shipped_at: nil>
>> p o.id
nil
=> nil
>> invoice.save
=> true
>> p o.id
2
=> nil
 
irb e1/ar/counters.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do
?>   create_table :products, :force => true do |t|
?>     t.string :title
>>     t.text :description
>>     # ...
?>     t.integer :line_items_count, :default => 0
>>   end
 
>>   create_table :line_items, :force => true do |t|
?>     t.integer :product_id
>>     t.integer :order_id
>>     t.integer :quantity
>>     t.decimal :unit_price, :precision => 8, :scale => 2
>>   end
 
>> end
-- create_table(:products, {:force=>true})
   -> 0.9360s
-- create_table(:line_items, {:force=>true})
   -> 0.0160s
=> nil
 
>> class Product < ActiveRecord::Base
>>   has_many :line_items
>> end
=> Product(id: integer, title: string, description: text, line_items_count: integer)
 
?> class LineItem < ActiveRecord::Base
>>   belongs_to :product, :counter_cache => true
>> end
=> nil
 
?> product = Product.create(:title => "Programming Ruby",
?>                          :description => " ... ")
=> #<Product id: 1, title: "Programming Ruby", description: " ... ", line_items_count: 0>
>> line_item = LineItem.new
=> #<LineItem id: nil, product_id: nil, order_id: nil, quantity: nil, unit_price: nil>
>> line_item.product = product
=> #<Product id: 1, title: "Programming Ruby", description: " ... ", line_items_count: 0>
>> line_item.save
=> true
>> puts "In memory size = #{product.line_items.size}"             #=> 0
In memory size = 0
=> nil
>> puts "Refreshed size = #{product.line_items(:refresh).size}"   #=> 1
Refreshed size = 1
=> nil
 
 
 
>> LineItem.delete_all
=> 1
>> Product.delete_all
=> 1
 
?> product = Product.create(:title => "Programming Ruby", 
?>                          :description => " ... ")
=> #<Product id: 2, title: "Programming Ruby", description: " ... ", line_items_count: 0>
>> product.line_items.create
=> #<LineItem id: 2, product_id: 2, order_id: nil, quantity: nil, unit_price: nil>
>> puts "In memory size = #{product.line_items.size}"             #=> 1
In memory size = 0
=> nil
>> puts "Refreshed size = #{product.line_items(:refresh).size}"   #=> 1
Refreshed size = 1
=> nil
 
 
 
>> >> => nil

20 ActiveRecord: Object Life Cycle

irb e1/ar/encrypt.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
 
>> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> ActiveRecord::Schema.define do
 
?>   create_table :orders, :force => true do |t|
?>     t.integer :user_id
>>     t.string  :name
>>     t.string  :address
>>     t.string  :email
>>   end
 
>>   create_table :users, :force => :true do |t|
?>     t.string :name
>>   end
>> end
-- create_table(:orders, {:force=>true})
   -> 0.8110s
-- create_table(:users, {:force=>:true})
   -> 0.0310s
=> nil
 
 
?> class ActiveRecord::Base
>>   def self.encrypt(*attr_names)
>>     encrypter = Encrypter.new(attr_names)
 
>>     before_save encrypter
>>     after_save  encrypter
>>     after_find  encrypter
 
>>     define_method(:after_find) { }
>>   end
>> end
=> nil
 
?> class Encrypter
 
>>   # We're passed a list of attributes that should
?>   # be stored encrypted in the database
?>   def initialize(attrs_to_manage)
>>     @attrs_to_manage = attrs_to_manage
>>   end
 
>>   # Before saving or updating, encrypt the fields using the NSA and
?>   # DHS approved Shift Cipher
?>   def before_save(model)
>>     @attrs_to_manage.each do |field|
?>       model[field].tr!("a-z", "b-za")
>>     end
>>   end
 
>>   # After saving, decrypt them back
?>   def after_save(model)
>>     @attrs_to_manage.each do |field|
?>       model[field].tr!("b-za", "a-z")
>>     end
>>   end
 
>>   # Do the same after finding an existing record
?>   alias_method :after_find, :after_save
>> end
=> Encrypter
 
?> class Order < ActiveRecord::Base
>>   encrypt(:name, :email)
>> end
=> #<Proc:0x00000000@/home/rubys/git/awdwr/data/code/e1/ar/encrypt.rb:33>
 
?> o = Order.new
=> #<Order id: nil, user_id: nil, name: nil, address: nil, email: nil>
>> o.name = "Dave Thomas"
=> "Dave Thomas"
>> o.address = "123 The Street"
=> "123 The Street"
>> o.email   = "dave@example.com"
=> "dave@example.com"
>> o.save
=> true
>> puts o.name
Dave Thomas
=> nil
 
>> o = Order.find(o.id)
=> #<Order id: 1, user_id: nil, name: "Dave Thomas", address: "123 The Street", email: "dave@example.com">
>> puts o.name
Dave Thomas
=> nil
>> >> => nil
sqlite3> select * from orders
     id = 1
user_id = 
   name = Dbwf Tipnbt
address = 123 The Street
  email = ebwf@fybnqmf.dpn
irb e1/ar/observer.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
 
>> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> require 'connect'
=> []
 
>> ActiveRecord::Base.logger = Logger.new(STDERR)
=> #<Logger:0x7e49db98 @progname=nil, @default_formatter=#<Logger::Formatter:0x7e49db70 @datetime_format=nil>, @level=0, @logdev=#<Logger::LogDevice:0x7e49db48 @shift_size=nil, @shift_age=nil, @filename=nil, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x7e49db20 @mon_entering_queue=[], @mon_count=0, @mon_owner=nil, @mon_waiting_queue=[]>, @dev=#<IO:0x10445920>>, @formatter=nil>
 
>> ActiveRecord::Schema.define do 
?>   create_table :payments, :force => true do |t|
?>   end
>> end
-- create_table(:payments, {:force=>true})
  *[1m*[36mSQL (0.0ms)  *[1mselect sqlite_version(*)
  *[1m*[35mSQL (0.0ms)   SELECT name
 FROM sqlite_master
 WHERE type = 'table' AND NOT name = 'sqlite_sequence'

    
  *[1m*[36mSQL (0.0ms)  *[1mCREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL) 
   -> 0.8110s
=> nil
 
>> class Order < ActiveRecord::Base
>> end
=> nil
 
>> class Payment < ActiveRecord::Base
>> end
=> nil
 
>> class Refund < ActiveRecord::Base
>> end
=> nil
 
?> class OrderObserver < ActiveRecord::Observer
>>   def after_save(an_order)
>>     an_order.logger.info("Order #{an_order.id} created")
>>   end
>> end
=> nil
 
>> OrderObserver.instance
=> #<OrderObserver:0x7e3db048>
 
?> class AuditObserver < ActiveRecord::Observer
 
>>   observe Order, Payment, Refund
 
>>   def after_save(model)
>>     model.logger.info("[Audit] #{model.class.name} #{model.id} created")
>>   end
>> end
=> nil
 
>> AuditObserver.instance
=> #<AuditObserver:0x7e3cb364>
 
 
>> o = Order.create
  *[1m*[35mSQL (0.0ms)  INSERT INTO "orders" ("address", "email", "name", "user_id") VALUES (NULL, NULL, NULL, NULL)
Order 2 created
[Audit] Order 2 created
=> #<Order id: 2, user_id: nil, name: nil, address: nil, email: nil>
>> p = Payment.create
  *[1m*[36mSQL (15.0ms)  *[1mINSERT INTO "payments" VALUES(NULL)
[Audit] Payment 1 created
=> #<Payment id: 1>
 
?> >> 
irb e1/ar/attributes.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
>> require "pp"
=> ["PP"]
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> class LineItem < ActiveRecord::Base
>> end
=> nil
 
>> LineItem.delete_all
=> 1
 
>> LineItem.create(:quantity => 1, :product_id => 27, :order_id => 13, :unit_price => 29.95)
=> #<LineItem id: 3, product_id: 27, order_id: 13, quantity: 1, unit_price: #<BigDecimal:7e7699e4,'0.2995E2',8(8)>>
>> LineItem.create(:quantity => 2, :unit_price => 29.95)
=> #<LineItem id: 4, product_id: nil, order_id: nil, quantity: 2, unit_price: #<BigDecimal:7e75c6b8,'0.2995E2',8(8)>>
>> LineItem.create(:quantity => 1, :unit_price => 44.95)
=> #<LineItem id: 5, product_id: nil, order_id: nil, quantity: 1, unit_price: #<BigDecimal:7e752dac,'0.4495E2',8(8)>>
 
>> result = LineItem.find(:first)
=> #<LineItem id: 3, product_id: 27, order_id: 13, quantity: 1, unit_price: #<BigDecimal:7e74df3c,'0.2995E2',8(8)>>
>> p result.quantity
1
=> nil
>> p result.unit_price
#<BigDecimal:7e74b5fc,'0.2995E2',8(8)>
=> nil
 
>> result = LineItem.find_by_sql("select quantity, quantity*unit_price " +
?>                               "from line_items")
=> [#<LineItem quantity: 1>, #<LineItem quantity: 2>, #<LineItem quantity: 1>]
>> pp result[0].attributes
{"quantity*unit_price"=>"29.95", "quantity"=>1}
=> nil
 
>> result = LineItem.find_by_sql("select quantity, 
                                      quantity*unit_price as total_price " +
?>                               "from line_items")
=> [#<LineItem quantity: 1>, #<LineItem quantity: 2>, #<LineItem quantity: 1>]
>> pp result[0].attributes
{"quantity"=>1, "total_price"=>"29.95"}
=> nil
 
>> p result[0].total_price
"29.95"
=> nil
>> sales_tax = 0.07
=> 0.07
>> p result[0].total_price * sales_tax
""
=> nil
 
>> class LineItem < ActiveRecord::Base
>>   def total_price
>>     Float(read_attribute("total_price"))
>>   end
 
>>   CUBITS_TO_INCHES = 2.54
 
>>   def quantity
>>     read_attribute("quantity") * CUBITS_TO_INCHES
>>   end
 
>>   def quantity=(inches)
>>     write_attribute("quantity", Float(inches) / CUBITS_TO_INCHES)
>>   end
>> end
=> nil
 
>> p result[0].quantity
2.54
=> nil
 
>> result[0].quantity = 500
=> 500
>> p result[0].save
true
=> nil
 
?> >> 
sqlite3> select id, quantity*unit_price from line_items
                 id = 3
quantity*unit_price = 29.95
 
                 id = 4
quantity*unit_price = 59.9
 
                 id = 5
quantity*unit_price = 44.95
irb e1/ar/transactions.rb 1
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 0.8730s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:7e746e94,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:7e735cc0,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
=> true
 
 
 
>> >> => nil
sqlite3> select * from accounts
     id = 1
 number = 12345
balance = 90
 
     id = 2
 number = 54321
balance = 210
irb e1/ar/transactions.rb 2
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 0.8890s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:7e74362c,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:7e73449c,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
ActiveRecord::RecordInvalid: Validation failed: Balance is negative
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/validations.rb:69:in `save_without_dirty!'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/attribute_methods/dirty.rb:28:in `save_without_transactions!'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:200:in `save!'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:200:in `save!'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:200:in `save!'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:48:in `adjust_balance_and_save'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:37:in `withdraw'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:84
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:82
	from :0
 
 
 
>> >> => nil
sqlite3> select * from accounts
     id = 1
 number = 12345
balance = 100
 
     id = 2
 number = 54321
balance = 200
irb e1/ar/transactions.rb 3
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 0.8740s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:7e74362c,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:7e73449c,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
Transfer aborted
Paul has 550.0
Peter has -250.0
=> nil
 
 
 
>> >> => nil
irb e1/ar/transactions.rb 4
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 0.8740s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:7e74362c,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:7e73449c,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
Transfer aborted
Paul has 200.0
Peter has 100.0
=> nil
 
 
 
>> >> => nil
irb e1/ar/transactions.rb 5
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 0.8890s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:7e74362c,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:7e73449c,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
Transfer aborted
Paul has 200.0
Peter has 100.0
=> nil
 
 
 
>> >> => nil
irb e1/ar/optimistic.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activeresource/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/activemodel/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/gorp/lib", "/home/rubys/git/arel/lib", "/home/rubys/git/rack/lib", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/bin", "/usr/lib/ruby/gems/1.8/gems/bundler-0.8.1/lib", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/bin", "/usr/lib/ruby/gems/1.8/gems/i18n-0.3.3/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "/home/rubys/git/awdwr/work/migration/vendor/rails/actionpack/lib/action_controller/vendor/html-scanner", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> []
 
>> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> ActiveRecord::Schema.define do
?>   create_table :counters, :force => true do |t|
?>     t.integer :count
>>     t.integer :lock_version, :default => 0
>>   end
>> end
-- create_table(:counters, {:force=>true})
   -> 0.8580s
=> nil
 
 
?> class Counter < ActiveRecord::Base
>> end
=> nil
 
>> Counter.delete_all
=> 0
>> Counter.create(:count => 0)
=> #<Counter id: 1, count: 0, lock_version: 0>
 
>> count1 = Counter.find(:first)
=> #<Counter id: 1, count: 0, lock_version: 0>
>> count2 = Counter.find(:first)
=> #<Counter id: 1, count: 0, lock_version: 0>
 
>> count1.count += 3 
=> 3
>> count1.save
=> true
 
>> count2.count += 4 
=> 4
>> count2.save
ActiveRecord::StaleObjectError: Attempted to update a stale object
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/locking/optimistic.rb:91:in `update_without_dirty'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/attribute_methods/dirty.rb:64:in `update_without_timestamps'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/timestamp.rb:66:in `update_without_callbacks'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/callbacks.rb:275:in `update'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib/active_support/callbacks.rb:407:in `_run_update_callbacks'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/callbacks.rb:274:in `update'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/base.rb:2115:in `create_or_update_without_callbacks'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/callbacks.rb:261:in `create_or_update'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activesupport/lib/active_support/callbacks.rb:407:in `_run_save_callbacks'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/callbacks.rb:260:in `create_or_update'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/base.rb:1787:in `save_without_validation'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/validations.rb:57:in `save_without_dirty'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/attribute_methods/dirty.rb:19:in `save_without_transactions'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:229:in `send'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:229:in `with_transaction_returning_status'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `save'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
	from /home/rubys/git/awdwr/work/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `save'
	from /home/rubys/git/awdwr/data/code/e1/ar/optimistic.rb:31>> #END:optimistic
?> >> => nil

21 Action Controller: Routing and URLs

ruby /home/rubys/git/rails/railties/bin/rails restful
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
Restful::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
ruby script/generate scaffold article title:string summary:text content:text
      invoke  active_record
      create    db/migrate/20100202192737_create_articles.rb
      create    app/models/article.rb
      invoke    test_unit
      create      test/unit/article_test.rb
      create      test/fixtures/articles.yml
       route  resources :articles
      invoke  scaffold_controller
      create    app/controllers/articles_controller.rb
      invoke    erb
      create      app/views/articles
      create      app/views/articles/index.html.erb
      create      app/views/articles/edit.html.erb
      create      app/views/articles/show.html.erb
      create      app/views/articles/new.html.erb
      create      app/views/articles/_form.html.erb
      create      app/views/layouts/articles.html.erb
      invoke    test_unit
      create      test/functional/articles_controller_test.rb
      invoke    helper
      create      app/helpers/articles_helper.rb
      invoke      test_unit
      create        test/unit/helpers/articles_helper_test.rb
      invoke  stylesheets
      create    public/stylesheets/scaffold.css
rake db:migrate
mv 20100202192737_create_articles.rb 20100301000001_create_articles.rb
(in /home/rubys/git/awdwr/work/restful)
==  CreateArticles: migrating =================================================
-- create_table(:articles)
   -> 0.0000s
==  CreateArticles: migrated (0.0000s) ========================================
 
rake routes
(in /home/rubys/git/awdwr/work/restful)
             GET    /articles(.:format)                    {:controller=>"articles", :action=>"index"}
    articles POST   /articles(.:format)                    {:controller=>"articles", :action=>"create"}
 new_article GET    /articles/new(.:format)                {:controller=>"articles", :action=>"new"}
             GET    /articles/:id(.:format)                {:controller=>"articles", :action=>"show"}
             PUT    /articles/:id(.:format)                {:controller=>"articles", :action=>"update"}
     article DELETE /articles/:id(.:format)                {:controller=>"articles", :action=>"destroy"}
edit_article GET    /articles/:id/edit(.:format)           {:controller=>"articles", :action=>"edit"}
                    /:controller(/:action(/:id(.:format))) 
edit config/routes.rb
Restful::Application.routes.draw do |map|
  resources :articles
 
  # ...
 
   match ':controller(/:action(/:id(.:format)))'
end
edit app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  # GET /articles
  # GET /articles.xml
  def index
    @articles = Article.all
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @articles }
    end
  end
 
  # GET /articles/1
  # GET /articles/1.xml
  def show
    @article = Article.find(params[:id])
 
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @article }
    end
  end
 
  # GET /articles/new
  # GET /articles/new.xml
  def new
    @article = Article.new
 
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @article }
    end
  end
 
  # GET /articles/1/edit
  def edit
    @article = Article.find(params[:id])
  end
 
  # POST /articles
  # POST /articles.xml
  def create
    @article = Article.new(params[:article])
 
    respond_to do |format|
      if @article.save
        format.html { redirect_to(@article, :notice => 'Article was successfully created.') }
        format.xml  { render :xml => @article, :status => :created,
                             :location => @article }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @article.errors,
                             :status => :unprocessable_entity }
      end
    end
  end
 
  # PUT /articles/1
  # PUT /articles/1.xml
  def update
    @article = Article.find(params[:id])
 
    respond_to do |format|
      if @article.update_attributes(params[:article])
        format.html { redirect_to(@article, :notice => 'Article was successfully updated.') }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @article.errors,
                             :status => :unprocessable_entity }
      end
    end
  end
 
  # DELETE /articles/1
  # DELETE /articles/1.xml
  def destroy
    @article = Article.find(params[:id])
    @article.destroy
 
    respond_to do |format|
      format.html { redirect_to(articles_url) }
      format.xml  { head :ok }
    end
  end
end
edit app/views/articles/index.html.erb
<h1>Listing articles</h1>
 
<table>
  <tr>
    <th>Title</th>
    <th>Summary</th>
    <th>Content</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>
 
<% @articles.each do |article| %>
  <tr>
    <td><%= article.title %></td>
    <td><%= article.summary %></td>
    <td><%= article.content %></td>
    <td><%= link_to 'Show', article %></td>
    <td><%= link_to 'Edit', edit_article_path(article) %></td>
    <td><%= link_to 'Destroy', article, :confirm => 'Are you sure?',
                                        :method => :delete %></td>
  </tr>
<% end %>
</table>
 
<br />
 
<%= link_to 'New article', new_article_path %>
edit config/routes.rb
Restful::Application.routes.draw do |map|
  resources :articles do
    collection do
      get :recent
    end
  end
 
  # ...
 
 
  # ...
  # The priority is based upon order of creation:
  # first created -> highest priority.
 
  # Sample of regular route:
  #   match 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action
 
  # Sample of named route:
  #   match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)
 
  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products
 
  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get :short
  #       post :toggle
  #     end
  #
  #     collection do
  #       get :sold
  #     end
  #   end
 
  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end
 
  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get :recent, :on => :collection
  #     end
  #   end
 
  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end
 
  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => "welcome#index"
 
  # See how all your routes lay out with "rake routes"
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
rake routes
(in /home/rubys/git/awdwr/work/restful)
recent_articles GET    /articles/recent(.:format)             {:controller=>"articles", :action=>"recent"}
                GET    /articles(.:format)                    {:controller=>"articles", :action=>"index"}
       articles POST   /articles(.:format)                    {:controller=>"articles", :action=>"create"}
    new_article GET    /articles/new(.:format)                {:controller=>"articles", :action=>"new"}
                GET    /articles/:id(.:format)                {:controller=>"articles", :action=>"show"}
                PUT    /articles/:id(.:format)                {:controller=>"articles", :action=>"update"}
        article DELETE /articles/:id(.:format)                {:controller=>"articles", :action=>"destroy"}
   edit_article GET    /articles/:id/edit(.:format)           {:controller=>"articles", :action=>"edit"}
                       /:controller(/:action(/:id(.:format))) 
edit config/routes.rb
Restful::Application.routes.draw do |map|
  resources :articles do
    member do
      post :embargo, :release
    end
  end
 
  # ...
 
 
  # ...
  # The priority is based upon order of creation:
  # first created -> highest priority.
 
  # Sample of regular route:
  #   match 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action
 
  # Sample of named route:
  #   match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)
 
  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products
 
  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get :short
  #       post :toggle
  #     end
  #
  #     collection do
  #       get :sold
  #     end
  #   end
 
  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end
 
  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get :recent, :on => :collection
  #     end
  #   end
 
  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end
 
  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => "welcome#index"
 
  # See how all your routes lay out with "rake routes"
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
rake routes
(in /home/rubys/git/awdwr/work/restful)
embargo_article POST   /articles/:id/embargo(.:format)        {:controller=>"articles", :action=>"embargo"}
release_article POST   /articles/:id/release(.:format)        {:controller=>"articles", :action=>"release"}
                GET    /articles(.:format)                    {:controller=>"articles", :action=>"index"}
       articles POST   /articles(.:format)                    {:controller=>"articles", :action=>"create"}
    new_article GET    /articles/new(.:format)                {:controller=>"articles", :action=>"new"}
                GET    /articles/:id(.:format)                {:controller=>"articles", :action=>"show"}
                PUT    /articles/:id(.:format)                {:controller=>"articles", :action=>"update"}
        article DELETE /articles/:id(.:format)                {:controller=>"articles", :action=>"destroy"}
   edit_article GET    /articles/:id/edit(.:format)           {:controller=>"articles", :action=>"edit"}
                       /:controller(/:action(/:id(.:format))) 
edit config/routes.rb
Restful::Application.routes.draw do |map|
  resources :articles do
    collection do
      namespace('new') { post :shortform }
    end
  end
 
  # ...
 
 
  # ...
  # The priority is based upon order of creation:
  # first created -> highest priority.
 
  # Sample of regular route:
  #   match 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action
 
  # Sample of named route:
  #   match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)
 
  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products
 
  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get :short
  #       post :toggle
  #     end
  #
  #     collection do
  #       get :sold
  #     end
  #   end
 
  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end
 
  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get :recent, :on => :collection
  #     end
  #   end
 
  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end
 
  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => "welcome#index"
 
  # See how all your routes lay out with "rake routes"
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
rake routes
(in /home/rubys/git/awdwr/work/restful)
shortform_articles_new POST   /articles/new/shortform(.:format)      {:controller=>"articles", :action=>"shortform"}
                       GET    /articles(.:format)                    {:controller=>"articles", :action=>"index"}
              articles POST   /articles(.:format)                    {:controller=>"articles", :action=>"create"}
           new_article GET    /articles/new(.:format)                {:controller=>"articles", :action=>"new"}
                       GET    /articles/:id(.:format)                {:controller=>"articles", :action=>"show"}
                       PUT    /articles/:id(.:format)                {:controller=>"articles", :action=>"update"}
               article DELETE /articles/:id(.:format)                {:controller=>"articles", :action=>"destroy"}
          edit_article GET    /articles/:id/edit(.:format)           {:controller=>"articles", :action=>"edit"}
                              /:controller(/:action(/:id(.:format))) 
edit config/routes.rb
Restful::Application.routes.draw do |map|
  resources :articles do
    resources :comments
  end
 
  # ...
 
   match ':controller(/:action(/:id(.:format)))'
end
rake routes
(in /home/rubys/git/awdwr/work/restful)
                     GET    /articles/:article_id/comments(.:format)          {:controller=>"comments", :action=>"index"}
    article_comments POST   /articles/:article_id/comments(.:format)          {:controller=>"comments", :action=>"create"}
 new_article_comment GET    /articles/:article_id/comments/new(.:format)      {:controller=>"comments", :action=>"new"}
                     GET    /articles/:article_id/comments/:id(.:format)      {:controller=>"comments", :action=>"show"}
                     PUT    /articles/:article_id/comments/:id(.:format)      {:controller=>"comments", :action=>"update"}
     article_comment DELETE /articles/:article_id/comments/:id(.:format)      {:controller=>"comments", :action=>"destroy"}
edit_article_comment GET    /articles/:article_id/comments/:id/edit(.:format) {:controller=>"comments", :action=>"edit"}
                     GET    /articles(.:format)                               {:controller=>"articles", :action=>"index"}
            articles POST   /articles(.:format)                               {:controller=>"articles", :action=>"create"}
         new_article GET    /articles/new(.:format)                           {:controller=>"articles", :action=>"new"}
                     GET    /articles/:id(.:format)                           {:controller=>"articles", :action=>"show"}
                     PUT    /articles/:id(.:format)                           {:controller=>"articles", :action=>"update"}
             article DELETE /articles/:id(.:format)                           {:controller=>"articles", :action=>"destroy"}
        edit_article GET    /articles/:id/edit(.:format)                      {:controller=>"articles", :action=>"edit"}
                            /:controller(/:action(/:id(.:format)))            
ruby script/generate model comment comment:text article_id:integer
      invoke  active_record
      create    db/migrate/20100202192938_create_comments.rb
      create    app/models/comment.rb
      invoke    test_unit
      create      test/unit/comment_test.rb
      create      test/fixtures/comments.yml
ruby script/generate controller comments new edit update destroy
      create  app/controllers/comments_controller.rb
      invoke  erb
      create    app/views/comments
      create    app/views/comments/new.html.erb
      create    app/views/comments/edit.html.erb
      create    app/views/comments/update.html.erb
      create    app/views/comments/destroy.html.erb
      invoke  test_unit
      create    test/functional/comments_controller_test.rb
      invoke  helper
      create    app/helpers/comments_helper.rb
      invoke    test_unit
      create      test/unit/helpers/comments_helper_test.rb
rm app/views/comments/destroy.html.erb
rm app/views/comments/update.html.erb
edit app/models/article.rb
class Article < ActiveRecord::Base
  has_many :comments
end
edit app/models/comment.rb
class Comment < ActiveRecord::Base
  belongs_to :article
end
rake db:migrate
mv 20100202192938_create_comments.rb 20100301000002_create_comments.rb
(in /home/rubys/git/awdwr/work/restful)
==  CreateComments: migrating =================================================
-- create_table(:comments)
   -> 0.0000s
==  CreateComments: migrated (0.0000s) ========================================
 
edit app/views/articles/show.html.erb
<p>
  <b>Title:</b>
  <%= @article.title %>
</p>
 
<p>
  <b>Summary:</b>
  <%= @article.summary %>
</p>
 
<p>
  <b>Content:</b>
  <%= @article.content %>
</p>
 
 
<% unless @article.comments.empty? %>
  <%= render :partial => "/comments/comment",
	           :collection => @article.comments %>
<% end %>
 
<%= link_to "Add comment", new_article_comment_url(@article) %> |
<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>
edit app/views/comments/_comment.html.erb
<div class="comment">
  <p>
    <strong>Comment last updated: <%= comment.updated_at %></strong>
    <%= link_to "Edit", edit_article_comment_url(:id => comment,
                                      :article_id => comment.article) %>
 
    <%= link_to "Delete", article_comment_url(:id => comment,
                                      :article_id => comment.article), 
                                      :method => :delete %>
  </p>
  <blockquote>
    <%=h comment.comment %>
  </blockquote>
 
 
</div>                                    
edit app/views/comments/_form.html.erb
<%= form.text_area  :comment, :rows => 3 %>
edit app/views/comments/edit.html.erb
<h1>Editing comment</h1>
 
<%= error_messages_for :comment %>
 
<% form_for([@article,@comment]) do |f| %>
  <p>
    <b>Comment</b><br />
    <%= f.text_area :comment %>
  </p>
 
  <p>
    <b>Article</b><br />
    <%= f.text_field :article_id %>
  </p>
 
  <p>
    <%= f.submit "Update" %>
  </p>
<% end %>
 
<%= link_to 'Back', article_path(@article) %>
edit app/views/comments/new.html.erb
<% form_for [@article, @comment] do |form| %>
<fieldset>
  <legend>Add a Comment</legend>
	
  <%= render :partial => 'form', :object => form %>
 
  <p>
    <%= submit_tag "Create" %>
  </p>
</fieldset>
<% end %>
edit app/controllers/comments_controller.rb
class CommentsController < ApplicationController
 
  before_filter :find_article
 
  def new
    @comment = Comment.new
  end
 
  def edit
    @comment = @article.comments.find(params[:id])
  end
 
  def create
    @comment = Comment.new(params[:comment])
    if (@article.comments << @comment)
      redirect_to article_url(@article)
    else
      render :action => :new
    end
  end
 
  def update
    @comment = @article.comments.find(params[:id])
    if @comment.update_attributes(params[:comment])
      redirect_to article_url(@article)
    else
      render :action => :edit
    end
  end
 
  def destroy
    comment = @article.comments.find(params[:id])
    @article.comments.delete(comment)
    redirect_to article_url(@article)
  end
 
private
 
  def find_article
    @article_id = params[:article_id]
    return(redirect_to(articles_url)) unless @article_id
    @article = Article.find(@article_id)
  end
 
end
ruby /home/rubys/git/rails/railties/bin/rails routing
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
Routing::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
ruby script/generate controller store index add_to_cart
      create  app/controllers/store_controller.rb
      invoke  erb
      create    app/views/store
      create    app/views/store/index.html.erb
      create    app/views/store/add_to_cart.html.erb
      invoke  test_unit
      create    test/functional/store_controller_test.rb
      invoke  helper
      create    app/helpers/store_helper.rb
      invoke    test_unit
      create      test/unit/helpers/store_helper_test.rb
cp -v /home/rubys/git/awdwr/data/routing/* config
`/home/rubys/git/awdwr/data/routing/routes.rb' -> `config/routes.rb'
`/home/rubys/git/awdwr/data/routing/routes_with_conditions.rb' -> `config/routes_with_conditions.rb'
`/home/rubys/git/awdwr/data/routing/routes_with_names.rb' -> `config/routes_with_names.rb'
`/home/rubys/git/awdwr/data/routing/routing_conditions_test.rb' -> `config/routing_conditions_test.rb'
`/home/rubys/git/awdwr/data/routing/routing_test.rb' -> `config/routing_test.rb'
mv -v config/*_test.rb test/unit
`config/routing_conditions_test.rb' -> `test/unit/routing_conditions_test.rb'
`config/routing_test.rb' -> `test/unit/routing_test.rb'
rake db:schema:dump
(in /home/rubys/git/awdwr/work/routing)
rake test
(in /home/rubys/git/awdwr/work/routing)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.....
Finished in 0.842 seconds.
 
5 tests, 29 assertions, 0 failures, 0 errors
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.
Finished in 0.718 seconds.
 
1 tests, 1 assertions, 0 failures, 0 errors

21.2 Routing Requests

ls app/controllers/*_controller.rb
app/controllers/admin_controller.rb
app/controllers/application_controller.rb
app/controllers/info_controller.rb
app/controllers/line_items_controller.rb
app/controllers/orders_controller.rb
app/controllers/products_controller.rb
app/controllers/store_controller.rb
app/controllers/users_controller.rb
irb e1/routing/config/routes_for_depot.rb
>> require "./config/environment.rb"
=> ["RAILS_CACHE"]
 
>> Rails::Application.reload_routes!
=> nil
>> require "active_support/test_case"
=> ["Mocha"]
 
>> rs = ActionController::Routing::Routes
=> #<ActionDispatch::Routing::RouteSet:0x7e85068c @controller_constraints=/rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+/, @routes=[#<ActionDispatch::Routing::Route:0x7e6a100c @path="/users(.:format)", @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="users", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e752168 @glob_param=nil>, @requirements={:controller=>"users", :action=>"index"}, @segment_keys=[:format], @defaults={:controller=>"users", :action=>"index"}>, #<ActionDispatch::Routing::Route:0x7e633804 @path="/users(.:format)", @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="users", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e63477c @glob_param=nil>, @requirements={:controller=>"users", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"users", :action=>"create"}>, #<ActionDispatch::Routing::Route:0x7e629070 @path="/users/new(.:format)", @conditions={:path_info=>/\A\/users\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e62aa88 @glob_param=nil>, @requirements={:controller=>"users", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"users", :action=>"new"}>, #<ActionDispatch::Routing::Route:0x7e61f660 @path="/users/:id(.:format)", @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e620e0c @glob_param=nil>, @requirements={:controller=>"users", :action=>"show"}, @segment_keys=[:id, :format], @defaults={:controller=>"users", :action=>"show"}>, #<ActionDispatch::Routing::Route:0x7e6160b0 @path="/users/:id(.:format)", @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/}, @name="user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e617ac8 @glob_param=nil>, @requirements={:controller=>"users", :action=>"update"}, @segment_keys=[:id, :format], @defaults={:controller=>"users", :action=>"update"}>, #<ActionDispatch::Routing::Route:0x7e60f2c4 @path="/users/:id(.:format)", @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e6104d0 @glob_param=nil>, @requirements={:controller=>"users", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"users", :action=>"destroy"}>, #<ActionDispatch::Routing::Route:0x7e6070ec @path="/users/:id/edit(.:format)", @conditions={:path_info=>/\A\/users\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e60880c @glob_param=nil>, @requirements={:controller=>"users", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"users", :action=>"edit"}>, #<ActionDispatch::Routing::Route:0x7e5fbf80 @path="/line_items(.:format)", @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="line_items", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5fdd1c @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"index"}, @segment_keys=[:format], @defaults={:controller=>"line_items", :action=>"index"}>, #<ActionDispatch::Routing::Route:0x7e5f2df4 @path="/line_items(.:format)", @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="line_items", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5f4690 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"line_items", :action=>"create"}>, #<ActionDispatch::Routing::Route:0x7e5ec274 @path="/line_items/new(.:format)", @conditions={:path_info=>/\A\/line_items\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5edb10 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"line_items", :action=>"new"}>, #<ActionDispatch::Routing::Route:0x7e5e0c30 @path="/line_items/:id(.:format)", @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5e30d4 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"show"}, @segment_keys=[:id, :format], @defaults={:controller=>"line_items", :action=>"show"}>, #<ActionDispatch::Routing::Route:0x7e5d5fb0 @path="/line_items/:id(.:format)", @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/}, @name="line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5d76d0 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"update"}, @segment_keys=[:id, :format], @defaults={:controller=>"line_items", :action=>"update"}>, #<ActionDispatch::Routing::Route:0x7e5cbee8 @path="/line_items/:id(.:format)", @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5cd608 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"line_items", :action=>"destroy"}>, #<ActionDispatch::Routing::Route:0x7e5c42d8 @path="/line_items/:id/edit(.:format)", @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5c5f0c @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"line_items", :action=>"edit"}>, #<ActionDispatch::Routing::Route:0x7e5b8e4c @path="/orders(.:format)", @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="orders", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ba008 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"index"}, @segment_keys=[:format], @defaults={:controller=>"orders", :action=>"index"}>, #<ActionDispatch::Routing::Route:0x7e5aff2c @path="/orders(.:format)", @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="orders", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5b0fa8 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"orders", :action=>"create"}>, #<ActionDispatch::Routing::Route:0x7e5a962c @path="/orders/new(.:format)", @conditions={:path_info=>/\A\/orders\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ab044 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"orders", :action=>"new"}>, #<ActionDispatch::Routing::Route:0x7e5a03d8 @path="/orders/:id(.:format)", @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5a16e8 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"show"}, @segment_keys=[:id, :format], @defaults={:controller=>"orders", :action=>"show"}>, #<ActionDispatch::Routing::Route:0x7e596f90 @path="/orders/:id(.:format)", @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/}, @name="order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5982a0 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"update"}, @segment_keys=[:id, :format], @defaults={:controller=>"orders", :action=>"update"}>, #<ActionDispatch::Routing::Route:0x7e590384 @path="/orders/:id(.:format)", @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e591978 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"orders", :action=>"destroy"}>, #<ActionDispatch::Routing::Route:0x7e589548 @path="/orders/:id/edit(.:format)", @conditions={:path_info=>/\A\/orders\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e58ad6c @glob_param=nil>, @requirements={:controller=>"orders", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"orders", :action=>"edit"}>, #<ActionDispatch::Routing::Route:0x7e57ec38 @path="/products(.:format)", @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="products", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5800c4 @glob_param=nil>, @requirements={:controller=>"products", :action=>"index"}, @segment_keys=[:format], @defaults={:controller=>"products", :action=>"index"}>, #<ActionDispatch::Routing::Route:0x7e575fc0 @path="/products(.:format)", @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="products", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e577244 @glob_param=nil>, @requirements={:controller=>"products", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"products", :action=>"create"}>, #<ActionDispatch::Routing::Route:0x7e56f954 @path="/products/new(.:format)", @conditions={:path_info=>/\A\/products\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e570fe8 @glob_param=nil>, @requirements={:controller=>"products", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"products", :action=>"new"}>, #<ActionDispatch::Routing::Route:0x7e5663b8 @path="/products/:id(.:format)", @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5678e4 @glob_param=nil>, @requirements={:controller=>"products", :action=>"show"}, @segment_keys=[:id, :format], @defaults={:controller=>"products", :action=>"show"}>, #<ActionDispatch::Routing::Route:0x7e55a748 @path="/products/:id(.:format)", @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/}, @name="product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e55be54 @glob_param=nil>, @requirements={:controller=>"products", :action=>"update"}, @segment_keys=[:id, :format], @defaults={:controller=>"products", :action=>"update"}>, #<ActionDispatch::Routing::Route:0x7e552c00 @path="/products/:id(.:format)", @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e554410 @glob_param=nil>, @requirements={:controller=>"products", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"products", :action=>"destroy"}>, #<ActionDispatch::Routing::Route:0x7e54b52c @path="/products/:id/edit(.:format)", @conditions={:path_info=>/\A\/products\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e54cf6c @glob_param=nil>, @requirements={:controller=>"products", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"products", :action=>"edit"}>, #<ActionDispatch::Routing::Route:0x7e540eec @path="/:controller(/:action(/:id(.:format)))", @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/}, @name=nil, @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil>, @requirements={}, @defaults={}>, #<ActionDispatch::Routing::Route:0x7e52c988 @path="/rails/info/properties", @conditions={:path_info=>/\A\/rails\/info\/properties\Z/}, @name=nil, @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e52fa98 @glob_param=nil>, @requirements={:controller=>"rails/info", :action=>"properties"}, @defaults={:controller=>"rails/info", :action=>"properties"}>], @resources_path_names={:edit=>"edit", :new=>"new"}, @set=#<Rack::Mount::RouteSet:0x7e7bad94 @recognition_key_analyzer=nil, @optimized_recognize_defined=true, @generation_key_analyzer=nil, @routes=[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e752168 @glob_param=nil> @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"index"} @name=:users>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e63477c @glob_param=nil> @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"users", :action=>"create"} @name=:users>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e62aa88 @glob_param=nil> @conditions={:path_info=>/\A\/users\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"new"} @name=:new_user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e620e0c @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"show"} @name=:user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e617ac8 @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"users", :action=>"update"} @name=:user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e6104d0 @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"users", :action=>"destroy"} @name=:user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e60880c @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"edit"} @name=:edit_user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5fdd1c @glob_param=nil> @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"index"} @name=:line_items>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5f4690 @glob_param=nil> @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"line_items", :action=>"create"} @name=:line_items>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5edb10 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"new"} @name=:new_line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5e30d4 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"show"} @name=:line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5d76d0 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"line_items", :action=>"update"} @name=:line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5cd608 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"line_items", :action=>"destroy"} @name=:line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5c5f0c @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"edit"} @name=:edit_line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ba008 @glob_param=nil> @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"index"} @name=:orders>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5b0fa8 @glob_param=nil> @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"orders", :action=>"create"} @name=:orders>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ab044 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"new"} @name=:new_order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5a16e8 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"show"} @name=:order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5982a0 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"orders", :action=>"update"} @name=:order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e591978 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"orders", :action=>"destroy"} @name=:order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e58ad6c @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"edit"} @name=:edit_order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5800c4 @glob_param=nil> @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"index"} @name=:products>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e577244 @glob_param=nil> @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"products", :action=>"create"} @name=:products>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e570fe8 @glob_param=nil> @conditions={:path_info=>/\A\/products\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"new"} @name=:new_product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5678e4 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"show"} @name=:product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e55be54 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"products", :action=>"update"} @name=:product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e554410 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"products", :action=>"destroy"} @name=:product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e54cf6c @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"edit"} @name=:edit_product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e52fa98 @glob_param=nil> @conditions={:path_info=>/\A\/rails\/info\/properties\Z/} @defaults={:controller=>"rails/info", :action=>"properties"} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>], @valid_conditions=nil, @parameters_key="action_dispatch.request.path_parameters", @generation_keys=[:action, :controller], @generation_graph=#<Rack::Mount::Multimap:0x7e4fb3d8 @hash={"new"=>#<Rack::Mount::Multimap:0x7e4f9538 @hash={"line_items"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5edb10 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"new"} @name=:new_line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "orders"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ab044 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"new"} @name=:new_order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "products"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e570fe8 @glob_param=nil> @conditions={:path_info=>/\A\/products\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"new"} @name=:new_product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "users"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e62aa88 @glob_param=nil> @conditions={:path_info=>/\A\/users\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"new"} @name=:new_user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>]}>, "edit"=>#<Rack::Mount::Multimap:0x7e4f8b38 @hash={"line_items"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5c5f0c @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"edit"} @name=:edit_line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "orders"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e58ad6c @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"edit"} @name=:edit_order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "products"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e54cf6c @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"edit"} @name=:edit_product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "users"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e60880c @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"edit"} @name=:edit_user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>]}>, "destroy"=>#<Rack::Mount::Multimap:0x7e4f8db8 @hash={"line_items"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5cd608 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"line_items", :action=>"destroy"} @name=:line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "orders"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e591978 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"orders", :action=>"destroy"} @name=:order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "products"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e554410 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"products", :action=>"destroy"} @name=:product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "users"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e6104d0 @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"users", :action=>"destroy"} @name=:user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>]}>, "show"=>#<Rack::Mount::Multimap:0x7e4f92b8 @hash={"line_items"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5e30d4 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"show"} @name=:line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "orders"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5a16e8 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"show"} @name=:order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "products"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5678e4 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"show"} @name=:product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "users"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e620e0c @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"show"} @name=:user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>]}>, "index"=>#<Rack::Mount::Multimap:0x7e4f9a38 @hash={"line_items"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5fdd1c @glob_param=nil> @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"index"} @name=:line_items>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "orders"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ba008 @glob_param=nil> @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"index"} @name=:orders>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "products"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5800c4 @glob_param=nil> @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"index"} @name=:products>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "users"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e752168 @glob_param=nil> @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"index"} @name=:users>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>]}>, "create"=>#<Rack::Mount::Multimap:0x7e4f97b8 @hash={"line_items"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5f4690 @glob_param=nil> @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"line_items", :action=>"create"} @name=:line_items>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "orders"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5b0fa8 @glob_param=nil> @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"orders", :action=>"create"} @name=:orders>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "products"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e577244 @glob_param=nil> @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"products", :action=>"create"} @name=:products>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "users"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e63477c @glob_param=nil> @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"users", :action=>"create"} @name=:users>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>]}>, "update"=>#<Rack::Mount::Multimap:0x7e4f9038 @hash={"line_items"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5d76d0 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"line_items", :action=>"update"} @name=:line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "orders"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5982a0 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"orders", :action=>"update"} @name=:order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "products"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e55be54 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"products", :action=>"update"} @name=:product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>], "users"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e617ac8 @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/PUT/} @defaults={:controller=>"users", :action=>"update"} @name=:user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>]}>, "properties"=>#<Rack::Mount::Multimap:0x7e4f5640 @hash={"rails/info"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e52fa98 @glob_param=nil> @conditions={:path_info=>/\A\/rails\/info\/properties\Z/} @defaults={:controller=>"rails/info", :action=>"properties"} @name=nil>]}>}>, @recognition_graph=#<Rack::Mount::Multimap:0x7e51f0e4 @hash={"rails"=>#<Rack::Mount::Multimap:0x7e4fb798 @hash={}>, "line_items"=>#<Rack::Mount::Multimap:0x7e5020c0 @hash={"DELETE"=>#<Rack::Mount::Multimap:0x7e5010bc @hash={}>, "GET"=>#<Rack::Mount::Multimap:0x7e501a6c @hash={"new"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5fdd1c @glob_param=nil> @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"index"} @name=:line_items>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5edb10 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"new"} @name=:new_line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5e30d4 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"show"} @name=:line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5c5f0c @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"edit"} @name=:edit_line_item>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>]}>, "POST"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5f4690 @glob_param=nil> @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"line_items", :action=>"create"} @name=:line_items>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>], "PUT"=>#<Rack::Mount::Multimap:0x7e5013f0 @hash={}>}>, "orders"=>#<Rack::Mount::Multimap:0x7e500b6c @hash={"DELETE"=>#<Rack::Mount::Multimap:0x7e4ffb68 @hash={}>, "GET"=>#<Rack::Mount::Multimap:0x7e500518 @hash={"new"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ba008 @glob_param=nil> @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"index"} @name=:orders>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ab044 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"new"} @name=:new_order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5a16e8 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"show"} @name=:order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e58ad6c @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"edit"} @name=:edit_order>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>]}>, "POST"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5b0fa8 @glob_param=nil> @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"orders", :action=>"create"} @name=:orders>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>], "PUT"=>#<Rack::Mount::Multimap:0x7e4ffe9c @hash={}>}>, "products"=>#<Rack::Mount::Multimap:0x7e4ff618 @hash={"DELETE"=>#<Rack::Mount::Multimap:0x7e4fdfac @hash={}>, "GET"=>#<Rack::Mount::Multimap:0x7e4fefc4 @hash={"new"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5800c4 @glob_param=nil> @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"index"} @name=:products>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e570fe8 @glob_param=nil> @conditions={:path_info=>/\A\/products\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"new"} @name=:new_product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5678e4 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"show"} @name=:product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e54cf6c @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"edit"} @name=:edit_product>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>]}>, "POST"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e577244 @glob_param=nil> @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"products", :action=>"create"} @name=:products>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>], "PUT"=>#<Rack::Mount::Multimap:0x7e4fe934 @hash={}>}>, "users"=>#<Rack::Mount::Multimap:0x7e503614 @hash={"DELETE"=>#<Rack::Mount::Multimap:0x7e502610 @hash={}>, "GET"=>#<Rack::Mount::Multimap:0x7e502fc0 @hash={"new"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e752168 @glob_param=nil> @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"index"} @name=:users>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e62aa88 @glob_param=nil> @conditions={:path_info=>/\A\/users\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"new"} @name=:new_user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e620e0c @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"show"} @name=:user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e60880c @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"edit"} @name=:edit_user>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>]}>, "POST"=>[#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e63477c @glob_param=nil> @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"users", :action=>"create"} @name=:users>, #<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e540fc8 @glob_param=nil> @conditions={:path_info=>/\A\/(rails\/[_a-zA-Z0-9]+|[_a-zA-Z0-9]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?\Z/} @defaults={} @name=nil>, #<Rack::Mount::Route @app=#<Proc:0x7e87b440@/home/rubys/git/awdwr/work/depot/vendor/rails/actionpack/lib/action_dispatch/routing/route_set.rb:7> @conditions={} @defaults={} @name=nil>], "PUT"=>#<Rack::Mount::Multimap:0x7e502944 @hash={}>}>}>, @recognition_keys=[[:path_info, 0, /\.|\//], :request_method, [:path_info, 1, /\.|\//]], @request_class=Rack::Request, @named_routes={:new_product=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e570fe8 @glob_param=nil> @conditions={:path_info=>/\A\/products\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"new"} @name=:new_product>, :new_user=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e62aa88 @glob_param=nil> @conditions={:path_info=>/\A\/users\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"new"} @name=:new_user>, :edit_line_item=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5c5f0c @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"edit"} @name=:edit_line_item>, :product=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e554410 @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"products", :action=>"destroy"} @name=:product>, :line_item=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5cd608 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"line_items", :action=>"destroy"} @name=:line_item>, :users=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e63477c @glob_param=nil> @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"users", :action=>"create"} @name=:users>, :new_line_item=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5edb10 @glob_param=nil> @conditions={:path_info=>/\A\/line_items\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"line_items", :action=>"new"} @name=:new_line_item>, :edit_order=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e58ad6c @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"edit"} @name=:edit_order>, :line_items=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5f4690 @glob_param=nil> @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"line_items", :action=>"create"} @name=:line_items>, :products=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e577244 @glob_param=nil> @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"products", :action=>"create"} @name=:products>, :edit_product=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e54cf6c @glob_param=nil> @conditions={:path_info=>/\A\/products\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"products", :action=>"edit"} @name=:edit_product>, :orders=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5b0fa8 @glob_param=nil> @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/} @defaults={:controller=>"orders", :action=>"create"} @name=:orders>, :edit_user=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e60880c @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"users", :action=>"edit"} @name=:edit_user>, :new_order=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ab044 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/} @defaults={:controller=>"orders", :action=>"new"} @name=:new_order>, :user=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e6104d0 @glob_param=nil> @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"users", :action=>"destroy"} @name=:user>, :order=>#<Rack::Mount::Route @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e591978 @glob_param=nil> @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/} @defaults={:controller=>"orders", :action=>"destroy"} @name=:order>}>, @disable_clear_and_finalize=false, @controller_namespaces=#<Set: {"rails"}>, @named_routes=#<ActionDispatch::Routing::RouteSet::NamedRouteCollection:0x7e850650 @module=#<Module:0x7e8505ec>, @routes={:new_product=>#<ActionDispatch::Routing::Route:0x7e56f954 @path="/products/new(.:format)", @conditions={:path_info=>/\A\/products\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e570fe8 @glob_param=nil>, @requirements={:controller=>"products", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"products", :action=>"new"}>, :new_user=>#<ActionDispatch::Routing::Route:0x7e629070 @path="/users/new(.:format)", @conditions={:path_info=>/\A\/users\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e62aa88 @glob_param=nil>, @requirements={:controller=>"users", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"users", :action=>"new"}>, :edit_line_item=>#<ActionDispatch::Routing::Route:0x7e5c42d8 @path="/line_items/:id/edit(.:format)", @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5c5f0c @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"line_items", :action=>"edit"}>, :product=>#<ActionDispatch::Routing::Route:0x7e552c00 @path="/products/:id(.:format)", @conditions={:path_info=>/\A\/products\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e554410 @glob_param=nil>, @requirements={:controller=>"products", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"products", :action=>"destroy"}>, :line_item=>#<ActionDispatch::Routing::Route:0x7e5cbee8 @path="/line_items/:id(.:format)", @conditions={:path_info=>/\A\/line_items\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5cd608 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"line_items", :action=>"destroy"}>, :users=>#<ActionDispatch::Routing::Route:0x7e633804 @path="/users(.:format)", @conditions={:path_info=>/\A\/users(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="users", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e63477c @glob_param=nil>, @requirements={:controller=>"users", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"users", :action=>"create"}>, :new_line_item=>#<ActionDispatch::Routing::Route:0x7e5ec274 @path="/line_items/new(.:format)", @conditions={:path_info=>/\A\/line_items\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_line_item", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5edb10 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"line_items", :action=>"new"}>, :edit_order=>#<ActionDispatch::Routing::Route:0x7e589548 @path="/orders/:id/edit(.:format)", @conditions={:path_info=>/\A\/orders\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e58ad6c @glob_param=nil>, @requirements={:controller=>"orders", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"orders", :action=>"edit"}>, :line_items=>#<ActionDispatch::Routing::Route:0x7e5f2df4 @path="/line_items(.:format)", @conditions={:path_info=>/\A\/line_items(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="line_items", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5f4690 @glob_param=nil>, @requirements={:controller=>"line_items", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"line_items", :action=>"create"}>, :products=>#<ActionDispatch::Routing::Route:0x7e575fc0 @path="/products(.:format)", @conditions={:path_info=>/\A\/products(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="products", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e577244 @glob_param=nil>, @requirements={:controller=>"products", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"products", :action=>"create"}>, :edit_product=>#<ActionDispatch::Routing::Route:0x7e54b52c @path="/products/:id/edit(.:format)", @conditions={:path_info=>/\A\/products\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_product", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e54cf6c @glob_param=nil>, @requirements={:controller=>"products", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"products", :action=>"edit"}>, :orders=>#<ActionDispatch::Routing::Route:0x7e5aff2c @path="/orders(.:format)", @conditions={:path_info=>/\A\/orders(?:\.([^\/.?]+))?\Z/, :request_method=>/POST/}, @name="orders", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5b0fa8 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"create"}, @segment_keys=[:format], @defaults={:controller=>"orders", :action=>"create"}>, :edit_user=>#<ActionDispatch::Routing::Route:0x7e6070ec @path="/users/:id/edit(.:format)", @conditions={:path_info=>/\A\/users\/([^\/.?]+)\/edit(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="edit_user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e60880c @glob_param=nil>, @requirements={:controller=>"users", :action=>"edit"}, @segment_keys=[:id, :format], @defaults={:controller=>"users", :action=>"edit"}>, :new_order=>#<ActionDispatch::Routing::Route:0x7e5a962c @path="/orders/new(.:format)", @conditions={:path_info=>/\A\/orders\/new(?:\.([^\/.?]+))?\Z/, :request_method=>/GET/}, @name="new_order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e5ab044 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"new"}, @segment_keys=[:format], @defaults={:controller=>"orders", :action=>"new"}>, :user=>#<ActionDispatch::Routing::Route:0x7e60f2c4 @path="/users/:id(.:format)", @conditions={:path_info=>/\A\/users\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="user", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e6104d0 @glob_param=nil>, @requirements={:controller=>"users", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"users", :action=>"destroy"}>, :order=>#<ActionDispatch::Routing::Route:0x7e590384 @path="/orders/:id(.:format)", @conditions={:path_info=>/\A\/orders\/([^\/.?]+)(?:\.([^\/.?]+))?\Z/, :request_method=>/DELETE/}, @name="order", @app=#<ActionDispatch::Routing::RouteSet::Dispatcher:0x7e591978 @glob_param=nil>, @requirements={:controller=>"orders", :action=>"destroy"}, @segment_keys=[:id, :format], @defaults={:controller=>"orders", :action=>"destroy"}>}, @helpers=[:hash_for_users_path, :users_path, :hash_for_users_url, :users_url, :hash_for_users_path, :users_path, :hash_for_users_url, :users_url, :hash_for_new_user_path, :new_user_path, :hash_for_new_user_url, :new_user_url, :hash_for_user_path, :user_path, :hash_for_user_url, :user_url, :hash_for_user_path, :user_path, :hash_for_user_url, :user_url, :hash_for_user_path, :user_path, :hash_for_user_url, :user_url, :hash_for_edit_user_path, :edit_user_path, :hash_for_edit_user_url, :edit_user_url, :hash_for_line_items_path, :line_items_path, :hash_for_line_items_url, :line_items_url, :hash_for_line_items_path, :line_items_path, :hash_for_line_items_url, :line_items_url, :hash_for_new_line_item_path, :new_line_item_path, :hash_for_new_line_item_url, :new_line_item_url, :hash_for_line_item_path, :line_item_path, :hash_for_line_item_url, :line_item_url, :hash_for_line_item_path, :line_item_path, :hash_for_line_item_url, :line_item_url, :hash_for_line_item_path, :line_item_path, :hash_for_line_item_url, :line_item_url, :hash_for_edit_line_item_path, :edit_line_item_path, :hash_for_edit_line_item_url, :edit_line_item_url, :hash_for_orders_path, :orders_path, :hash_for_orders_url, :orders_url, :hash_for_orders_path, :orders_path, :hash_for_orders_url, :orders_url, :hash_for_new_order_path, :new_order_path, :hash_for_new_order_url, :new_order_url, :hash_for_order_path, :order_path, :hash_for_order_url, :order_url, :hash_for_order_path, :order_path, :hash_for_order_url, :order_url, :hash_for_order_path, :order_path, :hash_for_order_url, :order_url, :hash_for_edit_order_path, :edit_order_path, :hash_for_edit_order_url, :edit_order_url, :hash_for_products_path, :products_path, :hash_for_products_url, :products_url, :hash_for_products_path, :products_path, :hash_for_products_url, :products_url, :hash_for_new_product_path, :new_product_path, :hash_for_new_product_url, :new_product_url, :hash_for_product_path, :product_path, :hash_for_product_url, :product_url, :hash_for_product_path, :product_path, :hash_for_product_url, :product_url, :hash_for_product_path, :product_path, :hash_for_product_url, :product_url, :hash_for_edit_product_path, :edit_product_path, :hash_for_edit_product_url, :edit_product_url]>>
>> app = ActionDispatch::Integration::Session.new(nil)
=> #<ActionDispatch::Integration::Session:0x7e54d2dc @controller=nil, @request_count=0, @request=nil, @accept="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", @response=nil, @mock_session=#<Rack::MockSession:0x7e54d1c4 @after_request=[], @default_host="www.example.com", @app=nil, @last_response=nil, @last_request=nil>, @remote_addr="127.0.0.1", @app=nil, @host="www.example.com", @named_routes_configured=true, @https=false>
 
>> puts rs.routes
GET    /users(.:format)                         {:controller=>"users", :action=>"index"}
POST   /users(.:format)                         {:controller=>"users", :action=>"create"}
GET    /users/new(.:format)                     {:controller=>"users", :action=>"new"}
GET    /users/:id(.:format)                     {:controller=>"users", :action=>"show"}
PUT    /users/:id(.:format)                     {:controller=>"users", :action=>"update"}
DELETE /users/:id(.:format)                     {:controller=>"users", :action=>"destroy"}
GET    /users/:id/edit(.:format)                {:controller=>"users", :action=>"edit"}
GET    /line_items(.:format)                    {:controller=>"line_items", :action=>"index"}
POST   /line_items(.:format)                    {:controller=>"line_items", :action=>"create"}
GET    /line_items/new(.:format)                {:controller=>"line_items", :action=>"new"}
GET    /line_items/:id(.:format)                {:controller=>"line_items", :action=>"show"}
PUT    /line_items/:id(.:format)                {:controller=>"line_items", :action=>"update"}
DELETE /line_items/:id(.:format)                {:controller=>"line_items", :action=>"destroy"}
GET    /line_items/:id/edit(.:format)           {:controller=>"line_items", :action=>"edit"}
GET    /orders(.:format)                        {:controller=>"orders", :action=>"index"}
POST   /orders(.:format)                        {:controller=>"orders", :action=>"create"}
GET    /orders/new(.:format)                    {:controller=>"orders", :action=>"new"}
GET    /orders/:id(.:format)                    {:controller=>"orders", :action=>"show"}
PUT    /orders/:id(.:format)                    {:controller=>"orders", :action=>"update"}
DELETE /orders/:id(.:format)                    {:controller=>"orders", :action=>"destroy"}
GET    /orders/:id/edit(.:format)               {:controller=>"orders", :action=>"edit"}
GET    /products(.:format)                      {:controller=>"products", :action=>"index"}
POST   /products(.:format)                      {:controller=>"products", :action=>"create"}
GET    /products/new(.:format)                  {:controller=>"products", :action=>"new"}
GET    /products/:id(.:format)                  {:controller=>"products", :action=>"show"}
PUT    /products/:id(.:format)                  {:controller=>"products", :action=>"update"}
DELETE /products/:id(.:format)                  {:controller=>"products", :action=>"destroy"}
GET    /products/:id/edit(.:format)             {:controller=>"products", :action=>"edit"}
ANY    /:controller(/:action(/:id(.:format)))   {}
ANY    /rails/info/properties                   {:controller=>"rails/info", :action=>"properties"}
=> nil
>> rs.recognize_path "/store"
=> {:controller=>"store", :action=>"index"}
>> rs.recognize_path "/store/add_to_cart/1"
=> {:controller=>"store", :action=>"add_to_cart", :id=>"1"}
>> rs.recognize_path "/store/add_to_cart/1.xml"
=> {:controller=>"store", :format=>"xml", :action=>"add_to_cart", :id=>"1"}
>> rs.generate :controller => :store
=> "/store"
>> rs.generate :controller => :store, :id => 123
=> "/store/index/123"
>> app.url_for :controller => :store, :action => :display, :id => 123
=> "http://www.example.com/store/display/123"
 
ruby /home/rubys/git/rails/railties/bin/rails view
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
View::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
cp -v /home/rubys/git/awdwr/data/code/e1/views/app/controllers/*.rb app/controllers
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/array_controller.rb' -> `app/controllers/array_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/article_controller.rb' -> `app/controllers/article_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/blog1_controller.rb' -> `app/controllers/blog1_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/blog2_controller.rb' -> `app/controllers/blog2_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/blog_controller.rb' -> `app/controllers/blog_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/builder_controller.rb' -> `app/controllers/builder_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/form_controller.rb' -> `app/controllers/form_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/form_for_controller.rb' -> `app/controllers/form_for_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/pager_controller.rb' -> `app/controllers/pager_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/partial_controller.rb' -> `app/controllers/partial_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/products_controller.rb' -> `app/controllers/products_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/rhtml_controller.rb' -> `app/controllers/rhtml_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/test_controller.rb' -> `app/controllers/test_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/views/app/controllers/upload_controller.rb' -> `app/controllers/upload_controller.rb'
irb e1/routing/config/routes_for_blog.rb
>> require "./config/environment.rb"
=> ["RAILS_CACHE"]
 
>> ActionController::Base.session_store = nil
=> nil
>> require "active_support/test_case"
=> ["Mocha"]
 
>> rs = ActionController::Routing::Routes
=> #<ActionDispatch::Routing::RouteSet:0x7e850ad8 @routes=[], @resources_path_names={:edit=>"edit", :new=>"new"}, @disable_clear_and_finalize=false, @controller_namespaces=#<Set: {"rails"}>, @named_routes=#<ActionDispatch::Routing::RouteSet::NamedRouteCollection:0x7e850a9c @module=#<Module:0x7e850a38>, @routes={}, @helpers=[]>>
>> app = ActionDispatch::Integration::Session.new(nil)
=> #<ActionDispatch::Integration::Session:0x7e5c744c @controller=nil, @request=nil, @named_routes_configured=true, @https=false, @request_count=0, @app=nil, @accept="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", @host="www.example.com", @response=nil, @remote_addr="127.0.0.1", @mock_session=#<Rack::MockSession:0x7e5c735c @last_response=nil, @last_request=nil, @app=nil, @after_request=[], @default_host="www.example.com">>
 
?> ActionController::Routing::Routes.draw do |map| 
 
?>   # Straight 'http://my.app/blog/' displays the index 
?>   map.connect "blog/", 
?>               :controller => "blog", 
?>               :action => "index" 
 
?>   # Return articles for a year, year/month, or year/month/day 
?>   map.connect "blog/:year/:month/:day", 
?>               :controller => "blog", 
?>               :action => "show_date", 
?>               :requirements => { :year => /(19|20)\d\d/,
?>                                  :month => /[01]?\d/, 
?>                                  :day => /[0-3]?\d/}, 
?>               :day => nil, 
?>               :month => nil 
 
>>   # Show an article identified by an id 
?>   map.connect "blog/show/:id", 
?>               :controller => "blog", 
?>               :action => "show", 
?>               :id => /\d+/ 
 
>>   # Regular Rails routing for admin stuff 
?>   map.connect "blog/article/:action/:id",
?>               :controller => "article" 
 
>>   # Catchall so we can gracefully handle badly formed requests 
?>   map.connect "*anything", 
?>               :controller => "blog", 
?>               :action => "unknown_request" 
>> end
=> nil
 
>> rs.recognize_path "/blog"
=> {:controller=>"blog", :action=>"index"}
>> rs.recognize_path "/blog/show/123"
=> {:controller=>"blog", :action=>"show", :id=>"123"}
>> rs.recognize_path "/blog/2004"
=> {:controller=>"blog", :year=>"2004", :action=>"show_date"}
>> rs.recognize_path "/blog/2004/12"
=> {:month=>"12", :controller=>"blog", :year=>"2004", :action=>"show_date"}
>> rs.recognize_path "/blog/2004/12/25"
=> {:month=>"12", :controller=>"blog", :year=>"2004", :day=>"25", :action=>"show_date"}
>> rs.recognize_path "/blog/article/edit/123"
=> {:controller=>"article", :action=>"edit", :id=>"123"}
>> rs.recognize_path "/blog/article/show_stats"
=> {:controller=>"article", :action=>"show_stats"}
>> rs.recognize_path "/blog/wibble"
=> {:controller=>"blog", :anything=>["blog", "wibble"], :action=>"unknown_request"}
>> rs.recognize_path "/junk"
=> {:controller=>"blog", :anything=>["junk"], :action=>"unknown_request"}
 
>> last_request = rs.recognize_path "/blog/2006/07/28"
=> {:month=>"07", :controller=>"blog", :year=>"2006", :day=>"28", :action=>"show_date"}
>> rs.generate({:day => 25}, last_request)
=> "/blog/2006/07/25"
>> rs.generate({:year => 2005}, last_request)
=> "/blog/2005"
 
>> app.url_for :controller => 'blog', :action => 'show_date', :year => 2002
=> "http://www.example.com/blog/2002"
>> app.url_for :controller => 'blog', :action => 'show_date', :overwrite_params => {:year => "2002" }
=> "http://www.example.com/blog/2002"
 

23.3 Helpers for Formatting, Linking, and Pagination

Ticket 25 : Will Paginate is broken on Rails 3

cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/pager app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/pager' -> `app/views/pager'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/pager/user_list.erb' -> `app/views/pager/user_list.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/pager/user_list.html.erb' -> `app/views/pager/user_list.html.erb'
edit config/initializers/pagination.rb
require 'will_paginate'
ruby script/generate model user name:string
      invoke  active_record
      create    db/migrate/20100202193238_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/unit/user_test.rb
      create      test/fixtures/users.yml

Restart the server.

rake db:migrate
mv 20100202193238_create_users.rb 20100301000001_create_users.rb
(in /home/rubys/git/awdwr/work/view)
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0000s
==  CreateUsers: migrated (0.0160s) ===========================================
 
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> PagerController.new.populate
=> 763
>> 
get /pager/user_list

TypeError in PagerController#user_list

can't convert nil into Array

Rails.root: /home/rubys/git/awdwr/work/view

Application Trace | Framework Trace | Full Trace
app/controllers/pager_controller.rb:47:in `user_list'

Request

Parameters:

None

Show session dump

Show env dump

Response

Headers:

None

get /pager/user_list?page=2

TypeError in PagerController#user_list

can't convert nil into Array

Rails.root: /home/rubys/git/awdwr/work/view

Application Trace | Framework Trace | Full Trace
app/controllers/pager_controller.rb:47:in `user_list'

Request

Parameters:

{"page"=>"2"}

Show session dump

Show env dump

Response

Headers:

None

23.5 Forms That Wrap Model Objects

cp -rpv /home/rubys/git/awdwr/plugins/country_select vendor/plugins/
`/home/rubys/git/awdwr/plugins/country_select' -> `vendor/plugins/country_select'
`/home/rubys/git/awdwr/plugins/country_select/init.rb' -> `vendor/plugins/country_select/init.rb'
`/home/rubys/git/awdwr/plugins/country_select/install.rb' -> `vendor/plugins/country_select/install.rb'
`/home/rubys/git/awdwr/plugins/country_select/lib' -> `vendor/plugins/country_select/lib'
`/home/rubys/git/awdwr/plugins/country_select/lib/country_select.rb' -> `vendor/plugins/country_select/lib/country_select.rb'
`/home/rubys/git/awdwr/plugins/country_select/MIT-LICENSE' -> `vendor/plugins/country_select/MIT-LICENSE'
`/home/rubys/git/awdwr/plugins/country_select/README' -> `vendor/plugins/country_select/README'
`/home/rubys/git/awdwr/plugins/country_select/uninstall.rb' -> `vendor/plugins/country_select/uninstall.rb'

Restart the server.

ruby script/generate model product title:string description:text image_url:string price:decimal
      invoke  active_record
      create    db/migrate/20100202193419_create_products.rb
      create    app/models/product.rb
      invoke    test_unit
      create      test/unit/product_test.rb
      create      test/fixtures/products.yml
cp -v /home/rubys/git/awdwr/data/code/e1/views/db/migrate/*products.rb db/migrate/*products.rb
`/home/rubys/git/awdwr/data/code/e1/views/db/migrate/002_create_products.rb' -> `db/migrate/20100202193419_create_products.rb'
cp -v /home/rubys/git/awdwr/data/code/e1/views/app/models/shipping.rb app/models
`/home/rubys/git/awdwr/data/code/e1/views/app/models/shipping.rb' -> `app/models/shipping.rb'
ruby script/generate model detail product_id:integer sku:string manufacturer:string
      invoke  active_record
      create    db/migrate/20100202193436_create_details.rb
      create    app/models/detail.rb
      invoke    test_unit
      create      test/unit/detail_test.rb
      create      test/fixtures/details.yml
cp -v /home/rubys/git/awdwr/data/code/e1/views/db/migrate/*details.rb db/migrate/*details.rb
`/home/rubys/git/awdwr/data/code/e1/views/db/migrate/004_create_details.rb' -> `db/migrate/20100202193436_create_details.rb'
cp -v /home/rubys/git/awdwr/data/code/e1/views/app/models/detail.rb app/models
`/home/rubys/git/awdwr/data/code/e1/views/app/models/detail.rb' -> `app/models/detail.rb'
rake db:migrate
mv 20100202193419_create_products.rb 20100301000002_create_products.rb
mv 20100202193436_create_details.rb 20100301000003_create_details.rb
(in /home/rubys/git/awdwr/work/view)
==  CreateProducts: migrating =================================================
-- create_table(:products)
   -> 0.0470s
==  CreateProducts: migrated (0.0470s) ========================================
 
==  CreateDetails: migrating ==================================================
-- create_table(:details)
   -> 0.0000s
==  CreateDetails: migrated (0.0000s) =========================================
 
cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/form_for app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/form_for' -> `app/views/form_for'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/form_for/create.html.erb' -> `app/views/form_for/create.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/form_for/new.html.erb' -> `app/views/form_for/new.html.erb'
get /form_for/new

Title:

Description:

Image URL:

Price:

cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/test app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test' -> `app/views/test'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/calc.html.erb' -> `app/views/test/calc.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/calculate.html.erb' -> `app/views/test/calculate.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/dates.xml.builder' -> `app/views/test/dates.xml.builder'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/date_dump.html.erb' -> `app/views/test/date_dump.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/date_format.reval' -> `app/views/test/date_format.reval'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/date_tags.html.erb' -> `app/views/test/date_tags.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/example.rdoc' -> `app/views/test/example.rdoc'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/example1.reval' -> `app/views/test/example1.reval'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/numbers.xml.builder' -> `app/views/test/numbers.xml.builder'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/objects.xml.builder' -> `app/views/test/objects.xml.builder'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/select.html.erb' -> `app/views/test/select.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/t.html.erb' -> `app/views/test/t.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/test.html.erb' -> `app/views/test/test.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/test/text.xml.builder' -> `app/views/test/text.xml.builder'
get /test/select

 

 

 

 

 

 

 

 

 

 

 

xc

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/products app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/products' -> `app/views/products'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/products/create.html.erb' -> `app/views/products/create.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/products/new.html.erb' -> `app/views/products/new.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/products/show.html.erb' -> `app/views/products/show.html.erb'
get /products/new
Title:
Description:
Image url:
Details... SKU:
Manufacturer:

23.6 Custom Form Builders

cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/helpers/tagged_builder.rb app/helpers
`/home/rubys/git/awdwr/data/code/e1/views/app/helpers/tagged_builder.rb' -> `app/helpers/tagged_builder.rb'
cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/builder app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/builder' -> `app/views/builder'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/builder/new.html.erb' -> `app/views/builder/new.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/builder/new_with_helper.html.erb' -> `app/views/builder/new_with_helper.html.erb'
get /builder/new

<br/>

<br/>

<br/>

cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/helpers/builder_helper.rb app/helpers
`/home/rubys/git/awdwr/data/code/e1/views/app/helpers/builder_helper.rb' -> `app/helpers/builder_helper.rb'
get /builder/new_with_helper

<br/>

<br/>

<br/>

cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/array app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/array' -> `app/views/array'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/array/edit.html.erb' -> `app/views/array/edit.html.erb'
get /array/edit

23.7 Working with Nonmodel Fields

get /test/calculate

23.8 Uploading Files to Rails Applications

ruby script/generate model picture comment:string name:string content_type:string data:binary
      invoke  active_record
      create    db/migrate/20100202193521_create_pictures.rb
      create    app/models/picture.rb
      invoke    test_unit
      create      test/unit/picture_test.rb
      create      test/fixtures/pictures.yml
cp -v /home/rubys/git/awdwr/data/code/e1/views/db/migrate/*pictures.rb db/migrate/*pictures.rb
`/home/rubys/git/awdwr/data/code/e1/views/db/migrate/003_create_pictures.rb' -> `db/migrate/20100202193521_create_pictures.rb'
cp -v /home/rubys/git/awdwr/data/code/e1/views/app/models/picture.rb app/models
`/home/rubys/git/awdwr/data/code/e1/views/app/models/picture.rb' -> `app/models/picture.rb'
rake db:migrate
mv 20100202193521_create_pictures.rb 20100301000004_create_pictures.rb
(in /home/rubys/git/awdwr/work/view)
==  CreatePictures: migrating =================================================
-- create_table(:pictures)
   -> 0.0000s
==  CreatePictures: migrated (0.0000s) ========================================
 
cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/upload app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/upload' -> `app/views/upload'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/upload/get.html.erb' -> `app/views/upload/get.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/upload/save.html.erb' -> `app/views/upload/save.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/upload/show.html.erb' -> `app/views/upload/show.html.erb'
get /upload/get
Comment:
Upload your picture:

23.9 Layouts and Components

cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/partial app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/partial' -> `app/views/partial'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/partial/list.html.erb' -> `app/views/partial/list.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/partial/test1.html.erb' -> `app/views/partial/test1.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/partial/_animal.html.erb' -> `app/views/partial/_animal.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/partial/_article.html.erb' -> `app/views/partial/_article.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/partial/_partial.html.erb' -> `app/views/partial/_partial.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/partial/_spacer.html.erb' -> `app/views/partial/_spacer.html.erb'
get /partial/list

The animal is ant


The animal is bee


The animal is cat


The animal is dog


The animal is elk

23.10 Caching, Part Two

ruby script/generate model article body:text
      invoke  active_record
      create    db/migrate/20100202193556_create_articles.rb
      create    app/models/article.rb
      invoke    test_unit
      create      test/unit/article_test.rb
      create      test/fixtures/articles.yml
cp -v /home/rubys/git/awdwr/data/code/e1/views/app/models/article.rb app/models
`/home/rubys/git/awdwr/data/code/e1/views/app/models/article.rb' -> `app/models/article.rb'
cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/blog app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/blog' -> `app/views/blog'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/blog/index.html.erb' -> `app/views/blog/index.html.erb'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/blog/list.html.erb' -> `app/views/blog/list.html.erb'
get /blog/list
Tue Feb 02 14:35:57 -0500 2010 Tue Feb 02 14:35:57 -0500 2010
cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/blog1 app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/blog1' -> `app/views/blog1'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/blog1/list.html.erb' -> `app/views/blog1/list.html.erb'
get /blog1/list
Tue Feb 02 14:35:58 -0500 2010 Tue Feb 02 14:35:58 -0500 2010
cp -vr /home/rubys/git/awdwr/data/code/e1/views/app/views/blog2 app/views
`/home/rubys/git/awdwr/data/code/e1/views/app/views/blog2' -> `app/views/blog2'
`/home/rubys/git/awdwr/data/code/e1/views/app/views/blog2/list.html.erb' -> `app/views/blog2/list.html.erb'
get /blog2/list

There are a total of 4 articles.

23.11 Adding New Templating Systems

cp -v /home/rubys/git/awdwr/data/code/e1/views/config/initializers/* config/initializers/
`/home/rubys/git/awdwr/data/code/e1/views/config/initializers/register_eval_template.rb' -> `config/initializers/register_eval_template.rb'
`/home/rubys/git/awdwr/data/code/e1/views/config/initializers/register_rdoc_template.rb' -> `config/initializers/register_rdoc_template.rb'
cp -v /home/rubys/git/awdwr/data/code/e1/views/lib/*_template.rb lib
`/home/rubys/git/awdwr/data/code/e1/views/lib/eval_template.rb' -> `lib/eval_template.rb'
`/home/rubys/git/awdwr/data/code/e1/views/lib/rdoc_template.rb' -> `lib/rdoc_template.rb'

Restart the server.

get /test/example

Greetings from RDoc

Let’s see if we’re doing real formatting…

get /test/date_format
distance_of_time_in_words(Time.now, Time.local(2005, 12, 25)) => about 4 years
time_ago_in_words(Time.utc(2004, 12, 25)) => about 5 years
get /test/example1
Time.now => Tue Feb 02 14:36:22 -0500 2010
request.path => /test/example1
a = 1 => 1
b = 2 => 2
a + b => 3

25.1 Sending E-mail

ruby /home/rubys/git/rails/railties/bin/rails mailer
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
Mailer::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
ruby script/generate mailer OrderMailer confirm sent
      create  app/mailers/order_mailer.rb
      invoke  erb
      create    app/views/order_mailer
      create    app/views/order_mailer/confirm.text.erb
      create    app/views/order_mailer/sent.text.erb
      invoke  test_unit
      create    test/functional/order_mailer_test.rb
      create    test/fixtures/order_mailer/confirm
      create    test/fixtures/order_mailer/sent
cp -vr /home/rubys/git/awdwr/data/code/e1/mailer/db/migrate db
`/home/rubys/git/awdwr/data/code/e1/mailer/db/migrate' -> `db/migrate'
`/home/rubys/git/awdwr/data/code/e1/mailer/db/migrate/001_create_products.rb' -> `db/migrate/001_create_products.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/db/migrate/002_create_line_items.rb' -> `db/migrate/002_create_line_items.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/db/migrate/003_create_orders.rb' -> `db/migrate/003_create_orders.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/db/migrate/004_populate_data.rb' -> `db/migrate/004_populate_data.rb'
cp -v /home/rubys/git/awdwr/data/code/e1/mailer/app/controllers/* app/controllers
`/home/rubys/git/awdwr/data/code/e1/mailer/app/controllers/application.rb' -> `app/controllers/application.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/controllers/order_controller.rb' -> `app/controllers/order_controller.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/controllers/test_controller.rb' -> `app/controllers/test_controller.rb'
cp -v /home/rubys/git/awdwr/data/code/e1/mailer/app/models/* app/models
`/home/rubys/git/awdwr/data/code/e1/mailer/app/models/incoming_ticket_handler.rb' -> `app/models/incoming_ticket_handler.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/models/line_item.rb' -> `app/models/line_item.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/models/order.rb' -> `app/models/order.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/models/order_mailer.rb' -> `app/models/order_mailer.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/models/product.rb' -> `app/models/product.rb'
cp -vr /home/rubys/git/awdwr/data/code/e1/mailer/test .
`/home/rubys/git/awdwr/data/code/e1/mailer/test/fixtures/line_items.yml' -> `./test/fixtures/line_items.yml'
`/home/rubys/git/awdwr/data/code/e1/mailer/test/fixtures/orders.yml' -> `./test/fixtures/orders.yml'
`/home/rubys/git/awdwr/data/code/e1/mailer/test/fixtures/order_mailer/confirm' -> `./test/fixtures/order_mailer/confirm'
`/home/rubys/git/awdwr/data/code/e1/mailer/test/fixtures/order_mailer/sent' -> `./test/fixtures/order_mailer/sent'
`/home/rubys/git/awdwr/data/code/e1/mailer/test/fixtures/products.yml' -> `./test/fixtures/products.yml'
`/home/rubys/git/awdwr/data/code/e1/mailer/test/functional/order_controller_test.rb' -> `./test/functional/order_controller_test.rb'
`/home/rubys/git/awdwr/data/code/e1/mailer/test/functional/order_mailer_test.rb' -> `./test/functional/order_mailer_test.rb'
cp -vr /home/rubys/git/awdwr/data/code/e1/mailer/app/views/order_mailer app/views
`/home/rubys/git/awdwr/data/code/e1/mailer/app/views/order_mailer/confirm.erb' -> `app/views/order_mailer/confirm.erb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/views/order_mailer/sent.erb' -> `app/views/order_mailer/sent.erb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/views/order_mailer/survey.text.html.erb' -> `app/views/order_mailer/survey.text.html.erb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/views/order_mailer/survey.text.plain.erb' -> `app/views/order_mailer/survey.text.plain.erb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/views/order_mailer/_html_line_item.erb' -> `app/views/order_mailer/_html_line_item.erb'
`/home/rubys/git/awdwr/data/code/e1/mailer/app/views/order_mailer/_line_item.erb' -> `app/views/order_mailer/_line_item.erb'
mv app/models/order_mailer.rb app/mailers/
mv confirm.erb confirm.text.erb
mv _line_item.erb _line_item.text.erb
mv sent.erb sent.html.erb
edit sent.html.erb
<h3>Pragmatic Order Shipped</h3>
<p>
  This is just to let you know that we've shipped your recent order:
</p>
 
<table>
 <tr><th colspan="2">Qty</th><th>Description</th></tr>
 <%= render(:partial => "line_item", :collection => @order.line_items) %>
</table>
mv _html_line_item.erb _line_item.htlm.erb
rm sent.text.erb

Restart the server.

rake db:migrate
mv 001_create_products.rb 20100301000001_create_products.rb
mv 002_create_line_items.rb 20100301000002_create_line_items.rb
mv 003_create_orders.rb 20100301000003_create_orders.rb
mv 004_populate_data.rb 20100301000004_populate_data.rb
(in /home/rubys/git/awdwr/work/mailer)
==  CreateProducts: migrating =================================================
-- create_table(:products)
   -> 0.0000s
==  CreateProducts: migrated (0.0000s) ========================================
 
==  CreateLineItems: migrating ================================================
-- create_table(:line_items)
   -> 0.0000s
==  CreateLineItems: migrated (0.0000s) =======================================
 
==  CreateOrders: migrating ===================================================
-- create_table(:orders)
   -> 0.0160s
==  CreateOrders: migrated (0.0160s) ==========================================
 
==  PopulateData: migrating ===================================================
==  PopulateData: migrated (0.1870s) ==========================================
 
get /test/create_order
Date: Tue, 02 Feb 2010 14:37:18 -0500
From: orders@example.com
To: dave@example.com
Message-ID: <4b687eee40f10_12543f3ceada166d2@rubys-PC.mail>
Subject: Pragmatic Store Order Confirmation
Mime-Version: 1.0
Content-Type: text/plain;
	charset="utf-8";
Content-Transfer-Encoding: 7bit

Dear Dave Thomas

Thank you for your recent order from The Pragmatic Store.

You ordered the following items:

 1 x Programming Ruby, 2nd Edition
 1 x Pragmatic Project Automation


We'll send you a separate e-mail when your order ships.


get /test/ship_order
Thank you...
rake test
(in /home/rubys/git/awdwr/work/mailer)
Loaded suite /usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
DEPRECATION WARNING: OrderMailer.deliver_confirm is deprecated, use OrderMailer.confirm.deliver instead. (called from method_missing at /home/rubys/git/awdwr/work/mailer/vendor/rails/actionmailer/lib/action_mailer/base.rb:344)
DEPRECATION WARNING: Giving a hash to body is deprecated, please use instance variables instead. (called from process at /home/rubys/git/awdwr/work/mailer/vendor/rails/actionmailer/lib/action_mailer/old_api.rb:78)
DEPRECATION WARNING: OrderMailer.create_confirm is deprecated, use OrderMailer.confirm instead. (called from method_missing at /home/rubys/git/awdwr/work/mailer/vendor/rails/actionmailer/lib/action_mailer/base.rb:344)
DEPRECATION WARNING: Giving a hash to body is deprecated, please use instance variables instead. (called from process at /home/rubys/git/awdwr/work/mailer/vendor/rails/actionmailer/lib/action_mailer/old_api.rb:78)
DEPRECATION WARNING: OrderMailer.create_sent is deprecated, use OrderMailer.sent instead. (called from method_missing at /home/rubys/git/awdwr/work/mailer/vendor/rails/actionmailer/lib/action_mailer/base.rb:344)
DEPRECATION WARNING: Giving a hash to body is deprecated, please use instance variables instead. (called from process at /home/rubys/git/awdwr/work/mailer/vendor/rails/actionmailer/lib/action_mailer/old_api.rb:78)
...
Finished in 1.248 seconds.
 
3 tests, 9 assertions, 0 failures, 0 errors

26 Active Resources

Restart the server.

ruby /home/rubys/git/rails/railties/bin/rails depot_client
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/models
      create  app/views/layouts
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/cookie_verification_secret.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/session_store.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  log
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/application.js
      create  public/javascripts/controls.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/effects.js
      create  public/javascripts/prototype.js
      create  public/javascripts/rails.js
      create  script
      create  script/about
      create  script/console
      create  script/dbconsole
      create  script/destroy
      create  script/generate
      create  script/performance/benchmarker
      create  script/performance/profiler
      create  script/plugin
      create  script/runner
      create  script/server
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/functional
      create  test/integration
      create  test/unit
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
ln -s /home/rubys/git/rails vendor/rails
edit config/routes.rb
DepotClient::Application.routes.draw do |map|
  # ...
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end
edit app/models/product.rb
class Product < ActiveResource::Base
  self.site = 'http://dave:secret@localhost:3000/'
end
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Product.find(2).title
ActiveResource::Redirection: Failed.  Response code = 302.  Response message = Found . => http://localhost:3000/admin/login
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/connection.rb:125:in `handle_response'
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/connection.rb:114:in `request'
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/connection.rb:79:in `get'
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/connection.rb:217:in `with_auth'
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/connection.rb:79:in `get'
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/base.rb:852:in `find_single'
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/base.rb:752:in `find'
	from (irb):1
>> 
edit app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  layout "store"
  before_filter :authorize, :except => :login
  #...
 
 
protected
  def authorize
    unless User.find_by_id(session[:user_id])
      if session[:user_id] != :logged_out
        authenticate_or_request_with_http_basic('Depot') do |username, password|
          user = User.authenticate(username, password)
          session[:user_id] = user.id if user
        end
      else
        flash[:notice] = "Please log in"
        redirect_to :controller => 'admin', :action => 'login'
      end
    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 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] = :logged_out
    flash[:notice] = "Logged out"
    redirect_to(:action => "login")
  end
 
  def index
    @total_orders = Order.count
  end
end
edit app/controllers/line_items_controller.rb
  def create
    params[:line_item][:order_id] ||= params[:order_id]
    @line_item = LineItem.new(params[:line_item])
 
    respond_to do |format|
      if @line_item.save
        format.html { redirect_to(@line_item, :notice => 'LineItem was successfully created.') }
        format.xml  { render :xml => @line_item, :status => :created,
                             :location => @line_item }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @line_item.errors,
                             :status => :unprocessable_entity }
      end
    end
  end
edit config/routes.rb
Depot::Application.routes.draw do |map|
  resources :users
 
  resources :line_items
 
  resources(:orders) { resources :line_items }
 
  resources :products
 
  # ...
  # The priority is based upon order of creation:
  # first created -> highest priority.
 
  # Sample of regular route:
  #   match 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action
 
  # Sample of named route:
  #   match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)
 
  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products
 
  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get :short
  #       post :toggle
  #     end
  #
  #     collection do
  #       get :sold
  #     end
  #   end
 
  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end
 
  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get :recent, :on => :collection
  #     end
  #   end
 
  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end
 
  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => "welcome#index"
 
  # See how all your routes lay out with "rake routes"
 
  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
   match ':controller(/:action(/:id(.:format)))'
end

Restart the server.

IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Product.find(2).title
=> "Pragmatic Project Automation"
>> 
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> p = Product.find(2)
=> #<Product:0x7e43b740 @prefix_options={}, @attributes={"price"=>#<BigDecimal:7e43fa70,'0.2995E2',8(8)>, "created_at"=>Tue Feb 02 18:55:43 UTC 2010, "image_url"=>"/images/auto.jpg", "title"=>"Pragmatic Project Automation", "updated_at"=>Tue Feb 02 18:55:43 UTC 2010, "id"=>2, "description"=>"<p>\n       <em>Pragmatic Project Automation</em> shows you how to improve the \n       consistency and repeatability of your project's procedures using \n       automation to reduce risk and errors.\n      </p>\n      <p>\n        Simply put, we're going to put this thing called a computer to work \n        for you doing the mundane (but important) project stuff. That means \n        you'll have more time and energy to do the really \n        exciting---and difficult---stuff, like writing quality code.\n      </p>"}>
>> puts p.price
29.95
=> nil
>> p.price-=5
=> #<BigDecimal:7e434da0,'0.2495E2',8(16)>
>> p.save
=> true
>> 
get /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.

$24.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/models/order.rb
class Order < ActiveResource::Base
  self.site = 'http://dave:secret@localhost:3000/'
end
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> Order.find(1).name
=> "Dave Thomas"
>> Order.find(1).line_items
NoMethodError: undefined method `line_items' for #<Order:0x7e422bdc>
	from /home/rubys/git/awdwr/work/depot_client/vendor/rails/activeresource/lib/active_resource/base.rb:1411:in `method_missing'
	from (irb):2
>> 
?> >> 
edit app/models/line_item.rb
class LineItem < ActiveResource::Base
  self.site = 'http://dave:secret@localhost:3000/orders/:order_id'
end
get /admin/logout
HTTP Basic: Access denied.
get /admin/login
Please Log In
post /admin/login
You are being redirected.
get http://localhost:3000/admin

Welcome

It's Tue Feb 02 14:39:58 -0500 2010 We have 2 orders.
get /orders/1/line_items.xml
<?xml version="1.0" encoding="UTF-8"?>
<line-items type="array">
  <line-item>
    <created-at type="datetime">2010-02-02T18:58:22Z</created-at>
    <id type="integer">1</id>
    <order-id type="integer">1</order-id>
    <product-id type="integer">3</product-id>
    <quantity type="integer">1</quantity>
    <total-price type="decimal">28.5</total-price>
    <updated-at type="datetime">2010-02-02T18:58:22Z</updated-at>
  </line-item>
  <line-item>
    <created-at type="datetime">2010-02-02T19:01:13Z</created-at>
    <id type="integer">2</id>
    <order-id type="integer">2</order-id>
    <product-id type="integer">2</product-id>
    <quantity type="integer">2</quantity>
    <total-price type="decimal">59.9</total-price>
    <updated-at type="datetime">2010-02-02T19:01:13Z</updated-at>
  </line-item>
</line-items>
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> LineItem.find(:all, :params => {:order_id=>1})
=> [#<LineItem:0x7e42a800 @prefix_options={:order_id=>1}, @attributes={"created_at"=>Tue Feb 02 18:58:22 UTC 2010, "product_id"=>3, "quantity"=>1, "total_price"=>#<BigDecimal:7e42de88,'0.285E2',8(8)>, "updated_at"=>Tue Feb 02 18:58:22 UTC 2010, "id"=>1}>, #<LineItem:0x7e42a79c @prefix_options={:order_id=>1}, @attributes={"created_at"=>Tue Feb 02 19:01:13 UTC 2010, "product_id"=>2, "quantity"=>2, "total_price"=>#<BigDecimal:7e42a9e0,'0.599E2',8(8)>, "updated_at"=>Tue Feb 02 19:01:13 UTC 2010, "id"=>2}>]
>> 
IRBRC=tmp/irbrc ruby script/console < tmp/irbin
Loading development environment (Rails 3.0.pre)
>> li = LineItem.find(:all, :params => {:order_id=>1}).first
=> #<LineItem:0x7e429af4 @prefix_options={:order_id=>1}, @attributes={"created_at"=>Tue Feb 02 18:58:22 UTC 2010, "product_id"=>3, "quantity"=>1, "total_price"=>#<BigDecimal:7e42d154,'0.285E2',8(8)>, "updated_at"=>Tue Feb 02 18:58:22 UTC 2010, "id"=>1}>
>> puts li.total_price
28.5
=> nil
>> li.total_price*=0.8
=> 22.8
>> li.save
=> true
>> li2 = LineItem.new(:order_id=>1, :product_id=>2, :quantity=>1, :total_price=>0.0)
=> #<LineItem:0x7e3a4aac @prefix_options={:order_id=>1}, @attributes={"product_id"=>2, "quantity"=>1, "total_price"=>0.0}>
>> li2.save
=> true
>> 

Environment

Tue, 02 Feb 2010 19:40:38 GMT
/usr/bin/ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
gem -v
1.3.5
gem list
abstract (1.0.0)
activesupport (2.3.5)
builder (2.1.2)
bundler (0.8.1)
erubis (2.6.5)
gorp (0.22.2)
htmlentities (4.2.0)
i18n (0.3.3)
mail (2.1.2)
mime-types (1.16)
rack (1.1.0)
rack-mount (0.4.5)
rack-test (0.5.3)
rake (0.8.7)
rdoc (2.4.3)
sqlite3-ruby (1.2.5)
tzinfo (0.3.16)
will_paginate (2.3.12)
echo $RUBYLIB | sed "s/:/\n/g"
/home/rubys/git/gorp/lib
/home/rubys/git/arel/lib
/home/rubys/git/rack/lib
ruby /home/rubys/git/rails/railties/bin/rails -v
Rails 3.0.pre
git log -1
commit ff2d04a9ec43a8df9d63c69236feb4d82e0f59f0    
Author: José Valim <jose.valim@gmail.com>
Date:   Tue Feb 2 12:07:41 2010 +0100

    
    Revert "failing tests in multibyte_chars_test.rb fixed". The bug is in Ruby 1.9.1 p376, not in AS test suite.
    
    This reverts commit bf1f70d8776e28f9181faefc4914059b4ad26b99.    

Todos