静岡市でWeb開発しているkazuomatzです。
以前、こちらの記事で、Rails + MySQL で位置情報を扱う時に標準だったライブラリ activerecord-mysql2spatial-adapterについて書きました。
ライブラリの開発が止まってしまい、新しいRailsのバージョンに更新しようとすると対応されていないので、リポジトリをforkして、Rails6.0で何とか動かした話です。
今年、AWSのRDSのMySQL5.7系のサポートの終了がアナウンスされました。2024年2月以降、RDSでMySQL5.7を利用し続けるには、有償の延長サポートに入る必要があります。
というわけで今年は、MySQL5.7で稼働しているシステムをMySQL8に更新するお仕事が数件ありました(2023年12月現在、まだまだ絶賛実施中です)。
当然、MySQL5.7とMySQL8.0に移行するにあたり非互換な部分を洗い出して行くのですが、activerecord-mysql2spatial-adapterにも非互換がありました。
Rails5.1以前であれば、activerecord-mysql2spatial-adapterは動作させることが可能でしたが、当時から稼働しているシステムをそのままデータベースをMySQL8アップグレードしてしまうと動かないので注意が必要です。
Mysql2::Error: FUNCTION some_scheme.GeomFromWKB does not exist.
具体的には、MySQLのリファレンスにあるのですが、
MySQL 5.7 では、複数の名前で使用可能ないくつかの空間関数は、空間関数ネームスペースの一貫性を高めるために非推奨になりました。各空間関数名が ST_(正確な操作を実行する場合) または MBR(最小境界矩形に基づいて操作を実行する場合) で始まるという目標です。 MySQL 8.0 では、非推奨となった関数は削除され、対応する ST_および MBR 関数のみが残されます:
これらの関数は、ST_名を優先して削除されます: Area(), AsBinary(), AsText(), AsWKB(), AsWKT(), Buffer(), Centroid(), ConvexHull(), Crosses(), Dimension(), Distance(), EndPoint(), Envelope(), ExteriorRing(), GeomCollFromText(), GeomCollFromWKB(), GeomFromText(), GeomFromWKB(), GeometryCollectionFromText(), GeometryCollectionFromWKB(), GeometryFromText(), GeometryFromWKB(), GeometryN(), GeometryType(), InteriorRingN(), IsClosed(), IsEmpty(), IsSimple(), LineFromText(), LineFromWKB(), LineStringFromText(), LineStringFromWKB(), MLineFromText(), MLineFromWKB(), MPointFromText(), MPointFromWKB(), MPolyFromText(), MPolyFromWKB(), MultiLineStringFromText(), MultiLineStringFromWKB(), MultiPointFromText(), MultiPointFromWKB(), MultiPolygonFromText(), MultiPolygonFromWKB(), NumGeometries(), NumInteriorRings(), NumPoints(), PointFromText(), PointFromWKB(), PointN(), PolyFromText(), PolyFromWKB(), PolygonFromText(), PolygonFromWKB(), SRID(), StartPoint(), Touches(), X(), Y()。
GLength() は、ST_Length() を優先して削除されます。
要はST_XXX という関数がMySQL5.7では非推奨ながら残っていたけど、MySQL8ではなくしたよということです。
activerecord-mysql2spatial-adapter では、
- GeomFromText
- GeometryFromWKB
- GLength
が使われています。
これらを、以下の関数を呼び出すよう置き換えなければなりません。
- ST_GeomFromText
- ST_GeometryFromWKB
- ST_Length
あー、これ、Rails6.0対応の時にやっていたんだった。モンキーパッチ当ててもよいですが、せっかくforkしたリポジトリがあるので、各Railsのバージョンに対応しました。
Rails4.2 の場合
gem 'activerecord-mysql2spatial-adapter', github: 'kazuomatz/activerecord-mysql2spatial-adapter', tag: 'v0.4.2'
- bundlerが1系の場合は、RubyGemsがgit:// で接続できなくなったので以下のように必要があるかもです。
gem 'activerecord-mysql2spatial-adapter', git: 'https://github.com/kazuomatz/activerecord-mysql2spatial-adapter', tag: 'v0.4.2'
Rails5.0の場合
gem 'activerecord-mysql2spatial-adapter', github: 'kazuomatz/activerecord-mysql2spatial-adapter', tag: 'v0.5.0'
Rails5.1の場合
gem 'activerecord-mysql2spatial-adapter', github: 'kazuomatz/activerecord-mysql2spatial-adapter', tag: 'v0.5.1'
Rails6.0の場合
gem 'activerecord-mysql2spatial-adapter', github: 'kazuomatz/activerecord-mysql2spatial-adapter', tag: 'v0.6.1'
Rails6.1以降は・・・対応していません。過去プロジェクトで対応が必要な場合は参考になればと思います。
現在はRails7で開発するプロジェクトがあるわけですが、さすがにactiverecord-mysql2spatial-adapterを引き続き使うのは辛いので、クックパッドさんが開発しているarmgを使っています。