PostGisを使っているケースが多く、MySQL周りのライブラリはあまり活発ではありませんでした。更新があまりされていなくて、Rails5への対応もずっと止まっていて少し不安です。対応した別のライブラリを探すか、これを使うなら自分でPRを凄く送る等が必要かなと思います。Railsで位置情報を扱ってる情報の流通量がそもそも少ないので新しいライブラリの情報を見つけづらいというのはありますね。Record::Type::Valueを継承する必要があります。Armgでも以下のように:geometry型を新規に定義しています。:mysql2)のようにして、データ型をActiveRecordに登録してやっています。DBへのQueryに埋め込む形式に変えるために、serializeというメソッドが呼び出されます。拡張なしのActiveRecordで対応しているのはStringNumericDateTimeSymboltruefalsenilくらいだと思います、なので、通常新規の型を作るなら、これらへの変換をserializeの中でやる必要があります。Deserializer合わせて定義しました。endこのようなカスタムのSerializerを定義してやりました。GeometrySerializer.new登録してやる必要があるのですが、このタイミングが重要です。initializersのなかで適当に上記の行を実行しようとするとArmg周りの定義で死にます。do....endというブロックの中でrequire等が行われているので、initializerの段階ではまだArmgの型等がUndefinedだったりします。そんな状況でnewしようとするので当然死にます。ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.prepend(::ArmgConnectionAdapterExt)endこちらの登録についても同様にハンドラに登録してやって遅延させる必要があります。ログが死ぬここまでで本来は問題ないのですが、ここで問題が起こります。上記のserializerではWKBと呼ばれるバイナリ形式をつかってSQLにgeometryデータを流し込もうとします。これがRails上でログ解析時に異常なUTF-8文字列だと認識されて例外を吐くようになります。FactoryGirl等で書き込むときに例外を吐かれるとテストが通りません。このような文字列形式じゃない形で送る必要があります。<SRID>)という16進数とSRIDを指定する形式です。これならエラーは出ないでしょう。そこで、正常にRubyが処理できる形式でSQLに織り込んでやる必要があります。serializeの中で適宜変換してやる必要があるのですが、SQLへの埋め込みは実際にはそれではうまく行きません。そもそも前述のようにserializeから本来返せるデータ型には制限があります。今回使うのに適切そうなのはStringだと思いました。ST_GeomFromWKBのSQL関数文字列を素直にserializeから返してやればいいと。そもそもserializeは文字列型で渡されるとSQLには「その文字列をそのまま文字列としてSQLに渡そう」とします。VALUES("ST_GeomFromWKB(....)")というふうに文字列形式で吐き出されてしまってSQLの関数呼び出しではなくなってしまいます。AdapterExtでquoteに手を入れるそのため、Type::Valueのレベルではハンドリングできないことがわかりました。ユーザーはSQLは理解してくれるはずの独自形式を作れないのでしょうか?そのようなときに使うのがDBへのコネクタへの拡張です。上のコードでActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.prepend(::ArmgConnectionAdapterExt)の用にしているのがソレです。DBへのコネクタが値をSQLに変換するまでの過程に手を加えることができます。column_=nil)というメソッドが重要になってきます。そのまま埋め込んで良い文字列に変換するためのメソッドです。イメージとしては返された文字列が直接SQLに結合されるというイメージです。埋め込まれるのではなくhogeとSQLの一部として埋め込まれるのです。これを使えば、SQLの中に直接先程のST_GeomFromWKBを埋め込むことができます。そこで、先程のGeometrySerializerを以下のように変更します。そのまま返すようにしました。定義して、ソレ以外は親に任せるように定義してやります。ラップされた形で書き込まれるようになります。以下のような感じです。1これで無事にログ上にも正常にSQLが表示されるようになり、例外は発生することはなくなりました。5.1で利用する場合は上のコードの引数も修正してください。ラップされている事があるようになりました。endendといった形で取りだしてやる事で対処できます。以下のようなscopeも書けるようになります。lat))}この?の部分で先程のquoteが使われています。自然にSQLで位置情報を扱えるようになりました。»プロフィールid:Pocket7878_devプログラミング好きで、仕事の傍らで趣味で書いたもの等があればちょびちょび更新していきます。Inc.はてなブログをはじめよう!Pocket7878_devさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。