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

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