我追求的是虚拟属性之类的东西,但这将在数据库级别上起作用:假设我有一个字段age
,我想添加一个age_quintile
等于的“虚拟字段” 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;
所以,我想我会在模型中声明这样的属性,比如:
class Person < ActiveRecord::Base
...
magic_attribute :age_quintile, :integer, 'age/5'
end
其中最后一位是 SQL 表达式,并且类型对于从字符串进行转换是必需的。
有没有办法用香草 ActiveRecord 或一些宝石来做到这一点?
更新
希望在模型中声明这些属性,而不是像建议的那样在 select 中逐字使用别名表达式的原因是,我们希望属性参与通用查询 API,并像任何其他属性一样呈现给 API 的用户. 所以以下应该是可能的:
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
将导致:
SELECT (age/5) as age_quintile, min(height), avg(height), max(height)
FROM persons
GROUP BY (age/5)
ORDER BY (age/5);