以自动方式选择ActiveRecord中连接表的所有列?

时间:2011-05-26 17:25:24

标签: ruby-on-rails activerecord arel

想知道升级到Arel,如果ActiveRecord还支持从连接表中选择列的自动方式,而不必在select子句中明确列出它们。

鉴于我已将users表格加入posts,我希望能够以更简洁的方式执行此类操作:

  scope :select_user,
    select("posts.*, " + User.columns.map{|c| 
      "users.#{c.name} user_#{c.name}"}.join(','))

所以,我想自动从用户中选择字段,以便我说出

Post.joins(:user).select_user.first.user_name

2 个答案:

答案 0 :(得分:3)

我认为如果您想在查询完成后访问关联的属性,那么您实际需要使用includes。所以相同的查询将是

Post.includes(:user).first.user.name

这将导致两个查询,一个select * from users和一个select * from posts where posts.user_id in (id1, id2, id3...)(假设为post belongs_to user),这可能是特定情况下的性能损失,但从语法中可能是值得的立场。在某些情况下,它甚至可能更快Rails :include vs. :joins

如果您向查询添加限制运算符,Arel也会智能地使用join,例如Post.includes(:user).where('users.name = "Bo Bob"')将使用join执行一次查询,并且还可以使用生成的Post对象上的关联。

答案 1 :(得分:1)

如果我理解你的问题,你可以用'加入'来做到这一点:

class Post < ActiveRecord::Base
  belongs_to :user

  scope :select_user, joins(:user).where('users.name = "Mary"')
  ...
end

或使用参数:

class Post < ActiveRecord::Base
  belongs_to :user

  scope :select_user, lambda {|user_name|
    joins(:user).where('users.name = ?', user_name)
  }
  ...
end