Рельсы СОВМЕСТНЫЕ СТОЛЫ - PullRequest
       7

Рельсы СОВМЕСТНЫЕ СТОЛЫ

2 голосов
/ 27 ноября 2008

Я пытаюсь использовать плагин GeoKit, чтобы вычислить расстояние между 2 точками. Итак, идея в том, что я делаю поиск статьи, а результаты хочу упорядочить по расстоянию. Итак, у меня есть форма, в которую я ввожу статью (которую я ищу) и мой адрес. Тогда рельсы должны найти все статьи, которые соответствуют моему запросу и упорядочить по адресу.

Итак, теперь у меня есть две модели: статья и пользователь. Статьи принадлежат пользователю и пользователю has_many. В модели пользователя у меня есть информация, связанная с моей широтой и долготой.

Итак, мой объект Article имеет три поля:

  • ID
  • имя
  • user_id (FK для модели пользователя)

И моя пользовательская модель имеет четыре поля

  • ID
  • имя
  • широта (широта)
  • lng (долгота)

ОК, чтобы получить доступ к информации о пользователях через статьи, я делаю запрос:

@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 => 'ASC расстояния', это терпит неудачу, потому что порядок по запросу использует поля Article.lat и Article.lng для вычисления расстояния, но эти поля lat и lng являются членами объекта User и не член статьи.

Кстати, если я получаю запрос, сгенерированный rails, и я изменяю порядок по пункту, где использует статьи.lat/lng на users.lat/lng, это работает.

Ответы [ 2 ]

4 голосов
/ 27 ноября 2008

Я на самом деле не эксперт по SQL, и мне очень трудно объединить объединения (даже больше, чем вычисление нескольких НЕ как 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?). Расстояние должно быть «названо» с SQL-кодом, например:

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

Таким образом, вы можете ссылаться на расстояние в заказе по выражению, я не думаю, что база данных заботится, если объект ruby ​​ не содержит значения.

Возможно, если бы вы показали нам сгенерированный SQL, который вызывает ошибки, и вы манипулировали SQL, мы могли бы лучше понять ...

1 голос
/ 27 ноября 2008

Я не хотел помещать sql, сгенерированный в первом посте, иначе это было бы слишком много: -)

Я использовал просто include, это работает, но я не знаю почему, include делает левое соединение, и мне нужно внутреннее соединение. Если я удаляю включение, я не могу получить доступ к пользовательской информации через объект article (как, например, article [0] .user.name)

вот это мой sql. если я изменяю порядок по полям article.lat и article.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)

С уважением,

Victor

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...