2015-04-23 79 views
4

我想构建一个强制索引,同时也使用包括一个ActiveRecord语句。Activerecord强制索引与包括

声明看起来是这样的:

Job.from("jobs FORCE INDEX(index1,index2)").includes(:workflow) 

但它似乎AR不喜欢这一点,并抛出:

NoMethodError (undefined method `map' for "jobs FORCE INDEX(index1,index2)":Arel::Nodes::SqlLiteral): 

有没有人有任何想法?所有的工作好,如果包含语句被取下,所以我认为这是试图建立LEFT OUTER JOIN和表别名查询...

感谢 中号

+1

似乎可以在rails 4中正常工作。值得探索从rails 3和rails 4之间的区别(http://api.rubyonrails.org/v3.2.11/classes/ActiveRecord/QueryMethods.html#method- i-from和http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-from) – Shadwell

+0

Hi Shadwell。它工作正常,除非activerecord必须执行基于其中一个包含的查询。所以一个更完整的例子是Job.from(“jobs FORCE INDEX(index1,index2)”)。includes(:workflow).where(“workflows.name ='Bob'”)... – user3707

+0

您需要添加一个'references'调用:'where(“workflows.name ='Bob'”)。references('workflows')' – Shadwell

回答

1

按照有关问题的意见事实证明,该count呼叫链上有fromincludes(包含关联的条件)是问题所在。

事实上,即使仅仅使用from调用,即使它只是from("jobs")也会导致问题,所以强制索引有点像是一条红色的鲱鱼。

在这种情况下(需要计数),我无法找到使用includes的解决方案。但是,如果你包含一个关联并添加一个条件,那么joins应该等于includes无论如何(我认为!)。在这种情况下,以下应该工作(我打破它分解成步骤,以使其更可见):

q = Job.from("jobs FORCE INDEX(index1,index2)") 
q = q.joins(:workflow) 
q = q.where("workflows.name = 'Bob'") 
q.count 

如果你真的需要左外是includes提供这时你可以手动指定:

q = Job.from("jobs FORCE INDEX(index1,index2)") 
q = q.joins("left outer join workflows on workflows.job_id = jobs.id") 
q = q.where("workflows.name = 'Bob'") 
q.count 
+0

注意:rails 4或rails 3也是一种红鲱鱼。这应该可以解决导轨4和导轨3上的问题。 – Shadwell

+0

Awesome Shadwell。不知道连接的语法(或者说,我从来没有想过我可以这样做)! – user3707