Conditional model callbacks

Hello,

I have a user model that I am protecting using a ‘before_update
:authorize’ filter. The authorize function basically ensures that the
user is authenticated and that they have sufficient permissions (checks
user’s role) to perform the modification. There is one field, however,
that I would like to exclude from this callback. When a user signs up
for a new account they need to follow a link that is emailed to them in
order to fully activate their account. When they follow the link it
will change the state of the new account to enabled. The problem is
that they are obviously not yet logged in so the ‘before_update
:authorize’ fails when attempting to change the ‘enabled’ field on the
account.

I’ve hit a bit of a wall in trying to figure out a way to exclude a
specific field from triggering that callback when it is modified.
Anyone have an elegant solution to this problem?

Hey,

so you’ve got

def authorize

checks here may return false

end

So why not have a method like this:

def activate(token)
return false if some_check_that_token_is_valid == false
@activate_called = true
update_attribute(:your_enabled_field, ‘enabled’) # whatever
end

and change authorize to do:

def authorize
return true if @activate_called # skip checks - we’re activating

checks that may return false

end

Then you make sure your controller method that calls model.activate
doesn’t (at the same time) set any other attributes from params
(otherwise users could potentially sneak in other attribute changes
without your checks - remember update_attribute may look like only
one field is being written to the DB but all fields are).

Note - I’ve not actually tested any of this - but it’s one way to
approach the problem.

HTH,
Trevor

Trevor S.
http://somethinglearned.com