1

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

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

使用它,我可以做类似的事情,Service.with_nomination并收到一份包含提名儿童的所有服务的清单。

问题是,当我Service.select("id, firstName, lastName").with_nomination在 essense 中执行 ActiveRecord之类的操作时,这样做SELECT * FROM services非常糟糕,并且没有使用我煞费苦心设置的索引。

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

4

2 回答 2

0

结果在我使用的语法中,选择是不可能的,所以它做了一个选择 * 并且任何进一步的选择都已经被覆盖了。

我像这样重写了范围:

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

于 2012-04-19T23:44:34.710 回答
0

8年后...

这很难看,但您也可以将结果ActiveRecord::Relation转换为 sqlto_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

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

于 2020-12-02T22:34:08.027 回答