The Depot Application

The Depot Application

Table of Contents 25.1 Sending E-mail

26 Active Resources

Restart the server.

ruby -rubygems /home/rubys/git/rails/bin/rails new depot_client
      create  
      create  README
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/controllers/application_controller.rb
      create  app/mailers
      create  app/models
      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/test.rb
      create  config/environments/production.rb
      create  config/initializers
      create  config/initializers/mime_types.rb
      create  config/initializers/inflections.rb
      create  config/initializers/session_store.rb
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/secret_token.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/500.html
      create  public/robots.txt
      create  public/favicon.ico
      create  public/422.html
      create  public/404.html
      create  public/index.html
      create  public/images
      create  public/images/rails.png
      create  public/stylesheets
      create  public/stylesheets/.gitkeep
      create  public/javascripts
      create  public/javascripts/prototype.js
      create  public/javascripts/dragdrop.js
      create  public/javascripts/rails.js
      create  public/javascripts/effects.js
      create  public/javascripts/controls.js
      create  public/javascripts/application.js
      create  script
      create  script/rails
      create  test
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  test/fixtures
      create  test/unit
      create  test/functional
      create  test/integration
      create  tmp
      create  tmp/sessions
      create  tmp/sockets
      create  tmp/cache
      create  tmp/pids
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
bundle install
Using rake (0.8.7) 
Using abstract (1.0.0) 
Using activesupport (3.0.0.rc) from source at /home/rubys/git/rails 
Using builder (2.1.2) 
Using i18n (0.4.1) 
Using activemodel (3.0.0.rc) from source at /home/rubys/git/rails 
Using erubis (2.6.6) 
Using rack (1.2.1) 
Using rack-mount (0.6.9) 
Using rack-test (0.5.4) 
Using tzinfo (0.3.22) 
Using actionpack (3.0.0.rc) from source at /home/rubys/git/rails 
Using mime-types (1.16) 
Using polyglot (0.3.1) 
Using treetop (1.4.8) 
Using mail (2.2.5) 
Using actionmailer (3.0.0.rc) from source at /home/rubys/git/rails 
Using arel (0.4.0) 
Using activerecord (3.0.0.rc) from source at /home/rubys/git/rails 
Using activeresource (3.0.0.rc) from source at /home/rubys/git/rails 
Using bundler (1.0.0.rc.3) 
Using thor (0.14.0) 
Using railties (3.0.0.rc) from source at /home/rubys/git/rails 
Using rails (3.0.0.rc) from source at /home/rubys/git/rails 
Using sqlite3-ruby (1.3.1) 
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
*[32m
Your bundle was installed to `/home/rubys/.rvm/gems/ruby-1.8.8-r28862`*[0m
edit config/routes.rb
DepotClient::Application.routes.draw do
  # ...
 
  # 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
echo "Product.find(2).title" | IRBRC=tmp/irbrc rails console
Loading development environment (Rails 3.0.0.rc)
>> Product.find(2).title
ActiveResource::Redirection: Failed.  Response code = 302.  Response message = Found . => http://localhost:3000/admin/login
	from /home/rubys/git/rails/activeresource/lib/active_resource/connection.rb:125:in `handle_response'
	from /home/rubys/git/rails/activeresource/lib/active_resource/connection.rb:114:in `request'
	from /home/rubys/git/rails/activeresource/lib/active_resource/connection.rb:79:in `get'
	from /home/rubys/git/rails/activeresource/lib/active_resource/connection.rb:217:in `with_auth'
	from /home/rubys/git/rails/activeresource/lib/active_resource/connection.rb:79:in `get'
	from /home/rubys/git/rails/activeresource/lib/active_resource/base.rb:881:in `find_single'
	from /home/rubys/git/rails/activeresource/lib/active_resource/base.rb:781: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 => 'Line item 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
  get "info/who_bought"
 
  get "admin/login"
 
  get "admin/logout"
 
  get "admin/index"
 
  resources :users
 
  resources :line_items
 
  resources(:orders) { resources :line_items }
 
  get "store/index"
 
  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.

echo "Product.find(2).title" | IRBRC=tmp/irbrc rails console
Loading development environment (Rails 3.0.0.rc)
>> Product.find(2).title
=> "Pragmatic Project Automation"
>> 
echo "p = Product.find(2)\\nputs p.price\\np.price-=5\\np.save" | IRBRC=tmp/irbrc rails console
Loading development environment (Rails 3.0.0.rc)
>> p = Product.find(2)
=> #<Product:0xb6b3ba08 @prefix_options={}, @attributes={"price"=>#<BigDecimal:b6b3ed20,'0.2995E2',8(8)>, "created_at"=>Sat Aug 07 13:14:15 UTC 2010, "title"=>"Pragmatic Project Automation", "image_url"=>"/images/auto.jpg", "updated_at"=>Sat Aug 07 13:14:15 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:b6b34370,'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
echo "Order.find(1).name\\nOrder.find(1).line_items\\n" | IRBRC=tmp/irbrc rails console
Loading development environment (Rails 3.0.0.rc)
>> Order.find(1).name
=> "Dave Thomas"
>> Order.find(1).line_items
NoMethodError: undefined method `line_items' for #<Order:0xb6bad20c>
	from /home/rubys/git/rails/activeresource/lib/active_resource/base.rb:1401: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/index

Welcome

It's Sat Aug 07 09:24:12 -0400 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-08-07T13:15:14Z</created-at>
    <product-id type="integer">3</product-id>
    <quantity type="integer">1</quantity>
    <order-id type="integer">1</order-id>
    <total-price type="decimal">28.5</total-price>
    <updated-at type="datetime">2010-08-07T13:15:14Z</updated-at>
    <id type="integer">1</id>
  </line-item>
  <line-item>
    <created-at type="datetime">2010-08-07T13:16:11Z</created-at>
    <product-id type="integer">2</product-id>
    <quantity type="integer">2</quantity>
    <order-id type="integer">2</order-id>
    <total-price type="decimal">59.9</total-price>
    <updated-at type="datetime">2010-08-07T13:16:11Z</updated-at>
    <id type="integer">2</id>
  </line-item>
</line-items>
echo "LineItem.find(:all, :params => {:order_id=>1})" | IRBRC=tmp/irbrc rails console
Loading development environment (Rails 3.0.0.rc)
>> LineItem.find(:all, :params => {:order_id=>1})
=> [#<LineItem:0xb6ae6760 @prefix_options={:order_id=>1}, @attributes={"created_at"=>Sat Aug 07 13:15:14 UTC 2010, "quantity"=>1, "product_id"=>3, "total_price"=>#<BigDecimal:b6ae8790,'0.285E2',8(8)>, "updated_at"=>Sat Aug 07 13:15:14 UTC 2010, "id"=>1}>, #<LineItem:0xb6ae66fc @prefix_options={:order_id=>1}, @attributes={"created_at"=>Sat Aug 07 13:16:11 UTC 2010, "quantity"=>2, "product_id"=>2, "total_price"=>#<BigDecimal:b6ae692c,'0.599E2',8(8)>, "updated_at"=>Sat Aug 07 13:16:11 UTC 2010, "id"=>2}>]
>> 
echo "li = LineItem.find(:all, :params => {:order_id=>1}).first\\nputs li.total_price\\nli.total_price*=0.8\\nli.save\\nli2 = LineItem.new(:order_id=>1, :product_id=>2, :quantity=>1, :total_price=>0.0)\\nli2.save" | IRBRC=tmp/irbrc rails console
Loading development environment (Rails 3.0.0.rc)
>> li = LineItem.find(:all, :params => {:order_id=>1}).first
=> #<LineItem:0xb6b7a294 @prefix_options={:order_id=>1}, @attributes={"created_at"=>Sat Aug 07 13:15:14 UTC 2010, "quantity"=>1, "product_id"=>3, "total_price"=>#<BigDecimal:b6b7c904,'0.285E2',8(8)>, "updated_at"=>Sat Aug 07 13:15:14 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:0xb6ae7e08 @prefix_options={:order_id=>1}, @attributes={"quantity"=>1, "product_id"=>2, "total_price"=>0.0}>
>> li2.save
=> true
>> 

Table of Contents 25.1 Sending E-mail