Rails 4.0 新特性

本文主要参考[官方release notes](https://github.com/rails/rails/blob/master/guides/source/4_0_release_notes.md ), [官方commits](https://github.com/rails/rails/commits/master )

##Rails 4.0主要更新
* Ruby 1.9.3 only
* Strong Parameters
* Queue API
* Caching Improvements

除此之外在缓存、即时web应用方面都有小的改进,另外还废除了一大堆东西...

###Ruby 1.9.3 at least
这个没什么好说的,现时很多常用gem的支持都已经高于1.9.2了,尽管使用ruby的朋友都不会太在意性能,但其实很早之前[跑Rails3.0 Ruby1.9.2 已经比快 1.8.7快](http://akitaonrails.com/2011/01/08/testing-a-rails-3-0-3-with-ruby-1-9-2-and-ree-1-8-7#.UKx5GePZ_RE),作为ruby圈圈的一分子,我们应该热情拥抱变化。话说Ruby 2.0也即将到来,过会也更新一篇关于Ruby 2.0新特性的Blog

###Strong Parameters
话说今年[github被hack](https://github.com/rails/rails/commit/b83965785db1eec019edf1fc272b1aa393e6dc57), 然后大家开始意识到Rails虽然能帮我们很方便的一条龙生产mvc还有粘合在view层上的各种表单helper,但是这在用户提交方面有很大的安全问题。

因为model的字段属性通常都直接现实在Form各种Input的属性里,如果我们不对用户提交作检查,用户很容易就可以写进能修改原来不能修改的属性。

例如有此Form:
```ruby
<%= form_for @user do |f| %>
    <%= f.string :name %>
    <%= f.integer :age %>
    <%= f.sumbit "Submit" %>
<% end %>
```

此controller:
```ruby
class UsersController < ApplicationController::Base
    def create
        if User.update_attributes(params[:user])
            #dosometing
        else
         #......
        end
    end
```

直接在model级别让我们用params,可以另我们的controller看上去很简洁,但如果被人猜到User认证admin的字段,同时加进params里面提交上来的话,后果...

但其实之前Rails也有防范的方法, 就是在model里设attr\_accessible白名单属性或attr\_protected黑名单(推荐用白名单),设置后有名单以外的属性要跑进来的话就会抛错误,这有效防御了恶意的属性。

但这属性设置也带来问题,这很容易把model搞得七零八落,当时[37Signals也给出他们的做法](https://gist.github.com/1975644), 就是把检验params的任务放在controller,如此就避免要走一堆model的callback。这做法曾经在hacknews上面也有争议,但到了Rails 4.0, 这成了官方推荐。

```ruby
class PostController
    def create
        Post.create(post_params)
    end
    
    private
    def post_params
        params.require(:post).
        permit(:title, :body)
    end
end
```

1. 在设过strong_parameter的controller里,以后如果直接把params这东西扔给设过mass-assigned model的话会直接raise `ForbiddenAttributesError`
2. 但mass-assigned model用在其他Controller里也会可以接收到params...
3. attr\_acessiable 和 attr\_protected 会被移除, 放到protected_attributes的gem

###Queque API 队列
ActiveSupport::Queue #用于后台队列新线程处理一些不用即时返回结果 或 昂贵代价(一般会容易令链接阻塞)的操作, 例如邮件发送,第三方数据处理,数据库大量的update或delete
```ruby
class ExpenceOperation
    def run #queue处理类实现一个run方法就行
    #...
    end
end
Rails.queue.new(ExpenceOperation.new) #what ever you want,Rails.queue可以访问整个队列
config.queue = ActiveSupport::Queue
config.queue_consumer = ThirdPart::Stuff #还可以指定第三方实现队列
```

另外还有了`Async ActionMailer` , 在MailerClass里设`self.async = true`就可以后台任务发邮件

###Caching Improvements
过往的设cache方式
```eruby
<% cache ["v1", Catagory] do%>
    Catagory : <%= Catagory.name %>
<% end%>
```
旧方式有可能在多个render或者 model嵌套后, nested的内容更新不了,例如开发规模大了上面的 v1也可能会有冲突

新方法
```
<% cache Catagory do%>
    Catagory : <%= Catagory.name %>
<% end%>
```
rails4.0方式,粒度更少,帮你掌管好key,不用管太多其他东西

###其他
1.ActionController::Live,利用html5 websocket的实时stream!
```ruby
class YourController
include ActionController::Live
    def index
        100.times {
            response.stream.write "hello \n"
        }
        ensure
        response.stream.close
    end
end
```

2.ActiveRecord all returns a relation
```ruby
Post.all.class #=> ActiveRecord::Relation
```
nil制不再抱怨太多
```ruby
#rails3
nil.id #=> RuntimeError blahblahblah...
#rails4
nil.id #=> nomethod for nil class!
```
3.update\_attribute|attributes 会改进 ?不再迷迷糊糊的要你记update\_attribute其实是不跑validate的,update\_column和columns又其实没有分别的...

4.`first`和`last`生成的sql语句有性能改进

5.废弃掉过去版本的find用法
```ruby
User.find(:all)
User.find(:first) 之类的
Post.find(:all, :conditions => { :comments_count => 10 }, :limit #=>User this: Post.where(comments_count: 10).limit(5)
```
一些方法会被取代为
```ruby
find_by # ok
find_all_by # where()
scoped_by # where()
find_last_by # where().last
find_or_create #where().first_or_create
find_or_initialize_by # wehere().first_or_initialize
```

6.查询条件更丰富,sql语句改进
```ruby
#过往
Post.includes(:comments).where("comments.id > ?", ...)
#Rails 4的做法,应该更详细指定条件
Post.includes(:comments).where("comments.id > ?", ...).references(:comments)
Post.includes(:comments).where(:comments=>{title:""...})
Post.includes(:comments).order("commments.created_at")
```

7.`:remote=>true` rails自身的ajax_helper,4.0开始要自己指定`authenticity_token`,增加了安全性

8.turbo_links pjax
这是某blog看回来貌似将会有个叫turbolinks.js的东西,方便做全站ajax单页面的应用

9.routes dispather方面也有挺多更新的,其中
Add /rails/info/routes path 把之前rake routes的内容放进来,可以更快得到routes的信息

---------
P.S当前更新比较主要内容,如有添加会继续更新,这是本网站的第一篇文章,下一个功能应该是RSS还有想实现一个基于ticket的小社交应用
来自:http://gu-da.com/users/1/articles/1

你可能感兴趣的:(Rails 4.0 新特性)