我们来看下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
相关推荐
rails2-sample good book
Ruby on Rails Guides v2 - Ruby on Rails 4.2.5
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 2011年9月新鲜出炉,针对最新的Rails 3.1进行说明
Windows7_Cygwin_Git_RVM_Ruby1.9.3_Rails3_MongoD B_Nginx_Unicorn_Rspec_Guard_Spork(2-Ruby on Rails3 安装配置
Ruby+on+Rails+3+Tutorial.pdf 应用Rails进行敏捷Web开发第4版.pdf (Agile Web Development with Rails) Rails.Recipes.Rails.3.Edition.pdf
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 ...
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》中文版(原书第2版,涵盖 Rails 4) Ruby 是一门很美的计算机语言,其设计原则就是“让编程人员快乐”。David Heinemeier Hansson 就是看重了这一点,才在开发 Rails 框架时选择了 Ruby...
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 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 ...
rails常用命令,例如新建rails项目,新建controller、model 等等
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 ...
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的英文文档
一个用Ruby on Rails搭建的图片分享的网站项目.完整源代码
adminlte-rails, AdminLTE Rails gem 将AdminLTE主题与 Rails 资产管道集成 AdminLTE Rails gem AdminLTE 是后端的高级 Bootstrap 主题。英镑 AdminLTE Rails gem 与 Rails 资产管道集成了英镑AdminLTE主题。安装将...
《Rails之道》按照Rails的各个子系统进行组织编排,分别介绍了Rails的环境、初始过程、配置和日志记录,Rails的分配器、控制器、页面生成和路由,REST、资源和Rails,ActiveRecord的基础、关联、验证和高级技巧,...