2012-08-22 126 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' –

相關問題