2015-05-03 3 views
2

Использование AS оператора SQL, мы можем создать ActiveRecord атрибуты, которые не соответствуют реальному столбцу в нашей базе:Создание ActiveRecord атрибутов без переопределения выберите

user = User.select(<<-SQL).first 
    *, CONTACT(first_name, ' ', last_name) AS full_name 
SQL 

user.full_name => "Bob Nastanovich" 

Моя проблема состоит в том, что * необходимо. Я пишу расширение AR, которое будет добавить виртуальных атрибутов для результата вычисления SQL, но включая * означает, что пользователь никогда не сможет сузить возвращаемые атрибуты с помощью метода select.

Есть ли способ добавить «вычисленные» атрибуты каким-либо другим способом, чем select, что также гарантирует, что вся работа выполняется базой данных? Я не собираюсь перебирать результаты после запроса. Мой пример был очень прост по назначению, фактическая реализация включает вычисления на JOIN.

Мне ничего не удалось найти, поэтому я скептически отношусь, но я думал, что попрошу!

+1

Возможно, вы могли бы переопределить 'ActiveRecord :: Relation # exec_queries', а затем проверить, не содержит ли' isl.projections' ничего, кроме вашего либрара y, а затем добавить '*' к проекциям, если нет. –

+0

Это, вероятно, будет очень сильно зависеть от версии Rails. –

+1

Эй, это действительно интересно. Определенно не чистое или идеальное решение - тем более, что вычисленные атрибуты имеют имена переменных (ну, полупеременные), но я собираюсь поиграть с этим и сообщить вам, как это происходит. Я уже начал копаться в источнике AR, и это ускорило меня очень много. Благодаря! –

ответ

0

Вы можете сделать то же самое, просто выбрав только одно поле (любое поле будет делать):

> user = User.select(<<-SQL).first 
> id, CONTACT(first_name, ' ', last_name) AS full_name 
> SQL 

> user.full_name 
=> "Bob Nastanovich" 

> user 
    => #<User id: 176488> 

> user.attributes 
=> {"id"=>176488, "full_name"=>"Bob Nastanovich"} 

EDIT

Запрос работает для меня без *, а также:

> user = User.select(<<-SQL).first 
> CONTACT(first_name, ' ', last_name) AS full_name 
> SQL 

> user.full_name 
=> "Bob Nastanovich" 

> user 
    => #<User id: nil> 

> user.attributes 
=> {"full_name"=>"Bob Nastanovich", "id"=>nil} 
+0

Как я уже говорил, это будет расширение AR, то есть оно будет в библиотечном коде. Я хочу добавить вычисляемые атрибуты SQL, но также разрешить пользователю использовать 'select'. Если в коде библиотеки есть 'select (" * ")', метод select становится бесполезным для пользователя (кроме добавления других вычисленных полей). –

+0

Без '*' объект будет * только * содержать вычисленные атрибуты. –

Смежные вопросы