Как ActiveRelation повлияет на возможности rails 'includes ()? - PullRequest
7 голосов
/ 20 мая 2010

Я просмотрел исходники Arel и некоторые источники activerecord для Rails 3.0, но я не могу найти для себя хорошего ответа относительно того, изменит ли Arel нашу способность использовать include (),при построении запросов, к лучшему.

Существуют случаи, когда кто-то может захотеть изменить условия на activerecord: включить запрос в 2.3.5 и ранее для записей ассоциации, которые будут возвращены.Но, насколько я знаю, это не подходит для всех программ: include запросы:

(я знаю некоторые AR-find-include, которые make t # {n} .c # {m} переименовывает для всех атрибутов,и можно предположительно добавить условия к этим запросам, чтобы ограничить результаты объединенных наборов, но другие делают n_joins + 1 количество запросов по наборам идентификаторов итеративно, и я не уверен, как можно взломать AR для редактирования этих итеративных запросов.)

Будет ли Arel позволять нам создавать запросы ActiveRecord, которые определяют результирующие связанные объекты модели при использовании include ()?

Пример:

User :has_many posts( has_many :comments)

User.all(:include => :posts) #say I wanted the post objects to have their 
 #comment counts loaded without adding a comment_count column to `posts`.

#At the post level, one could do so by: 
posts_with_counts = Post.all(:select => 'posts.*, count(comments.id) as comment_count', 
         :joins => 'left outer join comments on comments.post_id = posts.id',
         :group_by => 'posts.id') #i believe

#But it seems impossible to do so while linking these post objects to each 
  #user as well, without running User.all() and then zippering the objects into 
  #some other collection (ugly) 
  #OR running posts.group_by(&:user) (even uglier, with the n user queries)

Ответы [ 3 ]

4 голосов
/ 21 мая 2010

Почему бы вам не использовать AREL по своей сути. Как только вы перейдете к реальной области таблицы, вы можете использовать Arel :: Relation, который ПОЛНОСТЬЮ отличается от самой реализации ActiveRecord. Я искренне верю, что ActiveRecord :: Relation является ПОЛНОСТЬЮ другой (и отключенной) реализацией оболочки вокруг Arel :: Relation & Arel :: Table. Я решил использовать Arel в своей основе, либо выполнив Thing.scoped.table (Arel :: Table), который является стилем активной записи, ИЛИ Arel :: Table.new (: table_name), который дает мне свежий Arel :: Table (мой предпочтительный метод). Из этого вы можете сделать следующее.

posts = Arel::Table.new(:thing, :as => 'p') #derived relation
comments = Arel::Table.new(:comments, :as => 'c') # derived relation
posts_and_comments = posts.join(comments).on( posts[:id].eq(:comments[:id]) )

# now you can iterate through the derived relation by doing the following
posts_and_comments.each {...} # this will actually return Arel::Rows which is another story.  
#

Arel :: Row возвращает ИСТИННОЕ определение кортежа из набора, который будет состоять из Arel :: Header (набор Arel :: Attributes) и кортежа.

Также немного более многословно, причина, по которой я использую Arel в своей основе, заключается в том, что он действительно предоставляет мне реляционную модель, которая является силой ActiveRelation. Я заметил, что ActiveRecord демонстрирует примерно 20% от того, что может предложить Арель, и я боюсь, что разработчики не поймут этот NOR, если они поймут истинное ядро ​​реляционной алгебры. Использование хэша условий для меня - «старая школа» и программирование в стиле ActiveRecord в мире реляционной алгебры. Как только мы научимся отрываться от подхода, основанного на модели Мартина Фаулера, и принять подход, основанный на реляционной модели Э. Ф. Кодда, на самом деле это то, что СУБД пытались сделать десятилетиями, но ошиблись.

Я позволил себе начать серию из семи частей по Арелю и Реляционной Алгебре для сообщества рубинов. Они будут состоять из коротких видеороликов, начиная от абсолютного новичка до продвинутых техник, таких как отношения со ссылками на себя и замыкание в композиции. Первое видео на http://Innovative -Studios.com / # pilot Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, или она не достаточно описательна для вас.

Будущее выглядит ярко с Арелом.

3 голосов
/ 31 мая 2010

ActiveRecord :: Relation - довольно слабая оболочка для Base # find_by_sql, поэтому: включаемые запросы не расширяются никаким образом при включении.

1 голос
/ 07 февраля 2011

Не

Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all

что ты ищешь? (взято из официальных документов )

...