• 简单开始
    下载并且安装Ruby 1.8.4;
    RubyGems;
    通过命令行安装所有的Rails和其依赖:
    gem install rails --include-dependencies
    在用户工作目录运行命令行,即创建第一个rails的模板:
    rails depot
    cd depot
    ruby script/server
    在浏览器打开http://localhost:3000即可发现第一个rails的web应用已经开始run起来了。

    然后我参考书籍《Agile Web Development with Rails》2nd Edition的第一个例子一步一步的动手写了第一个ROR程序。(具体的过程不详细记录了.)
    从数据库准备、数据库的配置、创建表、migrate、创建controller和maintenance、add missing column、添加validation功能、使用scaffold、定制html、装填unit test数据。整个例子的思路比较清晰,从数据库、数据访问、业务、controller、展示;给我留下深刻的影响的是:自动生成功能、内嵌web server、支持数据库配置,支持应用的模板、支持mvc模板等,所以让人似乎感觉到一些DSL的色彩。

    做一个复杂一些的例子
    数据库准备
    支持数据库Mysql,从http://dev.mysql.com/downloads/mysql/5.0.html#downloads下载数据库Mysql安装,并且下载Mysql Administrator作为数据库管理工具。
    创建Schema为:depot_dev
    在文件./config/database.yml中对数据库进行配置:
    development:
      adapter: mysql
      database: depot_dev
      username: depot
      password: depot
      host: localhost
    测试配置:rake db:migrate
    如果配置不正确在控制台会出现错误的日志。
    创建Products的Model和Table如下:
    D:\IDE\rails-exampe\depot>ruby script/generate model product
          exists  app/models/
          exists  test/unit/
          exists  test/fixtures/
          create  app/models/product.rb
          create  test/unit/product_test.rb
          create  test/fixtures/products.yml
          create  db/migrate
          create  db/migrate/001_create_products.rb
    在./db/migrate/001_create_products.rb用类似DDL的形式表达表的结构:
    class CreateProducts < ActiveRecord::Migration
      def self.up
        create_table :products do |t|
          t.column :title,       :string
          t.column :description, :text
          t.column :image_url,   :string
        end
      end

      def self.down
        drop_table :products
      end
    end
    Okey,那就Migrate吧:
    D:\IDE\rails-exampe\depot>rake db:migrate
    D:0:Warning: require_gem is obsolete.  Use gem instead.
    (in D:/IDE/rails-exampe/depot)
    == CreateProducts: migrating ==================================================
    -- create_table(:products)
       -> 0.0780s
    == CreateProducts: migrated (0.0780s) =========================================
    数据库一切搞定,下一步开始应用层了,首先创建Controller:
    D:\IDE\rails-exampe\depot>ruby script/generate controller admin
          exists  app/controllers/
          exists  app/helpers/
          create  app/views/admin
          exists  test/functional/
          create  app/controllers/admin_controller.rb
          create  test/functional/admin_controller_test.rb
          create  app/helpers/admin_helper.rb
    创建Maintenance应用:
    编辑app/controller/admin_controller.rb
    class AdminController < ApplicationController
      scaffold :product
    end
    启动ruby script/server,通过浏览器就可以浏览这个Rail scaffolds的应用了。
    迭代2:Add a missing column
    D:\IDE\rails-exampe\depot>ruby script/generate migration add_price
          exists  db/migrate
          create  db/migrate/002_add_price.rb
    编辑db/migrate/002_add_price.rb
    class AddPrice < 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
    D:\IDE\rails-exampe\depot>rake db:migrate
    D:0:Warning: require_gem is obsolete.  Use gem instead.
    (in D:/IDE/rails-exampe/depot)
    == AddPrice: migrating ========================================================
    -- add_column(:products, :price, :decimal, {:default=>0, :precision=>8, :scale=>
    2})
       -> 0.2650s
    == AddPrice: migrated (0.2650s) ===============================================
    一切Okey,第二个迭代也已经结束:)
    第三个迭代:Validate!
    编辑app/model/product.rb文件:
    class Product < ActiveRecord::Base
      validates_presence_of :title, :description, :image_url
      validates_numericality_of :price
      validates_uniqueness_of :title
      validates_format_of :image_url,
                          :with    => %r{\.(gif|jpg|png)$}i,
                          :message => "must be a URL for a GIF, JPG, or PNG image"

      protected
      def validate
        errors.add(:price, "should be at least 0.01") if price.nil? ||  price < 0.01
      end
    end
    第四个迭代:Prettier Listings
    创建静态的scaffold如下:
    D:\IDE\rails-exampe\depot>ruby script/generate scaffold product admin
          exists  app/controllers/
          exists  app/helpers/
          exists  app/views/admin
          exists  app/views/layouts/
          exists  test/functional/
      dependency  model
          exists    app/models/
          exists    test/unit/
          exists    test/fixtures/
            skip    app/models/product.rb
       identical    test/unit/product_test.rb
       identical    test/fixtures/products.yml
          create  app/views/admin/_form.rhtml
          create  app/views/admin/list.rhtml
          create  app/views/admin/show.rhtml
          create  app/views/admin/new.rhtml
          create  app/views/admin/edit.rhtml
    overwrite app/controllers/admin_controller.rb? [Ynaqd] y
           force  app/controllers/admin_controller.rb
    overwrite test/functional/admin_controller_test.rb? [Ynaqd] y
           force  test/functional/admin_controller_test.rb
       identical  app/helpers/admin_helper.rb
    overwrite app/views/layouts/admin.rhtml? [Ynaqd] y
           force  app/views/layouts/admin.rhtml
          create  public/stylesheets/scaffold.css
    定制list.rhtml:
    <div id="product-list">
      <h1>Product Listing</h1>

      <table cellpadding="5" cellspacing="0">
      <% for product in @products %>
        <tr valign="top" class="<%= cycle('list-line-odd', 'list-line-even') %>">

          <td>
            <img class="list-image" src="<%= product.image_url %>"/>
          </td>

          <td width="60%">
            <span class="list-title"><%= h(product.title) %></span><br />
            <%= h(truncate(product.description, 80)) %>
          </td>

          <td class="list-actions">
            <%= link_to 'Show', :action => 'show', :id => product %><br/>
            <%= link_to 'Edit', :action => 'edit', :id => product %><br/>
            <%= link_to 'Destroy', { :action  => 'destroy', :id => product },
                                     :confirm => "Are you sure?",
                                     :method  => :post %>
          </td>
        </tr>
      <% end %>
      </table>
    </div>

    <%=  if @product_pages.current.previous
           link_to("Previous page", { :page => @product_pages.current.previous })
         end
    %>
    <%= if @product_pages.current.next
          link_to("Next page", { :page => @product_pages.current.next })
        end
    %>

    <br />

    <%= link_to 'New product', :action => 'new' %>
    增加测试数据:
    D:\IDE\rails-exampe\depot>ruby script/generate migration add_test_data
          exists  db/migrate
          create  db/migrate/003_add_test_data.rb
    编辑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
    安装测试数据:
    D:\IDE\rails-exampe\depot>rake db:migrate
    D:0:Warning: require_gem is obsolete.  Use gem instead.
    (in D:/IDE/rails-exampe/depot)
    == AddTestData: migrating =====================================================
    == AddTestData: migrated (0.2030s) ============================================
    编辑Layouts:app/views/layouts/admin.rhtml
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
    <head>
      <title>Admin: <%= controller.action_name %></title>
      <%= stylesheet_link_tag 'scaffold', 'depot' %>
    </head>
    <body>
    <p style="color: green"><%= flash[:notice] %></p>
    <%= yield :layout %>
    </body>
    </html>
    编辑:app/views/admin/list.rhtml
    <div id="product-list">
      <h1>Product Listing</h1>

      <table cellpadding="5" cellspacing="0">
      <% for product in @products %>
        <tr valign="top" class="<%= cycle('list-line-odd', 'list-line-even') %>">

          <td>
            <img class="list-image" src="<%= product.image_url %>"/>
          </td>

          <td width="60%">
            <span class="list-title"><%= h(product.title) %></span><br />
            <%= h(truncate(product.description, 80)) %>
          </td>

          <td class="list-actions">
            <%= link_to 'Show', :action => 'show', :id => product %><br/>
            <%= link_to 'Edit', :action => 'edit', :id => product %><br/>
            <%= link_to 'Destroy', { :action  => 'destroy', :id => product },
                                     :confirm => "Are you sure?",
                                     :method  => :post %>
          </td>
        </tr>
      <% end %>
      </table>
    </div>

    <%=  if @product_pages.current.previous
           link_to("Previous page", { :page => @product_pages.current.previous })
         end
    %>
    <%= if @product_pages.current.next
          link_to("Next page", { :page => @product_pages.current.next })
        end
    %>

    <br />

    <%= link_to 'New product', :action => 'new' %>
    http://www.rubyonrails.org/down
    书籍《Agile Web Development with Rails》2nd Edition

    另,JSR 315: Java Servlet 3.0 Specification under review at JCP:http://jcp.org/en/jsr/detail?id=315可以看到Servlet 3.0的规范中要涉及到的一些东西。