是否可以在与SQL表达式对应的activerecord中定义虚拟属性?

时间:2013-10-11 15:00:55

标签: ruby-on-rails activerecord

我正在使用类似虚拟属性的东西,但这可以在数据库级别上工作:说我有一个字段age,我想添加一个“虚拟字段”age_quintile等于{ {1}},但是可以这样说:

age/5

对应于:

Person.select(:age_quintile,"agv(height)").
  group(:age_quintile).
  order(:age_quintile)

  SELECT (age/5) as age_quintile, avg(height) 
    FROM persons 
GROUP BY (age/5) 
ORDER BY (age/5);

对应

Person.maximum(:age_quintile)

所以,我想我会在模型中声明这样的属性,如:

SELECT max(age/5) 
  FROM persons;

其中最后一位是SQL表达式,并且从字符串转换需要类型。

有没有办法用vanilla ActiveRecord或某些宝石做到这一点?

更新

希望在模型中声明此类属性的原因,而不是 - 如建议的那样 - 在select中使用别名表达式是我们希望属性参与通用查询API并且对API的用户显示为任何其他属性。所以以下内容应该是可能的:

class Person < ActiveRecord::Base
  ...
  magic_attribute :age_quintile, :integer, 'age/5'

end

和查询字符串class PeopleController < ApplicationController def search group_columns = params[:group].split(" ") # age_quintile could be one of measurements = params[:measurements].split(" ") # height could be one of aggregates = %w[min avg max] select_columns = measurement.map{|m| aggregates.map{|fn| "#{fn}(#{m})"} }.flatten render :json => Person. select( group_columns + select_columns ). group(group_columns). search(group_columns) end end 将导致:

?group=age_quintile&measurements=height

1 个答案:

答案 0 :(得分:3)

这是可能的。更重要的是,它由ActiveRecord自动完成:

@people = Person.
  select('(age/5) as age_quintile, height').
  group(:age_quintile).
  order(:age_quintile)
person = @people.first
person.age_quintile
# => age_quintile value (person.age / 5)