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
-
StrongParameters対応
更新可能なカラムをModelのattr_accessibleでなく各Controller内で定義する。
重要な内容なのでどこかで詳細について読んだ方がよいです。ここではあえて深くは書きません。
許可されていないパラメータを渡した時にエラーが出るよう、config/environments/development.rbに以下の一文を追加しておく方がよいでしょう。
config.action_controller.action_on_unpermitted_parameters = :raise
-
xxx_filterがxxx_actionに変更
3.2:before_filter
4.0:before_action
-
find_by_xxx記法の変更
3.2:User.find_by_name 'foo'
4.0:User.find_by(name: 'foo'
) -
scopedがallに変更
以前はUser.all
はArrayを返していましたが、whereなどを使った場合と同様にRelationを返すようになりました。
3.2:User.scoped
4.0:User.all
1〜4をまとめると以下のようになります。
3.2:
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:
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
-
attr_accessibleの削除
Mass Assignment脆弱性対策がcontrollerの説明の方で記述したstrong_parametersでの対応になるので、attr_accessibleは削除。
attr_accessibleを使いたければprotected_attributesというgemを導入するようです。 -
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
//= require jquery
//= require jquery_ujs
//= require_tree .
4.0
//= require jquery
//= require jquery.turbolinks
//= require turbolinks
//= require jquery_ujs
//= require_tree .
*私はjquery-turbolinksを入れてもうまくいかないところがあったので、今回は最終的にはturbolinksは切ってしまいました。
その他
- 正規表現の記述が一部厳しくなりました。
^と$は改行に対応していないため危険だと言われるので、^は\Aに、$は\zに変更します。
以上です。足りない内容などお気づきの点はコメントください。