1

因此,假设我有一个名为 Property 的类,并且我正在使用 PostGIS 适配器来跟踪物理属性(如房子、办公室等)之间的空间关系。我还使用 RGeo gem 来跟踪个人属性的位置。

因此,如果我打电话:

p = Property.first
p.location # => #<RGeo::Geographic::ProjectedPointImpl:0x3f9303eecc3c "POINT (-111.67226 33.231371)">
p.location.latitude # => 33.231371

我在 Property 模型中也有一个自定义方法:

class Property < ActiveRecord::Base
  ...
  def lat
    self[:location].latitude
  end
end

p.lat # => 33.231371

我想创建一个类似于“纬度小于 x”或“经度大于 x”的范围。

但是,如果我在控制台中输入

irb> Property.where("lat > ?", 30)
# => ActiveRecord::StatementInvalid: PG::Error: ERROR:  column "lat" does not exist

如果我尝试一个看起来像这样的范围:

class Property < ActiveRecord::Base
  ...
  scope :lat_lt, lambda {|val| where(['properties.location.latitude <= ?', val]) }
end

然后我得到

irb> Property.lat_lt "30"
# => Property Load (1.3ms)  SELECT "properties".* FROM "properties" WHERE (properties.location.latitude <= '30')
# => ActiveRecord::StatementInvalid: PG::Error: ERROR:  schema "properties" does not exist

所以基本上,“lat”没有列,尽管我可以在 Property 实例上调用 .lat 并获取我需要的信息。现在我只需要能够创建一种通过该返回值来确定范围的方法,即使没有列。

我想了解更多有关其工作原理的信息;ActiveRecord 查询是否在不知道模型上定义的方法的级别上运行,那些在数据库中不存在的方法?

任何和所有的帮助将不胜感激。

4

1 回答 1

1

当您使用where方法(或来自 AR 查询界面的任何其他方法:http: //guides.rubyonrails.org/active_record_querying.html)时,您正在构建一个在需要时执行的 sql 查询。由于您的数据库无法访问您的代码,因此它不知道您定义的方法 - 它只能访问存储在数据库中的内容。

如果您想根据您的自定义方法获取结果,您可以 1. 获取所有属性的列表,然后使用select方法(http://www.ruby-doc.org/core-2.1.0/Array.html )过滤它们#method-i-select ) - 但是这可能会遇到相当严重的性能和资源问题。2.(推荐)弄清楚如何使用纯sql得到你想要的。

如果您可以显示位置如何存储在数据库中,我会尽力提供帮助。

于 2014-01-02T23:44:05.993 回答