我有一个具有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()命令?
答案 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
这不会消除作用域检索到的多余列,和您必须使用字符串键访问每个字段,但是,至少,您仍然可以访问它们!