Access SQL computed columns through ActiveRecord

痴心易碎 提交于 2019-12-07 08:10:41

问题


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_accessor :age

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


回答1:


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




回答2:


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



来源:https://stackoverflow.com/questions/6741156/access-sql-computed-columns-through-activerecord

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!