自分は、Oracle を使ったアプリケーションコードを Rails 5 にアップグレードするにあたって、モンキーパッチを充てている箇所について調査をしていた。
予め分かっていたこととして、Rails 5 で Rails 4 の頃の (リンク先の) コードが消えていて、そのあたりが Rails 5 へのアップグレードに影響しているようだった。このことにより、String を期待するところ Enumerize::Value が渡されて以下のようなエラーが発生する事象と出会ってた。
サンプルコード。
class Music < ApplicationRecord extend Enumerize enumerize :genre, in: %i(rock metal) end Music.create(genre: :metal) genre = Music.first.genre # String を継承した Enumerize::Value インスタンスが返る Music.find_by(genre: genre) # エラーが発生する
エラー内容。
RuntimeError: unsupported datatype: Enumerize::Value: SELECT "MUSICS".* FROM "MUSICS" WHERE "MUSICS"."GENRE" = :a1 AND ROWNUM <= :a2
ワークアラウンドコードとしては config/initializers/oracle.rb
なんかを作って以下のようなコードを書いて回避している。
ActiveSupport.on_load(:active_record) do OCI8::BindType::Mapping[Enumerize::Value] = OCI8::BindType::String end
今回、upstream に手を入れるとしたら AR なのか、Adapter なのか Enumerize なのかといった感じで、開始点としてミニマムケースを作って Oracle 以外の RDBMS でどうかを試したところ、SQLite では同様の問題が起きなかったあたりで時間切れ。
やったことを話した際に得られたフィードバックとして、パッチ以外にアプリケーションコードとして AR::Enum の利用も視野に入れてよさそうというのがあった。Enumerize (Alternative) から AR::Enum (Standard) にするようであれば、以下のあたりを検討材料として加味すると良さそう。
- Enumerize の場合は default が使える
- Enumerize の場合は I18n が使える
- AR::Enum にすると
enum genre: { rock: 0, metal: 1 }
といった数値になるのでデータパッチは必要
その他、気に留まったいくつかの話題。
すぎのいさんのやっていたことの話から AR::NullRelation まわりの実装話。
大きくなった Kaminari が解体されはじめた。いずれ kaminari-core なんかもそちらに移って行く予定っぽい。