ActiveRelation将如何影响rails的includes()的功能?

时间:2010-05-20 01:33:59

标签: ruby-on-rails ruby activerecord active-relation

我查看了Arel源代码,以及Rails 3.0的一些活动记录源,但我似乎无法为自己找到一个好的答案,因为Arel是否会改变我们使用include()的能力,在构建查询时,为了更好。

有些人可能想要修改activerecord上的条件:在2.3.5及之前包含查询,以获取将返回的关联记录。但据我所知,这在所有方面都不具备成功:包含查询:

(我知道一些AR-find-includes make t#{n} .c#{m}重命名所有属性,可以想象为这些查询添加条件以限制连接集的结果;但是其他人做n_joins迭代地在id集上进行+ 1次查询,我不确定如何破解AR来编辑这些迭代查询。)

Will Arel是否允许我们构建ActiveRecord查询,在使用includes()时指定生成的关联模型对象?

例如:

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 个答案:

答案 0 :(得分:4)

为什么不实际使用AREL作为核心。一旦你到达实际的表范围,你可以使用Arel :: Relation,它完全不同于ActiveRecord实现本身。我真的相信ActiveRecord :: Relation是围绕Arel :: Relation& amp的包装器的完全不同(并且被破坏)的实现。阿雷尔::表。我选择使用Arel作为核心,通过Thing.scoped.table(Arel :: Table)这是活动的记录样式OR 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从集合返回一个元组的TRUE定义,该集合将包含Arel :: Header(Arel :: Attributes集合)和元组。

同样稍微冗长一点,我之所以使用Arel是因为它真正将关系模型暴露给我,这是ActiveRelation背后的力量。我注意到ActiveRecord暴露出类似于Arel所提供的20%,我担心开发人员不会意识到这个NOR他们会理解关系代数的真正核心。使用条件哈希对我来说是“旧学校”和关系代数世界中的ActiveRecord风格编程。一旦我们学会摆脱基于Martin Fowler模型的方法并采用基于E.F.Codd关系模型的方法,这实际上是RDBMS几十年来一直试图做的但是却非常错误。

我冒昧地为红宝石社区开始了关于Arel和Relational Algebra的七部分学习系列。这些视频将包括从绝对初学者到高级技术的短视频,例如自我引用关系和组合下的闭包。第一个视频位于http://Innovative-Studios.com/#pilot如果您需要更多信息,请告知我们,或者这对您来说不够具有描述性。

Arel看起来很光明。

答案 1 :(得分:3)

ActiveRecord :: Relation是一个围绕Base#find_by_sql的相当弱的包装器,因此:include查询不会以任何方式扩展。

答案 2 :(得分:1)

Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all
你正在寻找什么? (取自官方docs