質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
PostGIS

PostGISは、 PostgreSQLデータベースに地理空間情報を導入するための拡張です。ジオメトリ型、幾何関数、空間インデクスなどの機能が導入され、場所・移動・地域の情報などが扱い易くなります。

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Q&A

解決済

1回答

1657閲覧

Rails5 : SQL を扱う文で、何がsyntax errorなのかわからない

dwayne_johnson

総合スコア86

PostGIS

PostGISは、 PostgreSQLデータベースに地理空間情報を導入するための拡張です。ジオメトリ型、幾何関数、空間インデクスなどの機能が導入され、場所・移動・地域の情報などが扱い易くなります。

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

0グッド

0クリップ

投稿2018/05/27 02:31

編集2018/05/27 03:07

具体的なコード

res = Restaurant.find(1) # Restaurantの中からid: 1のものを取得 r1 = res.location.to_s # res からGeometry型で保存されているlocationカラムを取得し、文字列に # 具体的には、"POINT (139.6479183406 35.5253746419)" a = Station.select("stations.*").where("st_dwithin(location, ?, 5000)", r1).order("st_distance(location, ?)", r1).first

これを実行すると

Station Load (0.9ms) SELECT stations.* FROM "stations" WHERE (st_dwithin(location, 'POINT (139.6479183406 35.5253746419)', 5000)) ORDER BY st_distance(location, ?, 5000), POINT (139.6479183406 35.5253746419) LIMIT $1

となり、ORDER BY st_distance(location, ?, 5000)の箇所の?に、適切に代入されていないことがわかる。

なぜでしょうか?しばらく試行錯誤したのですが、わかりませんでした。。

order の引数に直接文字列を入れると、もちろん動きます。ですので、これはrailsやmodelの問題ではなく、SQL文の書き方に問題があると思われますが、まだあまりSQL文の書き方を分かっておらず、困っています。よろしくお願いします。

-- 追記 --
r1 の部分を、無理やりSQL文内部で展開すると、動きます。

a = Station.select("stations.*").where("st_dwithin(location, ?, 5000)", r1).order("st_distance(location, '#{r1}')").first

しかしこれだと、SQLインジェクション?の問題が起こると思われるので、望ましくありません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

これはrailsやmodelの問題ではなく

残念ながら、普通に.orderで書くと、プレースホルダは使えなさそう、とのことです(StackOverflow)。

なので、Arelを使う(これもこれで面倒&パブリックなAPIではないのでバージョン依存の危険性もあります)、あるいは厳密に値のチェックを行った上で「無理やりSQL文内部で展開する」他なさそうです。

投稿2018/05/27 03:20

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dwayne_johnson

2018/05/28 00:02

うーむ。。 そうなんですね。ありがとうございました。 Arelを使うか検討してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問