2012-08-22 89 views
2

在我的数据库中,我已将所有外键设置为unsigned int not null default 0。因此,在我的Rails应用程序中,我得到了许多对id = 0的对象的查询。这里有一个例子:有没有办法阻止ActiveRecord查询id = 0的对象?

class Foo < ActiveRecord::Base 
    belongs_to :bar 
end 

class Bar < ActiveRecord::Base 
end 

在控制台,如果我这样做:

Foo.new.bar 

那么这个查询获取运行:

SELECT `bars`.* FROM `bars` WHERE `bars`.`id` = 0 LIMIT 1 

我试过猴子打补丁,但method_missing的没有按似乎无法赶上这类电话。我真的不想(现在不可能)改变我的模式。看来我可以解决这个问题的唯一方法是手动检查bar_id!= 0,但这看起来不太干净。

想法/建议?

只是为了澄清,我不想更改架构。问题是:ActiveRecord是否可以配置/黑客攻击,使0和nil都被认为是无效ID,从而防止对id = 0的对象进行任何查询?

+0

为什么你在新实例化的Foo对象上调用“bar”?查询'where bar.id = 0'的原因是因为Foo对象上的bar_id为0。 –

+0

这只是一个例子来说明这一点。试想一下bar_id = 0的真实Foo实例。 –

+0

你是说所有查询还是你想阻止像find或find_by_id这样的东西与0一起工作? –

回答

0

无论如何我都发布了迁移解决方案。我会高兴,如果

删除它......真的不能在这一点上改变我的架构

证明是真实的。在新迁移文件中:

def up 
    change_column_default(:bars, :id, nil) # removes default, letting it be null 
    execute "update bars set id = null where id = 0" 
end 

def down 
    change_column_default(:bars, :id, 0) 
    execute "update bars set id = 0 where id is null" 
end 
+0

我不想改变的模式,因为我不得不采取了数据库。无论如何,我并不是在寻找一个架构解决方案;我想要一个应用程序级解决方案。 –

0

您可以尝试使用属于方法中的条件。条件创建一个必须通过任何活动记录查询来满足的默认where子句。

belongs_to :bar, :conditions => "id != 0" 
+0

不错的主意!不幸的是,它会导致这样的: 'SELECT酒吧* FROM酒吧,在那里bars.id = 0 AND(!ID = 0)LIMIT 1' –

相关问题