转自
Rails2.0新特性介绍( 下)
如果不是答应了一家杂志写一篇关于Rails2.0的文章,估计这篇贴就永远不会有下文了,不过虽然叫下,但其实是参考了2.0的ChangeLog重新写的,有一些是DHH在2.0 Preview那篇贴里也没有提到的,如果你还没看过或者不打算看那密密麻麻的ChangeLog,那么这篇贴应该还是有点意义,不过编辑说他们杂志的风格是尽量少用代码,因此我去掉了一些我认为本应该有的代码。
ActiveResource
Rails2.0最大的变化莫过于增加了ActiveResource,而去除了Action Web Services(有了REST,SOAP就显得很多余了),用实际行动为REST在与SOAP的竞争中投了一票。
你 可以将ActiveResource理解为远程的ActiveRecord,也就是说不同于 ActiveRecord 操作存储在本地数据库中的对象,ActiveResource 操作的是存储于远端服务器上的对象,我们假设Person是一个ActiveResource类:
Person = ActiveResource::Struct.new do |person|
person.uri = "http://api.example.com/people"
end
Person.find(1).name #=> "Ryan"
那 么上面这句话将向http://api.example.com/people/1发送了一个GET请求,并通过得到的响应构建了一个本地Person对 象,你可以像操作其它对象一样来操作这个ActiveResource对象,只不过你对这个对象的CRUD操作都被转化为了相应的HTTP请求,交由远端 的服务器来处理,并且这一转换是完全完全遵照REST规范的:
find(id)将被转化为针对http://api.example.com/people/id.xml的GET请求
新建对象的save操作将执行 POST http://api.example.com/people
已有对象的save则执行 PUT http://api.example.com/people/id.xml
destroy则将执行 DELETE http://api.example.com/people/id.xml
list 则执行 GET http://api.example.com/people
当然,如果确实需要SOAP,你也可以以gem方式继续使用Action Web Services。
Debugger
Rails2.0的另一个重大变化就是Debugger归来,Rails 1.x中的debugger受到ruby的一个bugfix的影响,已经停摆许久,不过这次借助强大的rdebug,重新归来的Rails debugger已经不再仅仅只是一个简单的IRB,而变成了一个真正意义上的功能齐全的调试器,支持单步调试,断点设置等等。并且也不再需要启动 script/breakpoint,只需要在启动script/server时增加debugger或-u参数,并在你需要进行调试的 controller中加入一行debugger即可:
class PostsController < ApplicationController
debugger
...
end
这样当执行到这个controller的代码时,启动server的终端窗口将自动进入debugger模式,然后你就可以执行rdebug的调试命令了,如图:
路由
另外Rails2.0的路由模块也发生了很大的变化,新的map.resource去除掉了1.2.x URL中的’;',新的URL映射如下:
GET /posts, PostsController#index
GET /posts/1, PostsController#show
GET /posts/1/new, PostsController#new
POST /posts, PostsController#create
GET /posts/1/edit, PostsController#edit
PUT /posts/1, PostsController#update
DELETE /posts/1, PostsController#destroy
同时,map resource还增加了namespace支持:
map.namespace(:admin) do |admin|
admin.resources :posts, has_many :tags
end
上面的代码将分别为路由helper和URL添加一个admin前缀:
admin_posts_url 对应 /admin/posts
new_admin_post_url 对应 /admin/posts/1/new
admin_post_tags_url 则对应 /admin/posts/1/tags
同时Rails2.0还对资源嵌套做了相应改进,controller名称默认为复数,也就是说对于像map.resources :people, :has_one => :avatar这样的路由,如果不存在AvatarController,那么所有请求都将被路由到AvatarsController,如果你还有另外一条路由map.resources :avatars,那么他们就可以使用同一个controller。
同时你可以直接使用model来指定URL,redirect_to(post),link_to(person.name, post),form_for(post)就相当于redirect_to(post_path),link_to(post.title, post_path),form_for(post, :url => post_path)
模板
Rails2.0中另外一个重大改变就是增加了多渲染引擎支持,在1.x中,.rhtml文件对应HTML请求,由ERB引擎解析,rxml对应XML请 求。而Rails2.0将模板的命名分成了3个部分:action.format.renderer,在action确定后,它首先根据HTTP请求的 content_type选择合适的format,然后根据模板后缀的renderer调用合适的渲染引擎,比如:
show.erb: 所有格式都使用此模板,使用ERB进行解析
index.atom.builder:针对application/atom+xml格式,使用Builder引擎,相当于1.x中的rxml
edit.iphone.haml:针对自定义的Mime::IPHONE格式,使用HAML模板引擎(需要自己安装)渲染。
Rails2.0鼓励开发者定义自己的MIME类型,所有新生成的应用的config目录下都将新增一个initializers/mime_types.rb的文件,你可以通过这个文件定义你自己的Mime类型,比如上例中的IPHONE:
# should go in config/initializers/mime_types.rb
Mime.register_alias "text/html", :iphone
我们可以通过检查请求来源,来决定是否返回IPHONE格式的响应:
if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :iphone
end
然后就可以在action中调用format.iphone来为iPhone和iPod用户返回IPHONE格式的数据了。
Migration
Migration现在变得更性感了,你不用再一遍遍的重复t.column
xx,
xx了,Rails2.0让你可以使用t.string :column_name建立新table。
同时,你也可以直接通过model/scaffold generator来自动生成migration文件,新的model/scaffold generator支持通过key:value pairs来为你自动生成migration文件,因此只需执行:
script/generate model post user_id:integer title:string content:text
rake db:migrate
一个包含user_id,title,content字段的posts表就已经躺在你的数据库里了。
Rails2.0 的migration generator也做了改进,它变得更智能了,比如它会根据你起的文件名AddSomeStuffToCustomers,猜出你想要向 customers表中添加一些字段,从而根据后面的key:value pairs自动为你生成migration文件。
其它
1. 新的Rake Tasks
Rails2.0新增了许多很实用的rake tasks:
rake routes,打印当前路由列表
rake db:drop, rake db:drop:all, 删除当前环境或config/database.yml中的所有数据库
rake db:create, rake db:create:all,创建当前环境数据库或或config/database.yml中的所有数据库
rake db:version,显示当前环境数据库的schema版本号
rake db:collation, db:charset,显示数据库的collation和charset
rake db:reset, 删除并重新创建当前环境的数据库
2. HTTP Basic认证
Rails2.0新增了一个模块用于处理HTTP认证,新的模块使用相当简单,你可以通过传递给authenticate_or_request_with_http_basic方法的Block来决定是否允许用户访问当前的action。
3. 性能优化
Rails2.0再性能方面还是做了不少改进的:
Rails2.0通过合并JS和CSS文件对页面的加载速度进行了优化,再产品模式下,所有的JS和CSS文件都将被合并为一个all.js和all.css文件,但是再开发模式下,则不过变化。
同 时,针对某些浏览器不愿意在同一时间发送太多请求到同一个域,Rails2.0提供了一个很简单的方法来欺骗浏览器,你只需要设置 ActionController::Base.asset_host = “assets%d.example.com”,Rails就会自动将你的链接(比如image)分散到从asset1到asset4的4个域中,从而提 高浏览器的并发。
另外一个值得称道的性能改进就是增加了Query Cache,虽然目前还有局限(比如不支持:include等等),但这毕竟是个好的开始。
同时 fixture的性能也得到了增强,比1.x提高了50-100%。
4. 更简单的异常处理
尽管Rails已经对大多数常见异常在action之上进行了处理,并且你也可以使用 rescue_action_in_public来覆盖通用的处理,但rescue_action_in_public要求你必须有一个case语句,并 且必须调用super,Rails2.0提供了一个新的 rescue_from方法,使用它,你可以更简单的对异常进行处理:
rescue_from User::NotAuthorized, :with => :deny_access
一旦出现异常,deny_access将被调用,但是Rails对于这个自定义的方法没有任何限制。
5. 安全
安全一直都是Rails的重中之重,Rails2.0在安全方面当然也做了大量改进:
首先,通过在form中增加特殊字段来防止CRSF攻击,这一功能在新应用中默认是开启的
同时,Rails2.0对XSS攻击的防范也得到增强,TextHelper#sanitize由黑名单改为了白名单实现
Rails2.0还新增了对HTTP only cookies的支持(尽管现在并非所有浏览器都支持这一特性,但提前做好准备总没什么坏处)
6. Atom协议支持
Rails2.0新增了一个AtomFeedHelper用于生成Atom标准的Feed.
7. 插件
除了将一些原本内置的特性改为插件(比如acts_as_list等)之外,Rails2.0对插件的控制更为灵活了,你可以通过config.plugins来控制加载那些插件以及以什么顺序来加载。
8. 商业数据库支持
Rails2.0 中,商业数据库的适配器被移出了Rails核心,只剩下MySQL, SQLite 和 PostgreSQL,如果你使用的不是这三种开源数据库,那么你需要自己通过gem来安装这些商业数据库的适配器,它们的命名遵照 activerecord-XYZ-adapter,比如activerecord-oracle-adapter。
9. 启动设置
修改environment.rb是不是常常让你头大,或者仅仅只是看着日益庞大的environment.rb 不爽?Rails2.0提供了一个config/initializer目录,所有放置于这个目录下的.rb文件都会在Rails启动成功后得到顺序执 行,因此现在你可以将你的启动脚本分成若干分,并给它们起个名字了。
好了,Rails2.0能够数得出来的大的改变就这些了,如果还不满足,可以查看官方的ChangeLog,你可以找到从1.2.3到2.0的每一个细小变化,迫不及待想要试一试?
svn co http://dev.rubyonrails.org/svn/rails/tags/rel_2-0-0_RC1/ vendor/rails
不过根据Rails官方的推荐,最好先升级你的Rails gem到1.2.5,解决掉所有的deprecation warnings,然后再升级到2.0,祝你好运!
参考:
http://blog.viget.com/whats-coming-in-rails-20/
http://weblog.rubyonrails.org/2007/9/30/rails-2-0-0-preview-release
http://ryandaigle.com/articles/2006/06/30/whats-new-in-edge-rails-activeresource-is-here
作者: admin