Rails4プロジェクトを新規作成してRails3.2からRails4にマイグレート

Rails3.2のプロジェクトをRails4に移行する際の手順をまとめます。
今回は新規にRails4プロジェクトを作り、Rails3.2のプロジェクトのファイルを移していく方法を取りました。
前バージョンからの移行でなく新しくRails4プロジェクトを作る場合にもある程度参考になると思います。

# 前準備
### 使っているgemがrails4に対応しているか調べる
以下のサイトが便利です。ほとんどのgemのrails4対応状況がわかります。
※リンク先が切れていたので削除しました。

### RubyGems本体をアップグレードしておく
必要があれば。

```
gem update --system
```

### rails4をインストール

```
gem install rails
```

### springをインストール
コマンドの実行が速くなるそうです。

```
gem install spring
```

### 新規プロジェクトを作成
今回はDBにPostgresqlを使うので--database=postgresqlをつけて。デフォルトのSQLite3を使う場合はここは不要。他のDBを使う場合は適宜変更してください。herokuを使うならpostgresがいいです。
springを導入したので以降各コマンドの先頭にspringが入ります。

```
spring rails new PROJECTNAME --database=postgresql
```

### database.ymlの変更
username, password等を入力。必要があればその他の項目も変更。

### scaffoldの作成
rails3と同じです。`spring rails g scaffold MODELNAME COLUMN_NAME:TYPE`
例：

```
spring rails g scaffold item user_id:integer name:string
```

db/migrate下のマイグレーションファイルを適宜編集して`spring rake db:migrate`
とりあえず一つscaffoldを作ってみて、生成されるファイルの中身を見てみると様子が少しわかります。

# 旧プロジェクトからのファイルの移動と変更
さて、いよいよ本題です。3.2->4.0マイグレートの際に変更が必要な箇所全部を網羅してはいないかもしれませんが、とりあえず私が行った変更はすべてあげます。
## Gemfile
rails4に対応していないGemを入れないよう注意。
jqueryを使っている場合はturbolinksがjqueryに悪さしないように以下のgemを追加。
`gem 'jquery-turbolinks'`
追加したら`bundle install`。バージョンの古いものがあれば`bundle update`

## Application Controller
3.2: `protect_from_forgery`
4.0: `protect_from_forgery with: :exception`
`with: :exception`のオプションは、apiを作る場合には`:null_session`が良いようです。

## 全Controller
1. StrongParameters対応
更新可能なカラムをModelのattr_accessibleでなく各Controller内で定義する。
重要な内容なのでどこかで詳細について読んだ方がよいです。ここではあえて深くは書きません。
許可されていないパラメータを渡した時にエラーが出るよう、config/environments/development.rbに以下の一文を追加しておく方がよいでしょう。
```config.action_controller.action_on_unpermitted_parameters = :raise```

1. xxx_filterがxxx_actionに変更
3.2: `before_filter`
4.0: `before_action`

1. find_by_xxx記法の変更
3.2: `User.find_by_name 'foo'`
4.0: `User.find_by(name: 'foo'`)

1. scopedがallに変更
以前は`User.all`はArrayを返していましたが、whereなどを使った場合と同様にRelationを返すようになりました。
3.2: `User.scoped`
4.0: `User.all`

### 1〜4をまとめると以下のようになります。
3.2:

```rb
def UserController < ApplicationController
  before_filter :set_user, :only => [:edit, :update]

  def update
    @user.update_attributes(params[:user])
  end

  private
  def set_user
    @user = User.find_by_id(params[:id])
  end
end
```

4.0:

```rb
def UserController < ApplicationController
  before_action :set_user, :only => [:edit, :update]  # _filterが_actionに

  def update
    @user.update(user_params) # Strong Parametersの例
  end

  private
  def set_user
    @user = User.find_by id: params[:id]  # find_by 記法の変更
  end

  def user_params
    # Userモデルのname, emailカラムのみ更新可能とする
    params.reqire(:user).permit(:name, :email)
  end
end
```

## Model
1. attr_accessibleの削除
Mass Assignment脆弱性対策がcontrollerの説明の方で記述したstrong_parametersでの対応になるので、attr_accessibleは削除。
attr_accessibleを使いたければprotected_attributesというgemを導入するようです。

1. lambdaなしscopeの記法の変更
3.2: `scope :items, where( target_type: 'Item' )`
4.0: `scope :items, -> { where( target_type: 'Item' ) }`
->はruby1.9からのlambdaの書き方。

## routes.rb
matchが廃止に。別の方法で書きましょう。
3.2 `match ':controller(/:action(/:id(.:format)))'`

## application.js
turbolinksを追加。

3.2 

```rb
//= require jquery
//= require jquery_ujs
//= require_tree .
```

4.0 

```rb
//= require jquery
//= require jquery.turbolinks
//= require turbolinks
//= require jquery_ujs
//= require_tree .
```

＊私はjquery-turbolinksを入れてもうまくいかないところがあったので、今回は最終的にはturbolinksは切ってしまいました。

## その他
1. 正規表現の記述が一部厳しくなりました。
^と＄は改行に対応していないため危険だと言われるので、^は\Aに、＄は\zに変更します。

***
以上です。足りない内容などお気づきの点はコメントください。