我们来看下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]}" }
|
路由约束: 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
相关推荐
综上所述,从Rails 2到Rails 3的过渡不仅仅是版本号的简单递增,而是对整个框架的一次全面升级。Rails 3在脚本命令的调用、配置文件的结构以及路由定义的语法上都做了大量的优化,旨在提供更高效、更直观的开发体验...
从给定的文件信息来看,我们正在探讨的是一本关于Ruby on Rails的书籍,书名为《Simply Rails2》,作者是Patrick Lenz。本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是...
### 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.1的核心概念和技术,还涵盖了从开发到部署的全过程,是Rails开发者不可或缺的参考书籍。通过阅读这本书,开发者可以深入理解Rails的工作原理,提升开发技能,并学会构建高效...
Rails3还支持安装插件,可以通过以下命令将插件添加到项目中: ```bash rails plugin install https://..../..git ``` 插件会被安装到`vendor/plugins`目录下,提供额外的功能或扩展。 以上就是Rails3的一些常用...
本书主要针对的是希望学习Ruby on Rails框架的读者,特别是那些想要从零开始掌握这项技术的新手。 #### 二、作者介绍与背景 - **作者**: xdite,一位经验丰富的开发者,专注于Ruby on Rails框架。 - **作品**: ...
为了确保读者能够通过实践加深理解,书中还安排了一系列练习作业,从最基础的“Hello World”开始,逐步过渡到更复杂的概念,如Rails的Routing(路由)机制。路由机制是Web应用中一个非常核心的概念,它定义了不同的...
《Ruby on Rails 3 Tutorial》是一本专门为初学者设计的指南,旨在帮助读者快速掌握Ruby on Rails这一强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby语言的一个开源框架,它采用MVC(Model-View-...
Rails的路由系统将URL映射到控制器的行动上,如`/sign_up`可能对应`users#new`,用于创建新用户。`config/routes.rb`文件定义了所有路由规则,包括资源路由、命名路由和自定义路由。 6. **视图模板**: 视图使用...
### CentOS环境下Rails 3开发环境搭建详解 #### 一、准备工作与环境配置 在开始部署Rails 3开发环境之前,我们需要确保系统上已经安装了一些基本的软件包和工具。这一步骤对于后续的Ruby和Rails安装至关重要。 ##...
使用Edge Rails的插件,如CRUD Generator 2,可以让你提前体验并利用到Rails的前沿技术。 **2. CRUD Generator 2的核心功能** CRUD Generator 2的核心是自动生成模型、控制器、视图以及相关的数据库迁移文件。它能...
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....
2. **Active Record**:这是Rails中的ORM(对象关系映射)库,它允许开发者用Ruby代码操作数据库,无需编写SQL语句。 3. **Action Controller**:负责处理HTTP请求并调用模型来执行业务逻辑,然后将结果传递给视图...
Rails 3.1 和 Cucumber-Rails 1.2.0 是两个在Web开发领域非常重要的工具,尤其对于Ruby on Rails框架的测试和自动化流程。本文将深入探讨这两个组件,以及它们如何协同工作来增强软件开发的效率和质量。 首先,...
Ruby on Rails 安装指南 Ruby on Rails 安装指南是指安装 Ruby 1.8.6 和 Rails 2.0.2 的详细步骤。首先,需要下载 Ruby One-Click Installer ...同时,也可以学习到 Ruby、Rails 和 Mongrel 的基本概念和使用方法。
Ruby+on+Rails+3+Tutorial.pdf 应用Rails进行敏捷Web开发第4版.pdf (Agile Web Development with Rails) Rails.Recipes.Rails.3.Edition.pdf
4. **Routes**:Rails的路由系统负责将HTTP请求映射到相应的控制器动作。通过配置routes.rb文件,开发者可以定义资源、命名路由等,使URL管理更加灵活。 5. **Gemfile与Bundler**:Rails项目通常使用Gemfile来管理...
你可以从其官方网站下载最新版本的安装包。安装过程中,遵循提示进行,确保选择自定义安装并勾选Rails相关的插件,以便在Aptana中获得对Rails的全面支持。 安装完成后,打开Aptana Studio,创建一个新的Rails项目。...