问题
I'm after something like virtual attribute, but that would work on the database level: say I have a field age
and I would like to add a "virtual field" age_quintile
which equals age/5
, but in such a way that it is possible to say:
Person.select(:age_quintile,"agv(height)").
group(:age_quintile).
order(:age_quintile)
corresponding to:
SELECT (age/5) as age_quintile, avg(height)
FROM persons
GROUP BY (age/5)
ORDER BY (age/5);
or
Person.maximum(:age_quintile)
corresponding to
SELECT max(age/5)
FROM persons;
So, I imagine I would declare such attributes in the model, like:
class Person < ActiveRecord::Base
...
magic_attribute :age_quintile, :integer, 'age/5'
end
where the last bit is an SQL expression and type is necessary for casting from strings.
Is there a way to do that with vanilla ActiveRecord or with some gem?
Update
The reason for wishing to declare such attributes in the model, and not - as suggested - use an aliased expression verbatim in select is that we would like the attributes participate in a generic query API and appear to the user of the API as any other attribute. So the following should be possible:
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
and a query string ?group=age_quintile&measurements=height
would result in:
SELECT (age/5) as age_quintile, min(height), avg(height), max(height)
FROM persons
GROUP BY (age/5)
ORDER BY (age/5);
回答1:
It's possible. What's more, it is done automatically by 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)
来源:https://stackoverflow.com/questions/19321340/is-it-possible-to-define-virtual-attributes-in-activerecord-corresponding-to-sql