2008-11-27 48 views
2

我正在嘗試使用GeoKit插件來計算2點之間的距離。所以我的想法是,我搜索一篇文章,並且我想按距離排序。所以我有一個表格,我輸入文章(即時通訊尋找)和我的地址。然後,rails必須找到與我的查詢匹配的所有文章並按地址排序。Rails JOIN TABLES

所以現在,我有兩個模型:文章和用戶。文章belongs_to用戶和用戶has_many文章。在用戶模型中,我有與我的經度和緯度相關的信息。

所以我的文章對象有三個字段:

  • ID
  • USER_ID(FK到用戶模式)

而且我的用戶模型有四個字段

  • id
  • 緯度(北緯)
  • LNG(經度)

OK,有機會獲得直通文章的用戶信息我做查詢:

@articles = Article.find(:all,:conditions=>"vectors @@ to_tsquery('büch')",:joins=>" INNER JOIN users ON users.id = articles.user_id",:include=>:user,:origin=>"Augustusplatz,8,leipzig,germany") 

它的工作原理。但是當我想添加:order =>'distance ASC'時,它失敗了,因爲按查詢順序使用Article.lat和Article.lng字段來計算距離,但是這些字段lat和lng是用戶對象的成員和不是文章會員。

順便說一句,如果我得到的軌道生成的查詢,我改變了order by子句where articles.lat/lng給users.lat/lng它的工作原理。

回答

4

我不是一個真正的SQL專家,我覺得加入很難繞到我的頭(甚至超過搞清楚多個NOT的像if(!(foo != !bar & (!baz)))),但我覺得,無論是:joins線或:include線是多餘的,甚至是錯誤的。

(我清理您的查詢,所以我能理解它,請不要與問題相同):

@articles = Article.find(:all, 
    :conditions=>"vectors @@ to_tsquery('büch')", 
    :joins=>" INNER JOIN users ON users.id = articles.user_id", 
    :include=>:user, 
    :origin=>"Augustusplatz,8,leipzig,germany") 

我想無論是用戶和物品的模型應該明確自己的關係,所以你不要不需要手動加入或刪除包含。

但我沒有看到從這段代碼實際計算距離(可能是GeoKit中的某些automagic?)。距離應被「點名」與SQL成才這樣的:

SELECT (some_heavy_calculation(user.lat, user.long)) AS distance, ... ; 

所以,你可以通過條款指的距離的順序,我不認爲數據庫在乎如果紅寶石對象不包含該值。

也許如果你向我們展示了生成的SQL,這會導致錯誤,並且你操作了SQL,我們可以更好地理解...

1

我沒有想擺在第一篇文章中生成的SQL否則將太多的事情:-)

我只使用包括這樣的作品,但我不知道爲什麼,包括使左連接,我需要一個內部連接。如果我刪除包含我不能通過文章對象訪問用戶信息(例如文章[0] .user.name)

這裏是我的SQL。如果我的順序由場articles.lat和articles.lng改變users.lat和user.lng它的工作原理:

SELECT "articles"."id" AS t0_r0, "articles"."name" AS t0_r1, "articles"."price" AS t0_r2, "articles"."user_id" AS t0_r3, "articles"."created_at" AS t0_r4, "articles"."updated_at" AS t0_r5, "articles"."vectors" AS t0_r6, "users_articles"."id" AS t1_r0, "users_articles"."name" AS t1_r1, "users_articles"."address" AS t1_r2, "users_articles"."created_at" AS t1_r3, "users_articles"."updated_at" AS t1_r4, "users_articles"."lat" AS t1_r5, "users_articles"."lng" AS t1_r6, "users_articles"."zipcode" AS t1_r7 FROM "articles" LEFT OUTER JOIN "users" users_articles ON "users_articles".id = "articles".user_id  INNER JOIN users ON users.id = articles.user_id WHERE (vectors @@ to_tsquery('büch')) ORDER BY     (ACOS(least(1,COS(0.896021391737553)*COS(0.216084610510851)*COS(RADIANS(articles.lat))*COS(RADIANS(articles.lng))+ 
       COS(0.896021391737553)*SIN(0.216084610510851)*COS(RADIANS(articles.lat))*SIN(RADIANS(articles.lng))+ 
       SIN(0.896021391737553)*SIN(RADIANS(articles.lat))))*3963.19) 

問候,

維克多