开发者

Access SQL computed columns through ActiveRecord

I have a Person model, which includes a property representing the data of birth (birth_date).

I also have a method called age(), which works out the current age of the person.

I now have need to run queries based on the person's age, so I have replicated the logic of age() as a computed column in MySQL.

I cannot workout how I would make this additional column part of the default select statement of the model.

I would like to be able to access the age as if it were a native property of the Person model, to perform queries against it and access the value in my views.

Is this possible, or am barking up the wrong tree?

I thought I might be able to define additional fields through default_scope or scope, but these methods seem to only recognise existing fields. I also tried default_scope in tandem with attr_assessor.

Possible workarounds I've considered but would prefer not to do:

  • Create an actual property called age and populate through the use of callbacks. The date is always changing, so this obviously would be be reliable.

  • Replicate the logic in ActiveRecord as age() and in a scope as a where cause. This would achieve what I need, but doesn't feel very DRY.

  • I am already caching the results of the age() method. it is the ability to use the field in where clauses that I am most interested in.

There must be a way to define dynamic fields through SQL that I can access through the model by default.

Any help would be appreciated.

Rich

UPDATE

An example of my failed attempt to utilise scopes:

default_scope :select => "*, 2 as age"

attr_ac开发者_开发问答cessor :age

age is blank, I assume because scopes only deal with limiting, not extending.


kim3er your solution to your problem is simple. Follow these steps:

Loose the attr_accessor :age from your model. You simply don't need it.

Leave the default scope at the Person model: default_scope :select => "*, 2 as age"

Lastly open up a console and try

p = Person.first
p.age
=> 2

When you define a select using as, Rails will automagically add those methods on the instances for you! So the answer to your question:

There must be a way to define dynamic fields through SQL that I can access through the model by default.

is:

Rails


I'm not an expert by any stretch, but it seems you want:

class Person < ActiveRecord::Base

scope :exact_age, lambda { |a| where('age = ?', a) }
scope :age_gt, lambda { |a| where('age > ?', a) }

but that said, I've just started looking at Arel, seems pretty cool

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