:包含和表别名

时间:2010-06-02 21:42:33

标签: ruby-on-rails

我患有the problem described here的变体:

  

ActiveRecord为其分配表别名   协会公平地加入   不可预知的。第一个协会   到给定的表保留表   名称。进一步加入协会   到该表使用别名包括   路径中的关联名称......   但它对应用程序开发人员来说很常见   不知道[其他]加入   编码时间。

在我的情况下,我被has_many和include的有毒混合物所咬。我的架构中的许多表都有state列,而has_many想要在该列上指定条件:has_many :foo, :conditions => {:state => 1}。但是,由于状态列出现在许多表中,因此我通过显式指定表名来消除歧义:has_many :foo, :conditions => "this_table.state = 1"

到目前为止,这种方法运行良好,为了提高效率,我想添加:include来预加载相当深的数据树。这会导致表在不同的代码路径中不一致地出现别名。我对上面引用的票证的解读是这个问题不是也不会在Rails 2.x中修复。但是,我没有看到任何方法来应用建议的解决方法(在查询中明确指定别名表名称)。我很高兴在has_many语句中明确指定表别名,但我没有看到任何方法这样做。因此,解决方法似乎不适用于这种情况(我认为,在许多'named_scope'方案中)也不适用。

是否有可行的解决方法?

3 个答案:

答案 0 :(得分:3)

而不是使用:include,使用:joins键,您可以显式编写连接并为其提供自己的表别名。您必须手动指定连接,但它将使您的要求完全明确。例如:

Bar.all(:joins => "INNER JOIN foos AS my_foos ON my_foos.bar_id = bars.id", :conditions =>  "my_foos.state = 1")

答案 1 :(得分:0)

类似

:conditions => { :this_table => { :state => 1 } }

答案 2 :(得分:0)

您是否正在使用查询中:include表中的任何字段(如:conditions /:order等)?如果没有,并且您只需要加载记录,则可以使用单独的查询来执行此操作:

records = Bar.all(:joins => ..., :conditions => ..., ...)
Bar.send(:preload_associations, records, [:association1, :association2 ... ])

preload_associations是受保护的方法(请参阅本答案中的more),但使用:join和:include together通常会产生巨大的SQL查询,这远远不能管理。