2012-10-29 32 views
12

可能重複:
Ruby on Rails: Is it better to validate in the model or the database?導軌:驗證模型VS遷移

我看到它有可能在兩個軌模型和遷移添加相同的約束/驗證。但哪一個是最好的方法?驗證模型和數據庫級別(以及爲什麼)是否是一種好的做法?或者他們在軌道上相同?

例如,我們可以對模型和遷移中的名稱進行相同的驗證

class User < ActiveRecord::Base 
    validates :name, :uniqueness => true, :presence => true 
end 

class CreateUser < ActiveRecord::Migration 
    def change 
    create_table :users do |t| 
     t.string :name, :unique => true, :null => false 
    end 
    end 
end 
+0

好問題。我會說在模型中做它,並讓它強制執行到數據庫,但我有興趣聽到別人說什麼。 – ardochhigh

回答

24

儘可能在數據庫級別以及模型級別進行驗證。

爲什麼?對於初學者來說,主動記錄不會在所有情況下強制進行驗證。以下方法跳過驗證,並且將對象保存到數據庫中,無論其有效性:

decrement! 
decrement_counter 
increment! 
increment_counter 
toggle! 
touch 
update_all 
update_attribute 
update_column 
update_counters 

如果傳遞:validate => falsesave,它也將跳過驗證。有關詳細信息,請參閱跳過驗證的Active Record Validations and Callbacks Guide部分。 (如果你擔心,甚至有a gem禁用這些方法。)

所以原因#1是Rails的驗證不充分,證明以任何方式:依靠他們完全是有風險的,特別是任務性關鍵驗證,如獨特性。

說到這,原因#2(把我的頭頂部):ActiveRecord的驗證是容易出現競爭情況,和Rails'特別唯一性驗證無法保證唯一性。這裏有很多文件中的one article這是爲什麼如此。

儘管它們可能很少發生,但違反唯一性約束可能會損壞整個數據集。在極少數情況下,Rails即將這樣做,您不惜一切代價阻止它,這是數據庫唯一性約束的來源:數據庫的構建是爲了處理這種情況,並且會始終如一地執行唯一性,即使Rails沒有。

And reason#3:爲什麼不是驗證模型和數據庫?當然,你重複了一下,但是與Rails相比,如果Rails沒有像唯一性驗證檢查那樣的事情,那通常是一個非常小的問題。這實際上不是一個/或命題:它總是總是更好地複製數據庫中的驗證,只要你可以,尤其是對於任務關鍵性約束如獨特性。

無論如何,這些都是我的想法,希望有所幫助。

編號:Where Correctness Is Enforced(加里·哈特截屏,需要訂閱才能觀看)

+1

優秀的答案,遠勝於完全重複的問題。 – 18bytes

+7

原因#4:一個數據庫本身擁有實體,它可以在Rails應用程序之外使用。 – tokland

+0

@Sundar謝謝!是的,其他答案不是非常有見地...... –