我们来看下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
相关推荐
1基于蓝牙的项目开发--蓝牙温度监测器.docx
AppDynamics:性能瓶颈识别与优化
xtrabackup银河麒麟v10rpm安装包
2024年全球产品经理大会(脱敏)PPT合集,共34份。 1、AI 原生产品设计的 7 个反共识 2、AI 时代的策略产品与内容社区推荐实践 3、AI时代的用户界面设计 4、AI智能陪练:大模型赋能销售成长 5、AI浪潮中的应用主义者 6、AI驱动下的B端产品的思考与创新 7、AI驱动业务增长的探索与实践 8、Al Native 生产力工具的发展、价值与商业落地 9、B端产品设计避坑指南 10、GenAl驱动的xGen电商AI平台产品实践与思考 11、Kwaipilot 在快手的落地实践 12、OPPO AI的探索新交互到新生态 13、RPA + AI打造大模型驱动的领先数字员工 14、产品AI化重塑的思考与实践 15、产品分析:通过关键指标助力团队与企业成功 16、从RPA到Al Agent,高价值、可落地的智能助手 17、从流量运营到AI驱动的机器增长 18、做穿越时代的产品 19、创造好工具,创造世界一流产品力 20、医疗健康场景的大模型产品探索 21、即时零售柔性供应链体系建设与AIGC在零售数字化的探索 22、向量数据库的出海实践与未来展望 23、大模型在B端落地思考实践
基于物联网技术的停车场智能管理系统设计用户有单独APP
Adobe XD:AdobeXD高级技巧与最佳实践.docx
ARKit(iOS的增强现实):ARKit的多人AR场景实现
1python自动化脚本.docx
河北省、市、区县及街镇可编辑SVG图
金融工程之量化交易算法:均值回归:时间序列分析与预测.docx
技术资料分享ADV7123非常好的技术资料.zip
Sawmill_cn.ppt
使用LabVIEW输入数字n,然后计算n的阶乘
1无人值守灌溉系统--stm.docx
金融工程之量化交易算法:动量交易:金融数据获取与处理.docx
基于SSM的毕业设计源码
头像图片调试使用用来调试
GITS_sawmill8.5.8.1_x64_linux-ubuntu11.tar.gz
Newspaper 是一个专为新闻、杂志和内容丰富网站设计的 WordPress 主题。它非常适合博客、在线出版和内容展示,具备多种强大功能。以下是 Newspaper 的主要特点: 响应式设计:确保网站在各种设备上(手机、平板、桌面)都能良好显示,优化用户体验。 丰富的预建模板:提供多个专业设计的预建布局和页面模板,用户可以快速导入并根据需求进行修改。 强大的页面构建器:内置的 TagDiv Composer 允许用户通过拖放功能轻松创建和自定义页面,无需编写代码。 SEO 优化:主题经过优化,有助于提升网站在搜索引擎中的排名,增加流量。 多种内容展示选项:提供多种文章格式和布局选项,如网格、列表、视频和画廊,方便展示不同类型的内容。 社交媒体集成:支持社交媒体分享功能,帮助用户轻松与观众互动并提高网站的曝光度。 实时自定义:支持实时预览功能,用户可以在更改设置时即时查看效果。 持续更新和支持:定期更新主题,确保用户获得最新功能和安全性,同时提供专业的技术支持。
国内市场:功能化脂质市场现状研究分析与发展前景预测报告(2024版).docx