Simple relationship

Create the application.

ruby -rubygems /home/rubys/git/rails/bin/rails new depot
      create  
      create  README
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/images/rails.png
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/mailers
      create  app/models
      create  app/views/layouts/application.html.erb
      create  app/mailers/.gitkeep
      create  app/models/.gitkeep
      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/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/secret_token.rb
      create  config/initializers/session_store.rb
      create  config/initializers/wrap_parameters.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/.gitkeep
      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  script
      create  script/rails
      create  test/fixtures
      create  test/fixtures/.gitkeep
      create  test/functional
      create  test/functional/.gitkeep
      create  test/integration
      create  test/integration/.gitkeep
      create  test/unit
      create  test/unit/.gitkeep
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/.gitkeep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.gitkeep
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
bundle install
Using rake (0.8.7) 
Using multi_json (1.0.1) 
Using activesupport (3.1.0.beta1) from source at /home/rubys/git/rails 
Using bcrypt-ruby (2.1.4) 
Using builder (3.0.0) 
Using i18n (0.6.0beta1) 
Using activemodel (3.1.0.beta1) from source at /home/rubys/git/rails 
Using erubis (2.7.0) 
Using rack (1.3.0.beta) 
Using rack-cache (1.0.1) 
Using rack-mount (0.7.2) 
Using rack-test (0.6.0) 
Using hike (0.7.1) 
Using tilt (1.3) 
Using sprockets (2.0.0) from source at /home/rubys/git/sprockets 
Using tzinfo (0.3.27) 
Using actionpack (3.1.0.beta1) from source at /home/rubys/git/rails 
Using mime-types (1.16) 
Using polyglot (0.3.1) 
Using treetop (1.4.9) 
Using mail (2.3.0) 
Using actionmailer (3.1.0.beta1) from source at /home/rubys/git/rails 
Using arel (2.1.0.20110430172428) from source at /home/rubys/git/arel 
Using activerecord (3.1.0.beta1) from source at /home/rubys/git/rails 
Using activeresource (3.1.0.beta1) from source at /home/rubys/git/rails 
Using bundler (1.0.12) 
Using coffee-script-source (1.1.0) 
Using execjs (0.3.3) 
Using coffee-script (2.2.0) 
Using rack-ssl (1.3.2) 
Using thor (0.14.6) 
Using railties (3.1.0.beta1) from source at /home/rubys/git/rails 
Using rails (3.1.0.beta1) from source at /home/rubys/git/rails 
Using jquery-rails (1.0) 
Using json (1.5.1) 
Using sass (3.1.1) 
Using sqlite3 (1.3.3) 
Using uglifier (0.5.1) 
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.

Generating our first model and associated scaffolding

rails generate scaffold product title:string
      invoke  active_record
      create    db/migrate/20110509143249_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
      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
      create  app/assets/stylesheets/scaffold.css.scss
      invoke  assets
      create    app/assets/javascripts/products.js.coffee
      create    app/assets/stylesheets/products.css.scss

Create a second controller with a single index action

rails generate controller store index
      create  app/controllers/store_controller.rb
       route  get "store/index"
      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
      invoke  assets
      create    app/assets/javascripts/store.js.coffee
      create    app/assets/stylesheets/store.css.scss

Create a cart.

rails generate scaffold cart
      invoke  active_record
      create    db/migrate/20110509143252_create_carts.rb
      create    app/models/cart.rb
      invoke    test_unit
      create      test/unit/cart_test.rb
      create      test/fixtures/carts.yml
       route  resources :carts
      invoke  scaffold_controller
      create    app/controllers/carts_controller.rb
      invoke    erb
      create      app/views/carts
      create      app/views/carts/index.html.erb
      create      app/views/carts/edit.html.erb
      create      app/views/carts/show.html.erb
      create      app/views/carts/new.html.erb
      create      app/views/carts/_form.html.erb
      invoke    test_unit
      create      test/functional/carts_controller_test.rb
      invoke    helper
      create      app/helpers/carts_helper.rb
      invoke      test_unit
      create        test/unit/helpers/carts_helper_test.rb
   identical  app/assets/stylesheets/scaffold.css.scss
      invoke  assets
      create    app/assets/javascripts/carts.js.coffee
      create    app/assets/stylesheets/carts.css.scss

Create an order.

rails generate scaffold order
      invoke  active_record
      create    db/migrate/20110509143253_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
      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
   identical  app/assets/stylesheets/scaffold.css.scss
      invoke  assets
      create    app/assets/javascripts/orders.js.coffee
      create    app/assets/stylesheets/orders.css.scss

Create the relationship object.

rails generate scaffold line_item product_id:integer cart_id:integer order_id:integer
      invoke  active_record
      create    db/migrate/20110509143255_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
      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
   identical  app/assets/stylesheets/scaffold.css.scss
      invoke  assets
      create    app/assets/javascripts/line_items.js.coffee
      create    app/assets/stylesheets/line_items.css.scss

Cart has many line items.

edit app/models/cart.rb
class Cart < ActiveRecord::Base
  has_many :line_items, :dependent=>:destroy
end

Order has many line items.

edit app/models/order.rb
class Order < ActiveRecord::Base
  has_many :line_items, :dependent=>:destroy
end

Product has many line items.

edit app/models/product.rb
class Product < ActiveRecord::Base
  has_many :line_items
end

Line item belongs to both Product and either a Cart or Order

edit app/models/line_item.rb
class LineItem < ActiveRecord::Base
  belongs_to :product
  belongs_to :cart
  belongs_to :order
end

Custom logic for creating a cart from an order

