升级到 Rails 4,你的应用需要准备什么?

一个新的 Rails 版本即将发布了,随之带来了很多的修改、依赖和新特性。

让我们看一下,要使用 Rails 4,你需要为你的应用准备些什么。

Tom-Lin
Tom-Lin
翻译于 7个月前

0人顶

 翻译的不错哦!

升级的方式

要为 Rails 4 做好准备最简单的方法就是让你的应用运行在 Rails 3.2 上。如果你目前还不是使用 Rails 3.2,建议使用小版本方式升级,就是说从 3.0 升级到 3.1 ,然后再从 3.1 升级到 3.2

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

废弃 Deprecations

一些方法将在 Rails 4 中被完全删除,我们应该知道这些,并事先做好准备。

Rails 4 只支持 Ruby 1.9.3+

Rails 4 将只支持 Ruby 1.9.3 或者更新的版本,因此必须确保你的应用可在 Ruby 1.9.3 版本上运行。

如果你使用的是 Ruby 1.9.x,这样升级会更加直接。

如果你还在使用 Ruby 1.8.7,那需要做多点工作。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

现在大多数 gems 都可以运行在 Ruby 1.9 版本,或者也有了替代品。例如 rvm 或 rbenv 这样的工具可以帮助我们的应用程序运行在多个 Ruby 的版本。

在你的 Gemfil 中使用条件语句可以方便的处理不同环境下的不同 gems,直到你完全移植到 Ruby 1.9.x 上。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

例如:

1 gem 'ruby18-only-gem':platforms => :ruby_18
2 gem 'ruby19-only-gem':platforms => :ruby_19
3 #More on this can be seen in the Bundler manpages:
4 #http://gembundler.com/man/gemfile.5.html#PLATFORMS-platforms-

关于 1.8 和 1.9 之间的改变可看 Peter Cooper 写的这篇文章 the Ruby 1.9 walkthrough . 强烈推荐!

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

不再有 vendor/plugins

Rails 4 将删除 Rails::Plugins 类,所以将不会再加载 vender/plugins 目录下的任何代码。

大多数应用应该依赖于 gems 而不是插件。但如果你在 vender/plugins 中还有一些代码,你有两种选择:

  • 改用 gem 方式实现,多数插件已经有了 gem 版本,如果没有你可以在 Gemfile 中通过 :gitor:pathoptions 来引用插件
  • 移到 lib/your\_pluginand ,然后在 onconfig/initializers 初始化

这里是关于废弃插件的说明 commit

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

路由匹配

关于路由,匹配方法不再作为是 catch-all 选项,你可以指定需要响应什么 HTTP 方法,包括 GET/POST 之类的。

1 #Rails 3.2
2 match "/users/:id" => "users#show"
1 #Rails 4.0
2 match "/users/:id" => "users#show", via: :get
3 #or specify multiple verbs
4 match "/users" => "users#index", via: [:get:post]

另外一个更好兼容 Rails 3.2 的方法是显式的指定 HTTP 方法,是 GET 或者 POST,或者是其他的方法。这样你就可以兼容现在的版本和 Rails 4.0.

1 #Rails 3.2 and 4.0 compatible
2 get "/users/:id" => "users#show"
3 # multiple verbs
4 get "/users" => "users#index"
5 post "/users" => "users#index"

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

ActiveRecord

ActiveRecord 范围需要一个 Callable 对象。

在 Rails 4 中,所有 ActiveRecord 范围必须使用一个 callable 对象来定义:

1 #Rails 3.2
2 scope :recent, where(created_at: Time.now - 2.weeks)
1 #Rails 4
2 scope :recent, -> { where("created_at > ?"Time.now - 2.weeks).order("created_at desc") }
3 scope :active, -> { where(status: 'active') }

这个可避免一些关于日期和时间对象的微小 bug,无需动态的评估。

红薯
红薯
翻译于 7个月前

1人顶

 翻译的不错哦!

被移除的代码

在 Rails 4 中有很多代码会被删除,别担心,因为大多数被删除的代码还会作为独立的 gems 存在,这样有助于更平滑的迁移。

被删除的代码包括:

  • ActiveResource (这里有篇文章 blogpost 解释了这个改动)
  • ActiveRecord Observers and ActionController Sweepers
  • ActiveRecord::SessionStore
  • ActiveModel Mass Assignment Sanitizer
  • Action Caching
  • Page Caching
  • Hash-based and dynamic finders


红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

特别值得一提的注意事项:

Activerecord-deprecated-finders 是 Rails 4.0 中默认提供废弃功能的依赖包,但它也将在 4.1 版本中被删除。因此你需要密切关注所有的警告信息,并开始修复这些警告。

Rails 指南 提供一个很有用的解释,关于在大多数情况下如何修改动态查找器:

