rails选择并包含

有谁能解释一下?

Project.includes([:user, :company]) 

这将执行3个查询,一个用于获取项目,一个用于获取这些项目的用户,另一个用于获取公司。

 Project.select("name").includes([:user, :company]) 

这将执行3个查询,并完全忽略选择位。

 Project.select("user.name").includes([:user, :company]) 

这将使用适当的左连接执行1个查询。 并且仍然完全忽略了选择。

在我看来,rails忽略带包含的select。 好的,但是为什么当我在select中放入一个相关的模型时,它会从发出3个查询切换到发出1个查询?

请注意,1查询是我想要的,我无法想象这是获取它的正确方法,也不是它的工作原理,但我不确定如何在一个查询中获得结果(.joins似乎只是使用我实际上并不想要的INNER JOIN,当我手动指定连接条件为.joins搜索gem时,我们正在尝试重新添加具有相同名称的连接。

我和select和includes有同样的问题。 为了热切加载相关模型,我使用了原生的Rails范围’preload’http: //apidock.com/rails/ActiveRecord/QueryMethods/preload它提供了急切的加载而没有在范围链上跳过’select’。

我在这里找到了它https://github.com/rails/rails/pull/2303#issuecomment-3889821

希望这个提示对某些人有用,因为它对我有帮助。

好吧,所以这就是我想出来的……

 .joins("LEFT JOIN companies companies2 ON companies2.id = projects.company_id LEFT JOIN project_types project_types2 ON project_types2.id = projects.project_type_id LEFT JOIN users users2 ON users2.id = projects.user_id") \ .select("six, fields, I, want") 

工作,屁股的痛苦,但它只是我在一个查询中需要的数据。 唯一糟糕的部分是因为我们正在使用meta_search,所以我必须给出一切model2别名,当你指定自己的连接条件时,似乎无法弄清楚表已经加入了。

当使用includeincludes时,Rails总是忽略select参数。 如果要使用select参数,请改用joins

您可能遇到了正在讨论的查询gem的问题,但您也可以使用连接方法包含sql片段。

 Project.select("name").joins(['some sql fragement for users', 'left join companies c on c.id = projects.company_id']) 

我不知道你的架构,所以我不得不猜测确切的关系,但这应该让你开始。

我可能在这里完全遗漏了一些东西,但是selectinclude不是ActiveRecord的一部分。 做你想做的事情的通常方法是这样的:

 Project.find(:all, :select => "users.name", :include => [:user, :company], :joins => "LEFT JOIN users on projects.user_id = users.id") 

有关更多示例,请查看api文档 。 偶尔我不得不去手动并使用find_by_sql

 Project.find_by_sql("select users.name from projects left join users on projects.user_id = users.id") 

希望这会指出你正确的方向。

我自己想要这个function,所以请使用它。 在您的课程中包含此方法

#ACCEPTS args采用字符串格式“ASSOCIATION_NAME:COLUMN_NAME-COLUMN_NAME”

 def self.includes_with_select(*m) association_arr = [] m.each do |part| parts = part.split(':') association = parts[0].to_sym select_columns = parts[1].split('-') association_macro = (self.reflect_on_association(association).macro) association_arr << association.to_sym class_name = self.reflect_on_association(association).class_name self.send(association_macro, association, -> {select *select_columns}, class_name: "#{class_name.to_sym}") end self.includes(*association_arr) end 

您可以调用如下:Contract.includes_with_select(’user:id-name-status’,’confirmation:confirmed-id’),它将选择那些指定的列。