あるプロジェクトでrails 3.2.9 にアップデートしたら テストが失敗しまくる。そのひとつに ActiveRecordの default_scope を使ってる部分に問題があるとわかった。

どんなエラーかと言いますと。

NoMethodError: undefined method `to_i' for [1, 2, 3]:Array
from activerecord-3.2.9/lib/active_record/connection_adapters/column.rb:178:in `value_to_integer'

[1, 2, 3] とか即値すぎて わけがわからないよ という感じだったんですが、いろいろ調べると

class User < ActiveRecord::Base
   default_scope proc { where(state_id: [1, 2, 3]]) }
end

というコードがあったときに

User.new

すると発生することがわかりました。

仕方ないので、

class User < ActiveRecord::Base
   scope :valid, proc { where(state_id: [1, 2, 3]]) }
end

として、ひたすら置換しまくりでした。 僕はdefault_scope使わない派なのであまり気にしない方向で。

ちなみに

class User < ActiveRecord::Base
   default_scope proc { where(state_id: 1,name: "hoge") }
end

としておくと

User.new
=> #<User id: nil, name: "hoge", state_id: 1>

となるようです。 scopeから初期値を生成する機能がもともとあったみたいで(知らなかった)それがdefault_scopeのものがデフォルトになったようです。