Доступ к вычисляемым столбцам SQL через ActiveRecord - PullRequest
4 голосов
/ 19 июля 2011

У меня есть модель Person, которая включает свойство, представляющее данные о рождении (birth_date).

У меня также есть метод с именем age(), который определяет текущий возраст человека.

Теперь мне нужно выполнить запросы, основанные на возрасте человека, поэтому я скопировал логику age() как вычисляемый столбец в MySQL.

Я не могу понять, как сделать этот дополнительный столбец частью оператора выбора модели по умолчанию.

Я бы хотел иметь возможность доступа к возрасту, как если бы он был нативным свойством модели Person, для выполнения запросов к нему и доступа к значению в моих представлениях.

Возможно ли это, или я лаю не на том дереве?

Я думал, что смогу определить дополнительные поля с помощью default_scope или scope, но эти методы, похоже, распознают только существующие поля. Я также пытался default_scope в тандеме с attr_assessor.

Возможные обходные пути, которые я рассмотрел, но предпочел бы не делать:

  • Создайте фактическое свойство с именем age и заполните его с помощью обратных вызовов. Дата всегда меняется, так что это, очевидно, будет надежным.

  • Реплицируйте логику в ActiveRecord как age() и в области действия как причину. Это дало бы то, что мне нужно, но не очень сухо.

  • Я уже кеширую результаты метода age(). это возможность использовать поле, в котором пункты, которые меня больше всего интересуют.

Должен быть способ определения динамических полей через SQL, к которому я могу получить доступ через модель по умолчанию.

Буду признателен за любую помощь.

Rich

UPDATE

Пример моей неудачной попытки использовать области действия:

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

attr_accessor :age

age пусто, я полагаю, потому что области охватывают только ограничение, а не расширение.

Ответы [ 2 ]

2 голосов
/ 23 июля 2011

kim3er Ваше решение вашей проблемы простое. Выполните следующие действия:

Освободите attr_accessor :age от вашей модели. Вам это просто не нужно.

Оставьте область по умолчанию для модели Person: default_scope :select => "*, 2 as age"

Наконец, откройте консоль и попробуйте

p = Person.first
p.age
=> 2

Когда вы определяете select, используя as, Rails автоматически добавит эти методы в экземпляры для вас! Итак, ответ на ваш вопрос:

Должен быть способ определения динамических полей через SQL, к которому я могу получить доступ через модель по умолчанию.

есть:

Рельсы

1 голос
/ 27 июля 2011

Я ни в коем случае не эксперт, но, кажется, вы хотите:

class Person < ActiveRecord::Base

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

но это сказал, я только начал смотреть на Арель , кажется довольно круто

...