edit app/controllers/orders_controller.rb
  def create
    cart = Cart.find_by_id(params[:cart_id])
    @order = Order.new(params[:order])
 
    # move line items from cart to order
    cart.line_items.each do |item|
      item.cart_id = nil
      @order.line_items << item
    end
 
    respond_to do |format|
      if @order.save
        Cart.destroy(params[:cart_id])
        format.html { redirect_to @order, :notice => 'Order was successfully created.' }
        format.json { render :json => @order, :status => :created, :location => @order }
      else
        format.html { render :action => "new" }
        format.json { render :json => @order.errors, :status => :unprocessable_entity }
      end
    end
  end
rake db:migrate
mv 20110509143249_create_products.rb 20110211000001_create_products.rb
mv 20110509143252_create_carts.rb 20110211000002_create_carts.rb
mv 20110509143253_create_orders.rb 20110211000003_create_orders.rb
mv 20110509143255_create_line_items.rb 20110211000004_create_line_items.rb
(in /home/rubys/tmp/work/depot)
==  CreateProducts: migrating =================================================
-- create_table(:products)
   -> 0.0017s
==  CreateProducts: migrated (0.0018s) ========================================
 
==  CreateCarts: migrating ====================================================
-- create_table(:carts)
   -> 0.0014s
==  CreateCarts: migrated (0.0015s) ===========================================
 
==  CreateOrders: migrating ===================================================
-- create_table(:orders)
   -> 0.0012s
==  CreateOrders: migrated (0.0013s) ==========================================
 
==  CreateLineItems: migrating ================================================
-- create_table(:line_items)
   -> 0.0018s
==  CreateLineItems: migrated (0.0019s) =======================================
 

Start the server.

Create a product

get /products/new

New product


Back
post /products
  • product[title] => Pragmatic Version Control
You are being redirected.
get http://localhost:3000/products/1

Product was successfully created.

Title: Pragmatic Version Control

Edit | Back

Create a cart

get /carts/new

New cart

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

Cart was successfully created.

Edit | Back

Connect the two

get /line_items/new

New line_item




Back
post /line_items
  • line_item[cart_id] => 1
  • line_item[product_id] => 1
You are being redirected.
get http://localhost:3000/line_items/1

Line item was successfully created.

Product: 1

Cart: 1

Order:

Edit | Back

Show the line item

sqlite3> select * from line_items
        id = 1
product_id = 1
   cart_id = 1
  order_id = 
created_at = 2011-05-09 14:33:08.919984
updated_at = 2011-05-09 14:33:08.919984

Create an order from a cart

post /orders
  • cart_id => 1
You are being redirected.
get http://localhost:3000/orders/1

Order was successfully created.

Edit | Back

Show the line item

sqlite3> select * from line_items
null cart id.

Traceback:
  relation.rb:97
  /home/rubys/git/gorp/lib/gorp/test.rb:151:in `call'
  /home/rubys/git/gorp/lib/gorp/test.rb:151:in `db'
  relation.rb:96

Environment

Mon, 09 May 2011 14:33:09 GMT
echo $PATH
/home/rubys/.rvm/gems/ruby-1.8.7-p334/bin:/home/rubys/.rvm/gems/ruby-1.8.7-p334@global/bin:/home/rubys/.rvm/rubies/ruby-1.8.7-p334/bin:/home/rubys/.rvm/bin:/home/rubys/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
node -v
v0.2.6
/home/rubys/.rvm/rubies/ruby-1.8.7-p334/bin/ruby -v
ruby 1.8.7 (2011-02-18 patchlevel 334) [x86_64-linux]
gem -v
1.6.2
bundle show
Gems included by the bundle:
  * actionmailer (3.1.0.beta1)
  * actionpack (3.1.0.beta1)
  * activemodel (3.1.0.beta1)
  * activerecord (3.1.0.beta1)
  * activeresource (3.1.0.beta1)
  * activesupport (3.1.0.beta1)
  * arel (2.1.0.20110430172428 a6f56d8)
  * bcrypt-ruby (2.1.4)
  * builder (3.0.0)
  * bundler (1.0.12)
  * coffee-script (2.2.0)
  * coffee-script-source (1.1.0)
  * erubis (2.7.0)
  * execjs (0.3.3)
  * hike (0.7.1)
  * i18n (0.6.0beta1)
  * jquery-rails (1.0)
  * json (1.5.1)
  * mail (2.3.0)
  * mime-types (1.16)
  * multi_json (1.0.1)
  * polyglot (0.3.1)
  * rack (1.3.0.beta)
  * rack-cache (1.0.1)
  * rack-mount (0.7.2)
  * rack-ssl (1.3.2)
  * rack-test (0.6.0)
  * rails (3.1.0.beta1 72a4893)
  * railties (3.1.0.beta1)
  * rake (0.8.7)
  * sass (3.1.1)
  * sprockets (2.0.0 ebd683e)
  * sqlite3 (1.3.3)
  * thor (0.14.6)
  * tilt (1.3)
  * treetop (1.4.9)
  * tzinfo (0.3.27)
  * uglifier (0.5.1)
rake about
(in /home/rubys/tmp/work/depot)
About your application's environment
Ruby version              1.8.7 (x86_64-linux)
RubyGems version          1.6.2
Rack version              1.3
Rails version             3.1.0.beta1
Active Record version     3.1.0.beta1
Action Pack version       3.1.0.beta1
Active Resource version   3.1.0.beta1
Action Mailer version     3.1.0.beta1
Active Support version    3.1.0.beta1
Application root          /home/rubys/tmp/work/depot
Environment               development
git log -1
commit 72a489345280964b4e4350fa6104658cd4e8da84
Merge: 8f10ccd 92c1076
Author: Jon Leighton <j@jonathanleighton.com>
Date:   Sun May 8 23:43:34 2011 +0100

    Merge pull request #451 from baroquebobcat/fixing_last_for_issue_371