在使用activeRecord的Rails中,为什么连接查询被认为是错误的。
例如
我在这里试图找到属于某个类别的公司数量。
class Company ActiveRecord::Base
has_one :company_profile
end
Finding the number of Company for a particular category_id
number_of_companies = Company.find(:all, :joins=>:company_profile, :conditions=>["(company_profiles.category_id = #{c_id}) AND is_published = true"])
How could this be better or is it just poor design?
company_profiles = CompanyProfile.find_all_by_category_id(c_id)
companies = []
company_profiles.each{|c_profile| companies.push(c_profile.company) }
第一个请求在为第二个案例运行多个查询时创建单个查询是不是更好。
有人可以解释为什么连接在Rails中被认为是不好的做法
提前致谢
答案 0 :(得分:1)
据我所知,没有这样的规则。规则是尽可能少地访问数据库,rails使用连接为您提供正确的工具。
Sam上面给出的例子是示例性的。简单的代码,但在幕后,rails必须做两个查询,而不是只有一个使用连接。
如果有一个规则浮现在脑海中,我认为是相关的,就是尽可能避免使用SQL并尽可能地使用rails方式。这使您的代码数据库不可知(因为rails会为您处理差异)。但有时即使这是不可避免的。
归结为良好的数据库设计,创建正确的索引(需要在迁移中手动定义),有时需要大的嵌套结构/连接。
答案 1 :(得分:1)
加入查询并不坏,事实上,它们很好,ActiveRecord就是它的核心。你不需要闯入find_by_sql来使用它们,像:include这样的选项会为你处理它。你可以留在ORM中,这提供了可读性和易用性,同时在大多数情况下,仍然可以创建非常高效的SQL(提供正确的索引!)
底线 - 您需要完成最少的数据库操作。连接是让数据库为您完成繁重工作并降低执行查询数量的好方法。
通过,DataMapper和Arel(Rails 3中的查询引擎)具有很多延迟加载功能 - 这意味着代码如:
@category = Category.find(params[:id])
@category.companies.size
最有可能导致只执行COUNT操作的连接查询,因为第一行不会导致查询被发送到数据库。
答案 2 :(得分:0)
如果您只想查找某个类别的公司数量,您需要查找该类别,然后调用关联名称和大小,因为它将返回一个数组。
@category = Category.find(params[:id])
@category.companies.size