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
Pragmatic Bookshelf
Your Pragmatic Catalog
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.
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.
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.
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
Pragmatic Bookshelf
post /admin/login
name => dave
password => secret
You are being
redirected .
get http://localhost:3000/admin/index
Pragmatic Bookshelf
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