2014-11-04 79 views
1

我需要在我的應用程序的某些部分有條件的驗證。現在,我使用下面的方案:更改驗證規則上即時

User.create 
User::WithPassword.create 
User::WithPhone.create 

這將是冷靜,如果我能在飛行中這樣的改變類的行爲:

User.with_phone.with_password.create 

於是,我就做這樣的:

class User < ActiveRecord::Base 
    validates :phone, presence: true, if: :phone_required? 

    def self.with_phone 
    define_method(:phone_required?) { true } 
    self 
    end 

    private 

    def phone_required? 
    false 
    end 
end 

因此,它可以像這樣在需要的地方使用:

User.with_phone.create(user_params) 

這種方法的問題是,由於實際的類更改用戶的所有實例得到新的行爲。

有沒有辦法在不影響「基」類的情況下僅返回User類的修改副本與新實例方法phone_required?

更新

謝謝你的評論,因爲這是更多的想法,要求是創建用戶沒有一定的驗證自動,然後當他們編輯的個人資料,他們正在處理原始User模型。我在需要時創建with_/without_在方法丟失的方法。

這裏是我的下一個迭代:

class User < ActiveRecord::Base 
    validates :phone, presence: true, if: :phone_required? 

    def self.with_password 
    define_singleton_method(:password_required?) { true } 
    self 
    end 

    def password_required? 
    self.class.try :password_required? 
    end 
end 

顯然,這是爲單身方法沒有任何好轉停留那裏所有的時間。

+2

請不要這樣做。它面對正確的面向對象設計飛行,除非你試圖採用「工作安全通過猖獗混淆」模式。爲什麼不使用'attr_accessor'標誌或第一類列來堅持這個布爾值?這種方法不會再顯示出來,所以當你嘗試重新保存現有的記錄時,你的驗證將失敗。 – tadman 2014-11-04 17:27:41

+0

感謝您的輸入,實際上我只需要創建時間的定製類。我從'User :: WithoutPassword'模型重構了這個。我使用單例方法創建更新了原始問題,因此它不會污染基類。 – firedev 2014-11-05 05:46:15

回答

1

爲什麼不能簡單地用在創建時初始化實例變量?

class User < ActiveRecord::Base 
    validates :phone, presence: true, if: :phone_required? 

    @phone_required = false 

    def self.create_with_phone(params) 
    obj = self.create(params) 
    obj.phone_required = true 
    end 

    private 

    def phone_required=(v) 
    @phone_required = v 
    end 

    def phone_required? 
    @phone_required 
    end 
end 

User.create_with_phone(user_params) 
+0

謝謝你的建議,我想模仿儘可能明確的基類的接口,而無需添加虛擬領域。事情是,在創建時,我需要'User.without_password.without_phone',然後只是'User.without_password',但是一旦用戶編輯他的配置文件,它就是'User'。我已經用新想法更新了原始帖子。 – firedev 2014-11-05 05:48:34