Ruby on Rails 2.3 + PostgreSQL 9.6.1 は一部の機能が動かない
ある仕事でRuby on Rails 2.3をメンテナンスしていますが、PostgreSQL のバージョンを 9.2 から 9.6.1 にアップデートする事になったのですが、一部の機能(Active Scaffold 覚えてますか?)が動きませんでした。
ソースを調べていくと、ActiveRecord の connection.table_exists?メソッドがいつでも falseを返しています。 ActiveRecord2.3のtable_exists?メソッドのソースを調べていくと PostgreSQLの SHOW search_path コマンドの戻り値を使っているのですが
PostgreSQLバージョン | 戻り値 |
---|---|
9.6より前 | "$user",public |
9.6.1 | "$user", public |
違いが判りますか? 9.6.1 は , の後ろに スペースが入っています。 ActiveRecord2.3では split(/,/)でパースしているので9.6.1では " public" が戻り、この値で pg_tablesテーブルの schemaname を検索するぐるのでテーブルが全くみつからなくなります。
そういうわけで、Ruby on Rails 2.3 はもうメンテされていないのでモンキーパッチを書いて対応しました。 ちなみにRuby on Rails4, 5 のソースを見てみましたが SHOW search_path ではなく current_schema() 関数を使っているのでこの問題ないです。
module ActiveRecord module ConnectionAdapters class PostgreSQLAdapter < AbstractAdapter def tables(name = nil) schemas = schema_search_path.split(/\s*,\s*/).map { |p| quote(p) }.join(',') query(<<-SQL, name).map { |row| row[0] } SELECT tablename FROM pg_tables WHERE schemaname IN (#{schemas}) SQL end end end end