Rails范围覆盖select

时间:2012-04-19 21:54:58

标签: mysql ruby-on-rails optimization named-scope

我有一个具有has_many关系的模型,以及一个确定它是否有子节点的范围,例如:

  scope :with_nomination, :include => [:nomination], :conditions => "nominations.service_id IS NOT NULL"

使用此功能,我可以执行Service.with_nomination之类的操作,并获得提名儿童的所有服务列表。

问题在于,当我在essense中执行类似Service.select("id, firstName, lastName").with_nomination ActiveRecord的操作时,SELECT * FROM services非常糟糕,并且没有使用我辛辛苦苦建立的索引。

如何重新编写查询或修改范围以使用.select()命令?

2 个答案:

答案 0 :(得分:0)

在我使用的语法中,选择是不可能的,因此它执行select *并且已经覆盖了任何进一步的选择。

我重新编写了这样的范围:

scope :no_nomination, joins("LEFT JOIN nominations ON nominations.service_id = services.id").where("nominations.service_id IS NULL")
# important distinction here, the left join allows you to find those records without children

scope :with_nomination, joins(:nomination).where("nominations.service_id IS NOT NULL")

使用此语法可以执行Service.select(:id,:user,:otherfield).with_nomination

之类的操作

答案 1 :(得分:0)

8年后...

这很丑陋,但是您也可以使用ActiveRecord::Relation将生成的to_sql转换为sql并使用ActiveRecord::Base.connection.execute手动运行命令。

它可能看起来像这样:

query = Service.select("id, firstName, lastName").with_nomination.to_sql
records = ActiveRecord::Base.connection.execute(query)
records.first["firstName"] # => First Name

这不会消除作用域检索到的多余列,您必须使用字符串键访问每个字段,但是,至少,您仍然可以访问它们!