Поиск людей на расстоянии х миль с помощью сетки и Rails 3.1 - PullRequest
1 голос
/ 10 декабря 2011

Я использую Graticule, чтобы найти людей на расстоянии х миль от события. Мне нужно отправить письмо всем, кто находится в пределах x миль от события.

Вот мой код: -

user.rb

def self.weekly_update
    @users = User.all
    @users.each do |u|
      @events = Event.all_with_distance([u.geo_lat, u.geo_lng]).where("start > ?", Time.zone.now).where("distance < 15")
      UsersMailer.weekly_mail(u.email, @events).deliver
    end
end

def self.all_with_distance(origin)
    distance_sql = sql_for_distance(origin)
    select("#{table_name}.*, #{distance_sql} AS distance").select("`locations`.`geo_lat`, `locations`.`geo_lng`, `locations`.`name` as location_name").joins(:location)
end

geo_search.rb

module GeoSearch
    def sql_for_distance(origin)
      Graticule::Distance::Spherical.to_sql(
        :latitude => origin[0],
        :longitude => origin[1],
        :latitude_column => "`locations`.`geo_lat`",
        :longitude_column => "`locations`.`geo_lng`",
        :units => :kilometers
      )
    end
  end
end

Это ошибка, которую я получаю: -

/usr/local/ruby/lib/ruby/gems/1.9.1/gems/railties-3.1.0/lib/rails/commands/runner.rb:49:in `eval': Mysql2::Error: Unknown column 'distance' in 'where clause': SELECT events.*, (ACOS( SIN(RADIANS(26.8465108)) * SIN(RADIANS(`locations`.`geo_lat`)) + COS(RADIANS(26.8465108)) * COS(RADIANS(`locations`.`geo_lat`)) * COS(RADIANS(`locations`.`geo_lng`) - RADIANS(80.9466832)) ) * 6378.135)  AS distance, `locations`.`geo_lat`, `locations`.`geo_lng`, `locations`.`name` as location_name FROM `events` INNER JOIN `locations` ON `locations`.`id` = `events`.`location_id` WHERE (start > '2011-12-10 10:38:20') AND (distance < 15) (ActionView::Template::Error)

Если я удаляю .where("distance < 15") в .order("distance"), все работает нормально.

1 Ответ

3 голосов
/ 29 декабря 2011

Как в стандартном SQL, так и в диалекте, поддерживаемом MySQL, псевдонимы столбцов нельзя использовать в предложении WHERE;Вы должны использовать столбец.Вот как это будет выглядеть для вашего кода: вызов where в all_with_distance:

select("#{table_name}.*, #{distance_sql} AS distance")
    .select("`locations`.`geo_lat`, `locations`.`geo_lng`, `locations`.`name` as location_name")
    .joins(:location)
    .where("#{distance_sql} < 50")
...