我有一个奇怪的问题,我正在使用的rails引擎中的某些模型在对象空间中被复制.
(rdb:1) ObjectSpace.each_object(::Class).each { |klass| puts klass.to_s + ": " + klass.object_id.to_s if klass.to_s.eql?("DynamicFieldsets::Field") }
DynamicFieldsets::Field: 66866100
DynamicFieldsets::Field: 71836380
2479
Run Code Online (Sandbox Code Playgroud)
发生这种情况时,我不能使用is_a?或等式检查以测试对象是Field类的实例.问题只发生在开发中,看起来它可能是由cache_classes关闭引起的.我认为前一个请求中的对象仍然在对象空间中,但我不确定如何删除它.
我在使用rails 3.1.4在不同的范围内连接到同一个表两次时遇到了问题.其中一个范围完全被忽略,包括join和where子句.这种删除没有错误或通知.
这是导致问题的简化示例:
Task是标准rails模型,与模型SavedOutput具有多态关系.SavedOuput用作缓存来存储复杂方法的结果.
任务模型如下所示:
class Task < ActiveRecord::Base
has_many :saved_outputs
scope :saved_lates, lambda { joins(:saved_outputs).where(
"saved_outputs.method" => "late?",
"saved_outputs.output" => true
)}
scope :saved_completes, lambda { joins(:saved_outputs).where(
"saved_outputs.method" => "complete?",
"saved_outputs.output" => true
)}
...
Run Code Online (Sandbox Code Playgroud)
使用此代码,我可以调用Task.saved_lates而不是调用类似于Task.all.select(&:late?)假设缓存数据是最新的.
问题是呼叫Task.saved_lates.saved_completes不起作用.我相信rails的重复查询检测会启动并删除第二个范围.即使没有发生这种情况,查询仍然会失败,因为如果不使用MYSQL中的别名,则无法连接到同一个表两次.
我有一个部分解决方案,手动编写连接和表别名.
scope :saved_lates, lambda { joins("INNER JOIN saved_outputs AS so1 ON so1.object_type='Task' AND so1.object_id=tasks.id").where(
"so1.method" => "late?",
"so1.output" => true
)}
scope :saved_completes, lambda { joins(INNER JOIN saved_outputs AS so2 ON so2.object_type='Task' AND so2.object_id=tasks.id).where(
"so2.method" => …Run Code Online (Sandbox Code Playgroud)