`

从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
分享到:
评论

相关推荐

    rails2-sample

    rails2-sample good book

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    rails3教程

    Rails3教程系列 DRY(Dont Repeat Yourself) DRY(Dont Repeat Yourself) DRY(Dont Repeat Yourself) DRY(Dont Repeat Yourself) DRY(Dont Repeat Yourself) DRY(Dont Repeat Yourself) DRY(Dont Repeat Yourself) DRY...

    Rails 3 in Action

    Rails 3 in Action 2011年9月新鲜出炉,针对最新的Rails 3.1进行说明

    RVM_Ruby1.9.3_Rails3(2-Ruby on Rails3安装配置)

    Windows7_Cygwin_Git_RVM_Ruby1.9.3_Rails3_MongoD B_Nginx_Unicorn_Rspec_Guard_Spork(2-Ruby on Rails3 安装配置

    rails金典教材3本

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

    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.3.2离线安装rails 2.3.2离线安装

    rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails ...

    centOS Rails3环境搭建

    3 rails # gem install rails -v=2.3.11 4 passenger # gem install passenger passenger-install-apache2-module 安装完成后按照提示将下面的内容添加到etc/httpd/httpd.conf LoadModule pa

    Ruby on Rails Tutorial

    《Ruby on Rails Tutorial》中文版(原书第2版,涵盖 Rails 4) Ruby 是一门很美的计算机语言,其设计原则就是“让编程人员快乐”。David Heinemeier Hansson 就是看重了这一点,才在开发 Rails 框架时选择了 Ruby...

    [Rails] Crafting Rails Applications (英文版)

    This pioneering book is the first resource that deep dives into the new Rails 3 APIs and shows you how use them to write better web applications and make your day-to-day work with Rails more ...

    The Rails 3 Way(2nd)

    The Rails™ 3 Way is a comprehensive resource that digs into the new features in Rails 3 and perhaps more importantly, the rationale behind them. —Yehuda Katz, Rails Core The Bible for Ruby on ...

    Rails3常用命令行命令

    rails常用命令,例如新建rails项目,新建controller、model 等等

    The Rails3 Way, 2nd Edition

    The Rails™ 3 Way is the only comprehensive, authoritative guide to delivering production-quality code with Rails 3. Pioneering Rails expert Obie Fernandez and a team of leading experts illuminate ...

    Bootstrap for Rails (2015)

    Chapter 2: Introducing Bootstrap 3 25 What is Bootstrap? 26 Installing Bootstrap in a Rails project 27 Placing Bootstrap files in a Rails project 28 Bootstrap – the Sass way 33 Bootstrap through CDN ...

    rails3文档

    rails3的英文文档

    Rails项目源代码

    一个用Ruby on Rails搭建的图片分享的网站项目.完整源代码

    adminlte-rails, AdminLTE Rails gem 将AdminLTE主题与 Rails 资产管道集成.zip

    adminlte-rails, AdminLTE Rails gem 将AdminLTE主题与 Rails 资产管道集成 AdminLTE Rails gem AdminLTE 是后端的高级 Bootstrap 主题。英镑 AdminLTE Rails gem 与 Rails 资产管道集成了英镑AdminLTE主题。安装将...

    Rails之道,完整扫描版

    《Rails之道》按照Rails的各个子系统进行组织编排,分别介绍了Rails的环境、初始过程、配置和日志记录,Rails的分配器、控制器、页面生成和路由,REST、资源和Rails,ActiveRecord的基础、关联、验证和高级技巧,...

Global site tag (gtag.js) - Google Analytics