upinetree's memo

Web系技術の話題や日常について。

Rails 5.0.2 => 5.1.4 へのアップデートで地味に面倒くさかったこと

ActionController::Parameters がpermittedでないときに例外出すようになった

ちゃんと指定してpermitしたほうが良いんだろうけど、ログとかでpermitしなくても問題ない場面やpermit対象が動的に変わるものがある。 そういときに

params[:hoge].to_h

みたいなのはpermittedフラグが立ってないので例外が発生する。

params[:hoge].permit!.to_h
# もしくは
params[:hoge].to_unsafe_h

のようにする。

ActiveRecord::AttributeMethods::Dirty の一部仕様が変わった

save前後で呼び出す attribute methods が変わった。 https://github.com/rails/rails/pull/25337

使い分けは面倒だが、save前後での違いが明確になってスッキリした感じ。

リリースノートにないので注意。

save後

attribute_changed? とかをsave後に利用することがdeprecatedとなった。 after_save コールバック内で呼び出したりするのも同じ。

たとえば以下のような感じに対応する。

  • attribute_changed? => saved_change_to_attribute?
  • attribute_was? => attribute_before_last_save

※ attribute method なので attribute の部分をカラム名で置き換える。nameの場合は saved_change_to_name のようになる。

save前

今までと同じ感じで使える。

ただ、save前用の新しいメソッドも生えてる。 たとえば attribute_changed? に対しては will_save_change_to_attribute? が使える。 新しい方は内部的な扱い方がちょっと違うけどやってることは同じっぽい。

create_table のプライマリキーがデフォルトBIGINTになった

ActiveRecord::Migration[5.1] 以降を継承しているマイグレーションが対象。

ActiveRecord::Migration[5.0] 以前のバージョンのマイグレーションはBIGINTにならないよう互換性の配慮がされている。 具体的には schema.rb での create_table のオプションに id: :serial (pgの場合)が付くようになる。

5.0以前と以後のマイグレーションではプライマリキーの型で違いが出るようになってしまう。 これに対して2通りのアプローチがある。

  1. Migration[5.0] 以前で作ったプライマリキー(及びそれを参照する外部キー)も順次BIGINTにしていく
  2. Migration[5.1] 以降のマイグレーションではすべて id: :integer をつけるルールにする(デフォルトに従わない)

1 が順当そうで、このPR投げた人もおすすめしてる ( http://www.mccartie.com/2016/12/05/rails-5.1.html )。 BIGINTが必要にならない場合は 2 もありなんだけど、ルールを忘れられないようにするか、自動でなんかするかしたほうがいい。

BIGINTとINTが混ざった状態も許容するのも考えられるが、後々の負の遺産となりそうなのでどちらかに統一したほうがよさそう。

互換性の考慮漏れが一部ある(Rails 5.1.4)

ふつうに create_table していれば前述したような互換性対策が走るので問題ないのだけど、一部考慮が漏れているところがある。 具体的にはプライマリキーを add_column :articles, :id, :primary_key のようにして作ったとき、BIGINTになってしまう。 masterでは対応が入っている ようなので、Rails 5.1.5 では問題にならなさそうだけど、 一応それまでは db:migrate:reset によるschema全更新ができないことは注意したい。