I want to change edit password process. On edit password page I have one field :foo and I want to check if user correctly entered it.
I created PasswordsController and override update method, where I added code for testing if :foo is same as in database:
def update
self.resource = resource_class.reset_password_by_token(resource_params)
# this is code that I added
unless self.resource.foo == params[resource_name][:foo]
self.resource.errors.add(:foo, "Foo not correct")
end
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message(:notice, flash_message) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => after_resetting_password_path_for(resource)
else
binding.pry
respond_with resource
end
end
Suppose I enter "test" in :foo field, but in database it's value is "fake". It will print error on view ("Foo not correct") but it will populate :foo field with value from database ("fake") not with value I entered ("test").
I should redefine reset_password_by_token or use my custom method, but wonder if there is more elegant way to solve this problem?
Try using a before_action (may be before_filter, depending on your Rails version):
You could also probably change this to just extend the existing
RegistrationsController
. Just re-use the existing Devise implementation ofupdate
without re-implementing it, just adding the filter in front.To prevent updating the
:foo
on the object, filter theparams
hash, removing the:foo
field, before passing it toreset_password_by_token
.Or if you're using Rails 4, or Strong Parameters, just don't permit it.