Mike Garey
2006-Aug-09 00:02 UTC
[Rails] question about enforcing constraints in the model
I have a user model and a status model. Each user has a specific status (accepted, rejected, declined, etc). I have a form that allows the adminstrator to change certain options for a user, including their status. I''m using a drop down menu populated with the different status values, and a default option that says "Choose a new status" with a value of "". I want to prevent setting the status of a user object to nil or 0, but without using validations. So, if for example, the administrator changes the first name of the user, but leaves the status drop down menu at the default option, which is an empty value, the status of the user will not be updated, but the user object will still be saved. I realize I could simply set the value for the default option in the drop down menu to be the current status id of the user, so that if they submit the form without changing the value, it will update their status_id with the same value that it''s presently set to, but I wanted to know how to enforce this constraint in the model, since I figured that would be a good place to put such a restriction, rather than have to enforce it through the user interface. And I don''t want to use validates_presence_of, since I want the administrator to be able to not change the status_id of the user and still be able to save other information. I have tried the following unsuccessfully: user.rb belongs_to :status def status_id=(new_status_id) return if new_status_id.blank? or new_status_id == 0 super end def status=(new_status) return if new_status.nil? super end however, calling super in the second instance gives me the following error: NoMethodError: super: no superclass method `status='' I''ve also tried: def status=(new_status) return if new_status.nil? write_attribute(''status'', new_status) end but this doesn''t write a new status at all. So can anyone tell me the correct way to enforce a restriction such as this in the model? Should I not override the status= method, and simply use the status_id= method? Any advice would be appreciated, thanks. Mike
Duzenbury, Rich
2006-Aug-09 13:42 UTC
[Rails] question about enforcing constraints in the model
> I want to prevent setting the status of a user object to nil or 0, but > without using validations. So, if for example, the administrator > changes the first name of the user, but leaves the status drop down > menu at the default option, which is an empty value, the status of the > user will not be updated, but the user object will still be saved. > > I realize I could simply set the value for the default option in the > drop down menu to be the current status id of the user, so that if > they submit the form without changing the value, it will update their > status_id with the same value that it''s presently set to, but I wanted > to know how to enforce this constraint in the model, since I figured > that would be a good place to put such a restriction, rather than have > to enforce it through the user interface. And I don''t want to use > validates_presence_of, since I want the administrator to be able to > not change the status_id of the user and still be able to save other > information.I think the login engine does this with the password, a before save filter, and an ''if'' statement on the validate. # Virtual attribute for the unencrypted password attr_accessor :password before_save :encrypt_password validates_presence_of :password, :if => :password_required? validates_presence_of :password_confirmation, :if => :password_required? validates_length_of :password, :within => 6..40, :if => :password_required? validates_confirmation_of :password, :if => :password_required? def password_required? crypted_password.blank? || !password.blank? end # before filter def encrypt_password return if password.blank? self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? self.crypted_password = encrypt(password) end I''ve got an ''update my account'' and a ''register for account'' screen. When they initially register, password_required? is true because there is no crypted password, and it forces the entry. When they update, they can change their password, but can also leave the password fields blank. Since they have a crypted password, the validations do not fire. I would think you might be able to adapt this to your own circumstance. Regards, Rich