1
我有一个事件模型。并且此事件模型has_one地址模型。用户模型也有一个地址模型。我想在将来获取所有事件的列表,但是根据事件地址和用户地址之间的距离进行排序。这个“距离”是我的地址模型中的一种方法。我如何写活动记录的轨道查询?我已经尝试了以下的许多变体,但似乎没有任何工作。Rails根据与子模型方法的关联对结果进行排序
Event.where('end_time > ?', Time.now).includes(Address).order(address.distance_from(User.find(3).primary_address))
我总是得到这样的错误:NameError:未定义的局部变量或方法'地址主:对象
事件的定义和用户:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
has_many :addresses
belongs_to :primary_address, :class_name => "Address"
class Event < ActiveRecord::Base
extend TimeFromPieces
attr_accessor :start_date_string
belongs_to :address
delegate :timezone, to: :address
这里是我的地址模型:
class Address < ActiveRecord::Base
belongs_to :user
has_many :events
validates_presence_of :name, :address1, :city, :state, :zip
geocoded_by :address_as_string do |obj, results|
Rails.logger.debug { "results: #{results}" }
obj.lat = results.first.coordinates[0]
obj.lng = results.first.coordinates[1]
Rails.logger.debug { "Neighborhoods: #{results.first.address_components_of_type(:neighborhood)}" }
neighborhoods = results.first.address_components_of_type(:neighborhood)
if neighborhoods.count > 1
obj.neighborhood = neighborhoods.first["long_name"]
end
end
after_validation :geocode, :if => :address1_changed?
after_validation :time_zone_for_address, :if => :address1_changed?
before_save :set_primary_if_only_address_for_user
before_save :normalize_fields
scope :near, ->(lat, lng, distance_in_meters = 2000) {
where(%{
ST_Dwithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || addresses.lng || ' ' || addresses.lat || ')'
),
ST_GeographyFromText('SRID=4326;POINT(%f %f)'),
%d
)
} % [lng, lat, distance_in_meters])
}
def self.distance(address1, address2)
query = %{ SELECT
ST_Distance(
ST_GeographyFromText('SRID=4326;POINT(%f %f)'),
ST_GeographyFromText('SRID=4326;POINT(%f %f)')
)
} % [address1.lng, address1.lat, address2.lng, address2.lat]
meters = ActiveRecord::Base.connection.execute(query).values.first.first.to_i
meters/1609.34
end
def distance_from(address)
Address.distance(self, address)
end
end
什么是提供'geocoded_by'的gem? – 2015-04-04 19:26:36
有一点需要注意的是,你被“铁轨魔术”所迷惑了。如果你仔细看看你的代码的这一部分:.order(address.distance_from(User.find(3).primary_address)),你会看到你的错误来自哪里。我猜测变量地址不在范围内。 – digidigo 2015-04-04 21:34:20
你也不能像你在做的那样将ruby代码传递到ActiveRecord方法链中。这可能需要适配器作为SQL查询的一部分执行ruby。这将是超级酷!正如@MohammadAbuShady在这里指导你们一样,用地理能力来扩展AR的宝石是这里的一种方式。 – digidigo 2015-04-04 21:37:45