2013-02-08 65 views
16

我有兩個相關模型 - 比如說ActivityStepActivity has_many :stepsStep belongs_to :activity這意味着steps的表有activity_id列。防止在Rails模型中改變一個字段

這是在Hobo 1.3中,所以Rails 3.0。

我想要確保在Step創建後無法將步驟移動到另一個步驟Activity。我們不希望activity_id字段發生變化。

我已經從編輯表單中刪除了該字段,但我正在尋找更強的約束。基本上我想驗證update(不在create)該列沒有被觸及。 Hobo的文檔沒有提到Hobo內部的任何類型,所以我在看着Rails validations,但到目前爲止我還沒有找到「我只記得更新」的約束條件,也沒有發現某些東西不是改變。

回答

29

您可以使用attr_readonly :your_field_name聲明屬性爲read_only。 但是,如果您嘗試寫入此屬性,則不會產生錯誤,它將自動失敗。

另一種選擇可能是編寫驗證此情況下(此屬性將所有SQL的更新被忽略),可能是這樣的:

class Step < ActiveRecord::Base 
    validate :activity_id_not_changed 

    private 

    def activity_id_not_changed 
    if activity_id_changed? && self.persisted? 
     errors.add(:activity_id, "Change of activity_id not allowed!") 
    end 
    end 
end 

persisted?返回true,如果這不是一個新的記錄,它不會被破壞。

鏈接:

http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html#method-i-readonly_attributes

http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-persisted-3F

+0

'attr_readonly'按照廣告宣傳,b ut可能會導致與應用程序的另一方面的皺紋。我會在明天嘗試驗證方法,看看這樣做是否更好。 – pjmorse 2013-02-09 02:17:11

+0

如果您確實需要在您的應用程序的其他地方更改ID,那麼即使採用以下驗證方法,您也可以執行此操作:'step.save(:validate => false)' – Deradon 2013-02-09 13:54:44

+0

這不是其他地方的更改問題;它是一個對象副本。 (所以,假設我們假設複製了'Activity',並且複製了所有的'Steps';出於某種原因,這種功能無法正常工作,而且我還沒有深入到複製代碼中去了解這個變化是否會破壞它。) – pjmorse 2013-02-10 01:05:49

相關問題