所有动态的方法除了 findby… 和 findby…! 外都已废弃,你可以使用如下的替代方法:

  • find_all_by_...改为 where(...).
  • find_last_by_...改为 where(...).last.
  • scoped_by_...改为 where(...).
  • find_or_initialize_by_...改为 where(...).first_or_initialize.
  • find_or_create_by_...改为 find_or_create_by(...) 或者 where(...).first_or_create.
  • find_or_create_by_...!改为 find_or_create_by!(...) 或者 where(...).first_or_create!.

所有的那些 gems 都可以帮你实现平滑的迁移。我的建议是:对一个完全的 Rails 4 环境,通过警告信息来帮你的代码适应于最新版本的语法。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

新特性

现在该是介绍最有趣的部分了!

Rails 4 增加了大量的新特性,好消息是这些新特性都可以在 Rails 3.2 中通过 gems 方式获取。同时 Rails 4 也提供了预览版不可方便进行升级测试。

下面我们来看看这些新特性。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

强参数 (gem)

在围绕着 mass-assignment保护 产生了不少争议之后,我们对各种不同的方法进行
探讨。

Rails 3.2 的做法是在模型中使用 attr_accessible 和 attr_protected 方法。

Rails 4 则需要从完全不同的角度来看,为模型分配参数的工作将由控制器负责。

01 #Rails 3.2
02 class User < ActiveRecord::Base
03   attr_protected :name:email
04 end
05 class UsersController < ApplicationController
06   def create
07     @user = User.new params[:user]
08     if @user.save
09       redirect_to @user
10     else
11       render :new
12     end
13   end
14 end
01 #Rails 4.0
02 class User < ActiveRecord::Base
03   include ActiveModel::ForbiddenAttributesProtection
04 end
05 class UsersController < ApplicationController
06   def create
07     @user = User.new params.require(:user).permit(:name:email)
08     if @user.save
09       redirect_to @user
10     else
11       render :new
12     end
13   end
14 end

也可以简化成类似的

01 #Rails 4
02 class UsersController < ApplicationController
03   def create
04     @user = User.new user_params
05     #  ...
06   end
07   private
08   def user_params
09     params.require(:user).permit(:name:email)
10   end
11 end
aiasfina
aiasfina
翻译于 7个月前

0人顶

 翻译的不错哦!

这种方法的好处是,我们可以在一个面向用户的方法里面过滤不同的参数,而不是在一个拥有管理权限的地方过滤。

还有一个好处,不同的方法可以允许不同组的属性。让控制器来控制模型应该接受什么是明智的选择。

在使用这个gem的时候还要记住一点,你需要添加一行代码到 config/application.rb:

1 config.active_record.whitelist_attributes = false
这个   gem   还提供了一个清晰的 README,非常值得一读。Railser的福气啊,想知道更多的话还有一个   Railscast 视频介绍。
刘劲
刘劲
翻译于 7个月前

0人顶

 翻译的不错哦!

Cache 摘要和和 Russian Doll Caching (gem)

在 Rails 4 中 action 和页面缓存被移除了,同时也引入了一种新的方式来存储缓存,那就是 基于键的失效期.

主思路就是增加 updated\_at 属性到缓存键,当记录更改时,缓存键也跟着更改,这样就可以获取新的数据。

这个方法导致了大量的缓存垃圾,因此更适合使用类似 memcached 同类的存储,因为当空间用完时会自动清除最老的数据。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

同时,对于视图而言,它生成文件的 MD5 checksum 并存做缓存的键,如果文件做任何改动,缓存的键也跟着更改,这样就可以重新加载文件内容。

