使用经纬网和Rails 3.1在x英里的范围内寻找人

时间:2011-12-10 10:41:54

标签: google-maps-api-3 ruby-on-rails-3.1 distance

我正在使用Graticule寻找离事件x英里的人。我需要向距离活动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 个答案:

答案 0 :(得分:3)

在标准SQL和MySQL支持的方言中,column aliases不能用于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")