我正在尝试使用自定义查询的结果(两个地理点之间的距离)作为模型属性。最终目标是能够使用该列过滤和排序行,例如:
Model.with_distance(point).order(:distance).first
我最初认为我可以在范围内使用 select
;这是一个没有 sanitizer 的较短版本:
scope :with_distance, ->(point) { select("ST_DISTANCE(models.point_in_model, ST_GeographyFromText('#{point.to_s}')) AS distance") }
但是,该范围仅选择 distance
列,而不检索模型属性:
> Model.with_distance(point)
[#<Model >, #<Model >,...]
将 models.*
添加到 select
调用可以解决问题,但代价是在每个查询中强制检索整行并忽略其他 select
调用。
如何添加 SELECT 子句而不是替换所有子句?
最佳答案
除了默认的 SELECT 模型。*
,ActiveRecord 通常添加 SELECT 子句,而不是替换它们。
> Project.select(:id).select(:name)
=> Project Load (0.5ms) SELECT id, name FROM "projects"
显然,当您想要“默认 SELECT 以及我要求的任何其他选择”时,这无济于事。
您可以尝试使用 select_star
范围
scope :select_star, -> { select("models.*") }
scope :select_star, -> { select(self.arel_table[Arel.star]) } # Arel version, if feeling adventurous
您可以在需要所有列的地方使用它吗?
> Model.with_distance(point).select_star
=> SELECT ST_DISTANCE(models.point_in_model, ST_GeographyFromText('0,0')) AS distance, models.* FROM ...
关于ruby-on-rails - 在 ActiveRecord 3 中添加自定义 SELECT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28836479/