Rails3.2.22.5 => 5.1.5 への道
■役たったコマンド
git co feature/rails5.1.5 spec/controllers/
これでブランチの一部をマージできる!地味にうれしい!
bundle exec rails app:update
これで初期設定はほぼやってくれる
Rails4ならこっち
bundle exec rake rails:update
勝手に作られた
configファイル
create config/secrets.yml create config/cable.yml create config/puma.rb create config/spring.rb create config/initializers/application_controller_renderer.rb create config/initializers/assets.rb identical config/initializers/backtrace_silencers.rb create config/initializers/cookies_serializer.rb create config/initializers/cors.rb create config/initializers/filter_parameter_logging.rb
逆に設定ファイルがあるせいで
エラーが出ることがある
一応
バックアップファイルとしておいてるけど挙動が不安スグル
■エラー集
Model
・countの罠
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near
こんなエラーがでたら
test = model.select("aaa, bbb, ccc").where(hoge: 0)
してから
test.count
をすると
select count(aaa, bbb, ccc) from hage where hoge = 0;
というようなSQLが発行され
Syntaxエラーになる
正解はこちら
test.size
・has_many, has_one, be_longsto系
conditios,orderは今後一切使えないので
has_one :hoge, order: :hoge_rank, condtions: ["hoge_rank >= 0", 0]
has_one :hoge, -> { where("hoge_rank >= ?", 0).order(:hoge_rank) }
と修正
そもそもconditiosが必要ないModel設計が
今回のバージョンアップで一番大切だと学んだ
正直これ直すのめちゃ辛かった。
・undefined method `sanitize`
Rails5から
ActiveRecord::Base::sanitize
は使えなくなりました!
・Modelから通常のハッシュクラスにしたい
users = User.where(sex: 1).map(&:attributes)
これでなるので
to_jsonにするときとかは非常に大事だと思う
・MySQL geometry型
位置情報で使われるgeometry型
Rails5からto_jsonするとこけるようになった
今回はGem入れて変換とかじゃなくて
使われてなかったので値を消した。
・eager_loadで勘違い
モデルのincludesは
preload => joins しない
eager_load => joins する
って感じらしいのとプラス
基本は
preload が使用されるらしい
ちなみにConfigのeager_load
はTrueであると
modelとは一切関係なく
サーバー起動前にapp配下のオブジェクトのNilCheckをしてくれるというやさしいやつ
・join, orderの書き方
User.joins(:item).order(:num)
というようなOrderの書き方に注意
Rails3だと
select users.* from users inner join items on items.user_id = users.id order by num;
と発行されるが
Rails5だと
select users.* from users inner join items on items.user_id = users.id order by users.num;
になるので
usersテーブルにnumカラムがないとエラーが起きるぞ!
ちゃんと
order("#{Item.table_name}.num")
と書こう!
・NOT NULL制約のカラムは入力必須に
Rails3は見ていなかったが
Rails5からはNOT NULL制約をみるようになった
usersテーブル name NOT NULL age NOT NULL
だとしたら
user = User.new user.name = "hogehoge" user.save
でエラーになる(当たり前っちゃ当たり前だが)
user.age = 100
も追加しよう
・belongs_to の罠
valid?っでかなり変なエラーが追加されるのでなんぞや??
って調べまくっていたら
relationで設定されている値がNullになっていると
エラーを出すようになったらしい。
Nullの可能性もあるよって時は
optional: true
をbelongs_toの最後に追加することで解決した
・配列と見せかけActiveRecode::Relationクラス
users = ::User.where(status: 0).all # Rails5だとエラーになる users << ::User.where(status: 1).all
また
普通の配列のようにslice
を使うと
これは配列じゃないだよと怒り出すので
User.all.to_a.slice(1, 3)
見たいに使おう
Controller
・Javascriptでアクセスされてもいい場合
Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.
protect_from_forgery except: :index
見たいな書き方でエラーではなくなる
・before_filterはうごかないぜ
before_actionへ切り替えや!
・params permit
ちゃんとしろよ!
permit してないのに
params[:user][:name].gsub(/ruby/, "perl")
とかしたらおこだぞ!
・Browserクラスの引数が変更
# botの場合はログに残さない ua = URI.decode(request["HTTP_USER_AGENT"]) browser = Browser.new(ua: ua)
こんなコードを見つけたんだが
正しくは
browser = Browser.new(ua)
である
・ActionController::Parametersオブジェクトに対して
with_indifferent_accessは使えない
with_indifferent_access
とはHash変数の引数を文字列でもシンボルでも受け取れるようになる関数
使用するためには
.to_h.with_indifferent_access
としなくてはいけない
・render text
はもう使えない
render plain: "OK"
に変更
Route
・asオプションに注意
get 'hoge', to: 'hoge#index' as: 'hoge' get 'huge/:id', to: 'hoge#show', as: 'hoge' # => 二個あるよ!エラー
・match 使うなら
vi オプションでHTTPメソッドの指定をしないといけなくなりました!
match 'admin' => 'admin#show', via: :get
・ActiveRecord::PendingMigrationError
未実行のマイグレーションファイルがあるぜ
Rails3は未実行でもエラーを起こさなかったことが逆にすごい。。
Rspec
・Rspec unknown keywordについて
Rails5限定みたい
get :show, id: 1
だとだめで
正しくは
get :show, params: { id: 1 }
とparams変数に入れないといけない
・Rails 5 からコントローラーのテストで assigns などを使う場合
rails-controller-testing
gem 必要です!
さらにいうとrequest specへ
移行することが好ましいようです!
・レンダリングページ
expect(response).to render_template("hogehoge")
こんな書き方をしていたら
Controller名も追加してテンプレート名を正しい値を入れる
expect(response).to render_template("hage/_hogehohge")
その他
・invalid byte sequence in UTF-8
これが厄介すぎる
普通の文字列のはずなのに
なぜかUTF-8じゃないって怒られて
image_tag
javascript_include_tag
stylesheet_link_tag
とか一切動かない
fileコマンド打ってみたらasciiがあったけども。。
=> 原因不明のままだが
Scssファイルの構文エラーを直し
bundle exec rails precompile
したら直る
・scssの設定がこけるこける
@include
@mixin not found
なんとかしないと
・正規表現のエラー
The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?
先頭、末尾を
^ $
から
\A \z
を使用
大体モデルで使ってるので
モデルに記載して終了
・Cookieの形が違う
TypeError (incompatible marshal file format (can't be read) format version 4.8 required; 123.34 given):
意外とガッツリはまったw
bundle exec rails app:update
で作成された下記ファイル
config/initializers/cookies_serializer.rb
ails.application.config.action_dispatch.cookies_serializer = :json
と指定していたらいつの間にか
上のエラーが出てびっくりした
ブラウザキャッシュを消すことで
収まったがこの設定はもう必要ないかな。。
・lib配下のモジュールを使う
config/application.rb
に下記を追加することで
lib配下のモジュールを使うことができた
config.paths.add 'lib', eager_load: true
・ブロック無しのlink_toは引数の数を三つ以内じゃないとエラー
link_to("hoge", "https://hogehoge/hage", a_options, b_options) => × link_to("hoge", "https://hogehoge/hage", a_options.reverse_merge(b_options)) => ○
・JqueryのVerによって書き方違った
$('a[href^=#hoge-]').on('click', function() {});
unrecognized expressionとエラーがでて
失敗するので
$('a[href^="#hoge-"]').on('click', function() {});
とかいてクォーテーションで囲もう