【问题标题】::include and table aliasing:include 和表别名
【发布时间】:2010-06-02 21:42:33
【问题描述】:

我遇到了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”场景中也不适用)。

是否有可行的解决方法?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      类似

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

      【讨论】:

      • 在猜测时测试您的答案被认为是一种很好的做法。散列中的第一个条目是表的列。 [2010-06-02 15:16:42] [DEBUG] ThisTable Load (0.000000) Mysql::Error: #42S22Unknown column 'this_table.this_table' in 'where 子句': SELECT * FROM this_table WHERE (this_table .this_table = '--- - :state - 1 ')
      【解决方案3】:

      您是否在查询中使用:include 表中的任何字段(如:conditions / :order 等)?如果没有,您只需要加载记录,您可以使用单独的查询来完成:

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

      preload_associations 是受保护的方法(请参阅此答案中的more),但是一起使用 :joins 和 :include 通常会产生巨大的 SQL 查询,这远非可管理。

      【讨论】:

      • 谢谢,有趣的建议。是的,条件包括 :include 表中的字段。我想我仍然可以手动构建预加载,也许我会依靠它。显然,这消除了很多 has_many 和 :include 的优雅。
      猜你喜欢
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多