我有一些复杂的ActiveRecord(2.3.8)模型(不是真的,一些关联和命名范围,以及一个缓存值),在我的应用程序的某处,我看到以下MySQL(5.1)查询出现:
SELECT `cases`.id FROM `cases`
INNER JOIN `contracts` ON `cases`.contract_id = `contracts`.id
WHERE ((case_status_id = 0 AND case_status_id IS NOT NULL) AND id = XXXX)
AND ((`cases`.`archived` = 0)
AND ((`contracts`.customer_id = XXXX)))
LIMIT 1
显然不是最易读的查询。有时ActiveRecord抱怨列'id'不明确,我不得不同意: - )
但是,只有当数据库中的数据“稀疏”时才会发生这种情况。我们有一个填充这些表的导入脚本,插入的数据越多,这些错误就越少。
触发异常的代码:
paginate_options = {:page => params[:page], :per_page => 25 }
options = paginate_options.merge(:include => [:active_status, :case_summary], :order => @sortable.order)
@cases = current_customer.cases.unarchived.paginate(options)
缓存“活动状态”字段的位置:
belongs_to :active_status,
:class_name => "CaseStatus",
:foreign_key => 'case_status_id'
caches_value :case_status_id,
:sql => 'SELECT id FROM case_statuses WHERE case_id = #{id} ORDER BY id DESC LIMIT 1'
stacktrace看起来像这样:
config/initializers/connection_fix.rb: 17:in `execute'
vendor/plugins/cached_values/lib/cached_value.rb: 91:in `update_cache'
vendor/plugins/cached_values/lib/cached_value.rb: 14:in `load'
vendor/plugins/cached_values/lib/cached_values.rb: 85:in `case_status_id'
plugins/will_paginate/lib/will_paginate/finder.rb: 82:in `paginate'
plugins/will_paginate/lib/will_paginate/collection.rb: 85:in `create'
plugins/will_paginate/lib/will_paginate/finder.rb: 76:in `paginate'
所以我假设第一次尝试刷新缓存时会发生此错误。查询似乎由cached_values插件和will_paginate语句使用,但该语句中使用的缓存查询不会出现在上面的查询中。
我也不明白为什么当还有cases.id
语句时,ActiveRecord会查询id=XXXX
。我假设两个查询相同的id
,但是再次, 非常模糊..
我可以告诉ActiveRecord使用显式表名吗?或者调试构建此查询的方式? “cached_values”插件是否可能受命名范围的影响,是否可以解决这个问题?