Rails 3.1中的嵌套作用域

时间:2011-11-19 15:22:55

标签: ruby-on-rails ruby-on-rails-3 scope nested named-scope

有没有办法可以将以下代码中的to_be_approved by方法转换为使用其他两个范围的范围?

scope :reports_to, lambda { |manager| 
  joins(" JOIN admin_users request_user on requests.admin_user_id = request_user.id and request_user.manager_id = #{manager.id} ") }
scope :pending, joins(:admin_request_status).where('admin_request_statuses.name = ?','Pending Approval')

def self.to_be_approved_by( manager )
  reports_to(manager).pending
end

我也想摆脱reports_to范围内的嵌入式sql,但这是一个完全不同的问题:)

1 个答案:

答案 0 :(得分:10)

scope :reports_to, lambda { |manager| joins(:admin_user).where('admin_users.manager_id = ?',manager.id) }  
scope :pending, joins(:admin_request_status).where('admin_request_statuses.name = ?','Pending Approval')
scope :to_be_approved_by, lambda { |manager| self.pending.reports_to(manager) }
end

所有人都要注意。

这样的链接范围通常在性能上是正确的,因为在示例中调用整个范围链之前不会评估“外部”或“初始”范围(例如scope_name1.scope_name2.scope_name3等,并且仅在构造sql需要实际输出。这被称为“延迟加载”,例如'懒惰,在实际需要之前不构建结果'。

这与“急切加载”相反,你使用:include语句获取其他表并“一次性”进行多次查询,避免臭名昭着的“n + 1”问题程序最终执行(例如)101查询以获得100条记录。

很多有趣的信息:)