Dennis Hackethal’s Blog
My blog about philosophy, coding, and anything else that interests me.
Running Custom Logic in Rails Devise Controller
Today, I ran into the problem of needing to make a change to a user instance in the RegistrationsController
using the Devise authentication gem. I couldn't do it in a model callback because I needed access to cookies.
Luckily, Devise allows you to pass a custom block, which will be given the resource (e.g., the user
object).
Assuming you already have a custom controller like this one
class RegistrationsController < Devise::RegistrationsController
end
you can achieve this pretty easily by passing a block:
class RegistrationsController < Devise::RegistrationsController
def create
super do |resource|
# do stuff with resource...
resource.foo = 'bar'
resource.save
end
end
end
Unfortunately, the block is invoked after the resource is saved to the database, so you'll need to save it again if you're making any changes that need to be persisted.
The call to super
works because the RegistrationsController
inherits from Devise::RegistrationsController
as defined here. super
will call Devise::RegistrationsController#create
and pass it the block, where it then gets invoked with the resource.
As you can see in the source code, Devise offers support for blocks in #new
, #update
, and #destroy
as well.
Unless you require functionality that's only available in controllers (such as cookies, as I mentioned), I recommend using model callbacks instead. But if you do need to do your magic in controllers, this approach should work.
What people are saying