1 #Rails 3.2
2 <% cache ['v1'@userdo %>
3 ...
4 <% end %>
1 #Rails 4.0
2 <% cache @user do %>
3 ...
4 <% end %>
5 #this will generate a key like
6 # views/users/1-201222172130/1a79a4d60de6718e8e5b326e338ae533

在嵌套视图中也可以使用,它能识别是嵌套视图的情况。这里有一个相关的 Railscast

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

声明式 ETags (gem)

在 Rails 4 中你将可以设置控制器范围的 ETag 后缀。当一个 action 依赖于多个记录或者是登录用户时很有用。

这真的是一个非常简单的方法用以获取更好的HTTP缓存。

一个简单的例子:

01 class TodosController < ApplicationController
02   etag { current_user.try :id }
03   etag { @todo_list }
04   before_fiter :find_todo_list
05   def show
06     @todo @todo_list.todos.find(params[:id])
07     fresh_when(@todo)
08   end
09   private
10   def find_todo_list
11     @todo_list = TodoList.find(params[:todo_list_id])
12   end
13 end

在这个例子中,第一个 etag 块检查当前用户,确保不会出现两个不同的用户使用相同的缓存 ETag。第二个使用 TotoList 对象作为 ETag 的一部分,因此修改了 todo list 就会同时修改 ETag。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

Turbolinks (gem)

Turbolinks 类似 pjax 的兄弟,它使用 pushState,触发一个 XHR 请求,然后替换 <body> 内容。有三个优点:

  • 需多次下载 CSS/JS
  • 无需重新编译
  • 不用重新评估


红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

Rails 4 默认启用 Turbolinks。但如果你使用太多 dom ready 事件的话可能会带来一些问题。TurboLinks 声明了 4 个新的事件:
  • page:fetchstarting 用于获取目标页面 (只有刷新时调用,缓存时不调用).
  • page:loadfetched 当从服务器中获取完页面时调用
  • page:restorefetched 当从客户端缓存中获取页面时调用
  • page:changepage 页面更改为最新获取的版本


红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

你必须检查你的 JavaScript 代码,并在需要的时候修复它。

想现在使用,只需安装那个 gem 然后在你的主 JavaScript 文件(通常是 application.js)中添加 //= require turbolinks

关于这个特性,这里有一篇很好的 Railscast

Concerns

Rails 4 引入了新的默认模式用于避免代码重复。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

Routing Concerns (gem)

当多个resources或methods被几个routes共享时, 会产生大量重复代码. 这个功能在routes上给了我们一个新的concern定义, 来提高可读性以及使代码更DRY.

1 #Rails 3.2
2 resources :messages  do
3   resources :comments
4   post :trash:restore, on: :member
5 end
6 resources :documents do
7   resources :comments
8   post :trash:restore, on: :member
9 end
1 #Rails 4
2 concern :commentable do
3   resources :comments
4 end
5 concern :trashable do
6   post :trash:restore, on: :member
7 end
8 resources :messages:documents, concerns: [:commentable:trashable]

这功能可以在Rails 3.2中通过加装routing_concerns gem来使用.

OnionBomb
OnionBomb
翻译于 7个月前

0人顶

 翻译的不错哦!

其它翻译版本(1)

Models 和 Controller 关注

Rails 4 默认增加两个新的文件夹:path:app/controllers/concerns 和 app/models/concerns .

DHH 上有篇 文章 解释了这个思路。

一般代码是存在于 lib 目录,这些新的目录让事情看起来更加简洁和容易查找。

红薯
红薯
翻译于 7个月前

0人顶

 翻译的不错哦!

要完成这点修改,你仅需简单的把下面这行代码添加到 yourconfig/application.rb

1 config.autoload_paths += Dir["#{config.root}/app/controllers/concerns""#{config.root}/app/models/concerns"]

然后再把你的 model 和 controller 等这些模块移到这些目录中。

Tom-Lin
Tom-Lin
翻译于 7个月前

0人顶

 翻译的不错哦!

Dalli 成为了 memcache 客户端(gem)

Dalli 将替换掉掉 memcache-client 而成为 gem 的默认缓存客户端。

这将带来以下几点改进:

  • 这将比 memcache-client 快了将近 20%.
  • 可以处理故障转移和恢复,并能调节超时设置。
  • 这是线程安全的
  • 使用了更新的 memcached 二进制协议


Tom-Lin
Tom-Lin
翻译于 7个月前

0人顶

 翻译的不错哦!

现在要在你的应用中测试这项改动,你仅需简单地做以下两点:

在你的 Gemfile 里:

gem 'dalli'

Inconfig/environments/production.rb(或者是你使用的memcached环境):

1 config.cache_store = :dalli_store
2 # just be sure to change this back to :mem_cache_store when upgrading to Rails 4

要注意一件事:Dalli 依赖于 memcached 1.4+,因此如果你使用了旧的 memcached 版本,那么你也要先升级你的 memcached!

Tom-Lin
Tom-Lin
翻译于 7个月前

0人顶

 翻译的不错哦!

默认启用线程安全

在新的 Rails 应用中,产品模式下默认启用线程安全选项,你可设置 config.cache_classes 和 config.eager_loader 值为 false 来关闭它。

这里应该不会有太多问题,除非应用过分的依赖于线程安全。

这里有一篇 Aaron Patterson 写的博客解释了这个改变:config.threadsafe!: What does it do?

你现在就可以在应用中启用 threadsafe! 选项来查看具体表现。当升级到 Rails 4 后你就会看到一个警告,你可以移除这个配置行。

红薯
红薯
翻译于 7个月前

2人顶

 翻译的不错哦!

其它翻译版本(1)

总结

本文把即将发布的 Rails 4 的主要更新内容都包含了。在这些更新中,大多数应用都能够轻易地升级到 Rails 4。但不管怎么说,Rails 4 还在积极的开发中,因此,将来还会有一些其他的更新。我将会持续关注并不断更新本文。

进一步阅读:

  • Rails 4 Countdown to 2013
  • Rails 4 in 30 minutes
  • Ruby on Rails 4.0 Release Notes# Get your app ready for Rails 4!

你可能感兴趣的:(on,Ruby,Rails,Rails)