私は仮想属性のようなものを求めていますが、それはデータベースレベルで機能します。たとえば、フィールドがあり、に等しい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またはgemでそれを行う方法はありますか?
アップデート
モデルでそのような属性を宣言し、提案されているように、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);