2012-04-13 58 views
13

我有一個徽標模型,其名稱的字段爲string:default:boolean。我希望真正的值是唯一的,以便數據庫中只有一個項目可以一次設置爲true。如何在我的控制器中設置我的更新和新操作以將我的徽標的所有其餘值設置爲false?Rails 3應用程序模型如何確保一次只有一個布爾字段設置爲true

比方說,我有以下設置 在我的數據庫
型號標誌
名稱:串|默認值:boolean |
商品1 | true |
商品2 | false |
商品3 | false |

如果我將Item2默認值更改爲true,我希望它遍歷所有徽標,並將其餘部分設置爲false,所以只有一個是同時存在的,所以它看起來像這樣。

name:string |默認值:boolean |
商品1 | false |
商品2 | true |
商品3 | false |

感謝您提前提供任何幫助。

回答

18

此代碼是從前面的答案被盜,稍作簡化:

def falsify_all_others 
    Item.where('id != ?', self.id).update_all("default = 'false'") 
end 

您可以在模型中使用的before_save回調此方法。

其實,這是更好地 「僞造」 只記錄其值是 '真',是這樣的:

Item.where('id != ? and default', self.id).update_all("default = 'false'") 

UPDATE:保持代碼幹後,用self.class代替Item

self.class.where('id != ? and default', self.id).update_all("default = 'false'") 
+0

+1使用回調。 – 2013-03-30 21:22:40

+3

更好地使用標準的sql爲id比較''id <>?''。如果默認的當前值也是真的,那麼確保你只關閉update_all。 – toxaq 2013-08-14 02:45:34

+0

超棒的男人!它非常完美! – 2013-11-17 13:47:23

3

在控制器代碼,你可以做這樣的事情....請注意你很可能會項目2作爲設置了一個param [...]所以你可以互換,下面

@items_to_be_falsified = Item.where('id != ?', Item2.id) 

@items_to_be_falsified.each do |item| 
    item.default = false 
    item.save 
end 

請注意,當你得到這個工作,它很好的做法,推動這一到模型,使之成爲一個函數並調用它像Item2.falsify_all_others像下面

def falsify_all_others 
    Item.where('id != ?', self.id).each do |item| 
    item.default = false 
    item.save 
    end 
end 

享受!

+0

這很好,謝謝,現在我已經學會了將來如何做到這一點。 – ruevaughn 2012-04-13 05:31:20

+3

你最好在這裏使用'update_all'。此代碼可能正在執行數千個查詢。 – Mischa 2012-05-27 07:24:02

3

我也建議僞造你的所有記錄,然後使其成爲真實。

add_column :users, :name ,:boolean, default: false 
3

好的還有一些你需要的東西。

請勿使用字段名稱default,其通常爲數據庫保留。 將缺省記錄保存爲false會將所有記錄設置爲false,但這不是您想要的。檢查我們是否將此記錄設置爲true和falseify。

before_save :falsify_all_others 
    def falsify_all_others 
    if is_default 
     self.class.where('id != ?', self.id).where('is_default').update_all(:is_default => false) 
    end 
    end 
+0

我遇到了這個。我一直在想,爲什麼我的falsify_all是在重寫新的默認值。你說使用列名默認會導致類似的問題? – nathanengineer 2016-12-01 18:34:23

4

我認爲在你篡改他人之前檢查你保存的那個是否是真的很好。否則,當你保存一個不活躍的記錄時,你就會僞造每個人。

def falsify_all_others 
    if self.default 
     self.class.where('id != ? and default', self.id).update_all("default = 'false'") 
    end 
end 
1

,如果你想這對於創建和更新工作(軌道V4) 請記下此珍聞從rails guides

after_save的同時運行的創建和更新,但總是愈後 具體回調after_create和after_update,無論其中執行宏調用的訂單 。

相關問題