`

从Rails2到Rails3

阅读更多

我们来看下rails3相比rails2, 进步在哪里, 优势又在什么地方.

 

1. 脚本命令

旧的命令                                      新的用法

script/generate                          rails g

script/console                            rails c

script/server                              rails s

script/dbconsole                        rails db

 

2. 配置文件

rails2: config/environment.rb

1
2
3
4
5
6
7
8
Rails::Initializer.run do |config|  
    config.load_paths += %W( #{RAILS_ROOT}/extras )  
    config.gem "bj" 
    config.gem "sqlite3-ruby", :lib => "sqlite3" 
    config.gem "aws-s3", :lib => "aws/s3" 
   config.plugins = [ :exception_notification ]  
   config.time_zone = 'UTC' 
end

rails3:config/application.rb

1
2
3
4
5
6
7
module APP_NAME  
    class Application < Rails::Application  
        config.load_paths += %W( #{RAILS_ROOT}/extras )  
        config.plugins = [ :exception_notification ]  
        config.time_zone = 'UTC' 
    end 
end  

这样就变成了一种架构式的应用, 我们可以根据方便的对config进行操作

 

3. 路由

在rails3中, 已经的路由可以继续工作, 而新的路由方式更加简洁.

在 rails2 中:

1
2
3
map.resources :posts do |post|  
    post.resources :comments 
end 

而在rails3中, 表达更为形象:
 

1
2
3
resources :posts do 
    resources :comments 
end

对于一些复杂的路由, rails2:

1
2
3
post.resources :comments,  
                 :member => { :preview => :post },  
                :collection => { :archived => :get

 在rails3中可以这样表达:

1
2
3
4
5
6
7
8
resources :comments do 
    member do 
        post :preview 
    end 
    collection do 
        get :archived 
    end 
end 

不够简洁? 我们还可以这样做:

1
2
3
4
resources :comments do 
    post :preview, :on => :member 
    get :archived, :on => :collection 
end 

对于基本路由, rails2:

1
map.connect 'login', :controller => 'session', :action => 'new'

 那么在rails3中:

1
match 'login' => 'session#new'

对于具名路由, rails2:

1
map.login 'login', :controller => 'session', :action => 'new' 

在rails3中:

1
match 'login' => 'session#new', :as => :login 

对于程序根路由, rails2:

1
map.root :controller => 'users', :action => 'index' 

rails3:

1
root :to => 'users#index' 

对于遗留路由, rails2:

1
2
map.connect ':controller/:action/:id' 
map.connect ':controller/:action/:id.:format' 

 那么在rails3中写法更优雅:

1
match ':controller(/:action(/:id(.:format)))'

对于路由参数, rals2:

1
map.connect '/articles/:year/:month/:day', :controller => 'posts', :action => 'index' 

rails3:
 

1
match '/articles/:year/:month/:day' => "posts#index"

那么对于存档请求, 比如rails2:

1
2
3
map.connect '/articles/:year/:month/:day', :controller => 'posts', :action => 'index' 
map.connect '/articles/:year/:month', :controller => 'posts', :action => 'index' 
map.connect '/articles/:year', :controller => 'posts', :action => 'index' 

在rails3中:
 

1
match '/articles(/:year(/:month(/:day)))' => "posts#index"

指定请求方式, rails2:

1
2
map.connect '/articles/:year', :controller => 'posts', :action => 'index',  
:conditions => {:method => :get}

在rails3中:
 

1
2
3
match '/articles/:year' => "posts#index", :via => :get 
#或者更简单的:  
get '/articles/:year' => "posts#index"

对于跳转, rails3:

1
2
3
match 'signin', :to => redirect("/login")  
match 'users/:name', :to => redirect {|params| "/#{params[:name]}" }  
match 'google' => redirect('http://www.google.com/')

路由约束: rails2中实际上使用了 :requirements 符号

1
2
map.connect '/:year', :controller => 'posts', :action => 'index',  
                                    :requirements => { :year => /\d{4}/ }

在rails3中:
 

1
match '/:year' => "posts#index", :constraints => {:year => /\d{4}/}
1
2
3
4
5
6
7
8
:constraints => { :user_agent => /iphone/ }  
:constraints => { :ip => /192\.168\.1\.\d{1,3}/ }  
constraints(:host => /localhost/) do 
    resources :posts 
end 
constraints IpRestrictor do 
   get 'admin/accounts' => "queenbee#accounts" 
end 

对于Rack应用, rails3:

1
2
3
get 'hello' => proc { |env| [200, {}, "Hello Rack"] }  
get 'rack_endpoint' => PostsController.action(:index)  
get 'rack_app' => CustomRackApp

4. Bundler与ActionController

一个典型的rails应用, 我们一般需要在 environment.rb 指定你的 gems:

1
2
config.gem "haml" 
config.gem "chronic", :version => '0.2.3' 

然后我们运行 $ rake gems:install, 该命令会取得并下载然后安装编译这些gems到你的系统RubyGems目录中.

之后我们运行 $ rake gems:unpack:dependencise, 把这些gem打包到你应用程序的vendor/gems目录中去.

 

这样做产生的问题:

1. 它直接绑定到Rails中

2. 没有从本质上解决依赖问题

3. 运行时容易发生冲突

 

在rails3中, 使用了 bundle 命令:

直接在你的 gemfile 中指定你的 gem

1
2
gem "haml" 
gem "chronic", '0.2.3'

然后运行 $ bundle, 该命令会会取得并下载然后安装编译这些gems

然后运行 $ bundle package 把gem源移到/vendor/cache中去.

这样rails应用中的gem与系统中的gem就不会相冲突.

一般的控制器语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class UsersController < ApplicationController  
    def index  
       @users = User.all  
        respond_to do |format|  
            format.html  
            format.xml { render :xml => @users.to_xml }   
        end 
    end 
  
    def show  
       @user = User.find(params[:id])  
        respond_to do |format|  
            format.html # show.html.erb  
            format.xml { render :xml => @user }  
        end 
    end 
   
.... 

改进的语法:

1
2
3
4
5
6
7
8
9
10
11
class UsersController < ApplicationController  
    respond_to :html, :xml, :json 
    def index  
        @users = User.all  
       respond_with(@users)  
    end 
   def show  
       @user = User.find(params[:id])  
        respond_with(@user)  
    end 
....

5. ActionMailer

rails2:  $ script/generate mailer UserMailer welcome forgot_password

这将创建 app/models/user_mailer.rb

那么在rails3中: $ rails g mailer UserMailer welcome forgot_password

这将创建 app/mailers/user_mailer.rb

 

在实现部分, rails2:

1
2
3
4
5
6
def welcome(user, subdomain)  
    subject 'Welcome to TestApp' 
   recipients user.email  
    from 'admin@testapp.com' 
    body :user => user, :subdomain => subdomain  
end 
1
UserMailer.deliver_welcome(user, subdomain)

在rails3中:

1
2
3
4
5
6
7
def welcome(user, subdomain)  
    @user = user  
    @subdomain = subdomain  
    mail(:from => "admin@testapp.com",  
            :to => user.email,  
           :subject => "Welcome to TestApp")  
end 
1
UserMailer.welcome(user, subdomain).deliver 

相比rails2, 我们在rails3下实现一个mail要简单的多:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class UserMailer < ActionMailer::Base  
    default :from => "admin@testapp.com",  
                :reply_to => "noreply@testapp.com",  
               "X-Time-Code" => Time.now.to_i.to_s  
    def welcome(user, subdomain)  
        @user = user  
        @subdomain = subdomain  
        attachments['test.pdf'] = File.read("#{Rails.root}/public/test.pdf")  
        mail(:to => @user.email, :subject => "Welcome to TestApp") do |format|  
            format.html { render 'other_html_welcome' }  
            format.text { render 'other_text_welcome' }  
        end 
    end 
end  

6. ActiveRelation 以及 ActiveModel

在rails2中, 我们经常使用下面的方法来进行查询:

1
@posts = Post.find(:all, :conditions => {:published => true}) 

该方式将立即查询数据库然后返回Posts数组

 

而在rails3中:

1
@posts = Post.where(:published => true)

该方法不会查询数据库, 仅仅返回一个 ActiveRecord::Relation 对象, 然后:
 

1
2
3
4
5
6
7
@posts = Post.where(:published => true)  
if params[:order]  
   @posts = @posts.order(params[:order])  
end 
@posts.each do |p|  
    ...                 #在这里进行查询, 实现延迟加载  
end 

对于命名范围, 在rails2中:

1
2
3
4
5
class Post < ActiveRecord::Base  
    default_scope :order => 'title' 
    named_scope :published, :conditions => {:published => true}  
    named_scope :unpublished, :conditions => {:published => false}  
end 


而在rails3中:

1
2
3
4
5
class Post < ActiveRecord::Base  
    default_scope order('title')  
    scope :published, where(:published => true)  
    scope :unpublished, where(:published => false)  
end 

对于查找方法, rails2:
 

1
Post.find(:all, :conditions => {:author => "Joe"}, :includes => :comments, :order => "title", :limit => 10


在rails3:

1
 
1
2
Post.find(:all, :conditions => {:author => "Joe"}, :includes => :comments,
:order => "title", :limit => 10

7. 跨站点脚本(XSS)

在rails2中, 一般我们输入一段文本的时候, 我们往往会这样写: <%= h @post.body %>

那么在rails3中, <%= @post.body %> 默认输出的是一段safe html, 如果想输出XSS, 可以在前面加上 raw

3
1
分享到:
评论

相关推荐

    rails版本区别

    综上所述,从Rails 2到Rails 3的过渡不仅仅是版本号的简单递增,而是对整个框架的一次全面升级。Rails 3在脚本命令的调用、配置文件的结构以及路由定义的语法上都做了大量的优化,旨在提供更高效、更直观的开发体验...

    rails2-sample

    从给定的文件信息来看,我们正在探讨的是一本关于Ruby on Rails的书籍,书名为《Simply Rails2》,作者是Patrick Lenz。本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是...

    Flexible Rails: Flex3 on Rails2

    ### Flexible Rails: Flex3 on Rails2 #### 关于Flexible Rails 本书《Flexible Rails: Flex 3 on Rails 2》由Peter Armstrong撰写,旨在探讨如何结合使用Flex 3和Rails 2来开发高效的富互联网应用程序(Rich ...

    Rails 3 in Action

    《Rails 3 in Action》不仅覆盖了Rails 3.1的核心概念和技术,还涵盖了从开发到部署的全过程,是Rails开发者不可或缺的参考书籍。通过阅读这本书,开发者可以深入理解Rails的工作原理,提升开发技能,并学会构建高效...

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    - **升级**:当需要更新到Rails的最新版本时,可以使用`bundle update rails`命令来更新依赖。 - **回滚**:如果更新后出现问题,可以通过`git`命令或者手动修改`Gemfile`来回滚到之前的版本。 #### 六、添加第二个...

    Rails3常用命令行命令

    Rails3还支持安装插件,可以通过以下命令将插件添加到项目中: ```bash rails plugin install https://..../..git ``` 插件会被安装到`vendor/plugins`目录下,提供额外的功能或扩展。 以上就是Rails3的一些常用...

    Rails 101 入门电子书

    本书主要针对的是希望学习Ruby on Rails框架的读者,特别是那些想要从零开始掌握这项技术的新手。 #### 二、作者介绍与背景 - **作者**: xdite,一位经验丰富的开发者,专注于Ruby on Rails框架。 - **作品**: ...

    Rails101_by_rails4.0

    为了确保读者能够通过实践加深理解,书中还安排了一系列练习作业,从最基础的“Hello World”开始,逐步过渡到更复杂的概念,如Rails的Routing(路由)机制。路由机制是Web应用中一个非常核心的概念,它定义了不同的...

    ruby on rails 3 tutorial.pdf

    《Ruby on Rails 3 Tutorial》是一本专门为初学者设计的指南,旨在帮助读者快速掌握Ruby on Rails这一强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby语言的一个开源框架,它采用MVC(Model-View-...

    Rails项目源代码

    Rails的路由系统将URL映射到控制器的行动上,如`/sign_up`可能对应`users#new`,用于创建新用户。`config/routes.rb`文件定义了所有路由规则,包括资源路由、命名路由和自定义路由。 6. **视图模板**: 视图使用...

    centOS Rails3环境搭建

    ### CentOS环境下Rails 3开发环境搭建详解 #### 一、准备工作与环境配置 在开始部署Rails 3开发环境之前,我们需要确保系统上已经安装了一些基本的软件包和工具。这一步骤对于后续的Ruby和Rails安装至关重要。 ##...

    [Rails 常用插件简介]CRUD Generator 2

    使用Edge Rails的插件,如CRUD Generator 2,可以让你提前体验并利用到Rails的前沿技术。 **2. CRUD Generator 2的核心功能** CRUD Generator 2的核心是自动生成模型、控制器、视图以及相关的数据库迁移文件。它能...

    Rails.Angular.Postgres.and.Bootstrap.2nd.Edition

    Chapter 3. Secure the User Database with Postgres Constraints Chapter 4. Perform Fast Queries with Advanced Postgres Indexes Chapter 5. Create Clean Search Results with Bootstrap Components Chapter 6....

    Rails

    2. **Active Record**:这是Rails中的ORM(对象关系映射)库,它允许开发者用Ruby代码操作数据库,无需编写SQL语句。 3. **Action Controller**:负责处理HTTP请求并调用模型来执行业务逻辑,然后将结果传递给视图...

    关于rails 3.1 cucumber-rails 1.2.0

    Rails 3.1 和 Cucumber-Rails 1.2.0 是两个在Web开发领域非常重要的工具,尤其对于Ruby on Rails框架的测试和自动化流程。本文将深入探讨这两个组件,以及它们如何协同工作来增强软件开发的效率和质量。 首先,...

    Ruby on Rails安装指南(Ruby 1.8.6+Rails 2.0.2)

    Ruby on Rails 安装指南 Ruby on Rails 安装指南是指安装 Ruby 1.8.6 和 Rails 2.0.2 的详细步骤。首先,需要下载 Ruby One-Click Installer ...同时,也可以学习到 Ruby、Rails 和 Mongrel 的基本概念和使用方法。

    rails金典教材3本

    Ruby+on+Rails+3+Tutorial.pdf 应用Rails进行敏捷Web开发第4版.pdf (Agile Web Development with Rails) Rails.Recipes.Rails.3.Edition.pdf

    rails指南 中文版

    4. **Routes**:Rails的路由系统负责将HTTP请求映射到相应的控制器动作。通过配置routes.rb文件,开发者可以定义资源、命名路由等,使URL管理更加灵活。 5. **Gemfile与Bundler**:Rails项目通常使用Gemfile来管理...

Global site tag (gtag.js) - Google Analytics