Rails Devise: after_confirmation
Is there a way to create a after_confirmation开发者_JAVA技巧 :do_something
?
The goal is to send an e-mail after the user confirms using Devise :confirmable
.
I'm using Devise 3.1.2, it has a placeholder method after_confirmation
which is called after the confirmation finished successfully. We just need to override this method in User
model.
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
# Override Devise::Confirmable#after_confirmation
def after_confirmation
# Do something...
end
end
See: Devise 3.5.9 Source Code: https://github.com/plataformatec/devise/blob/d293e00ef5f431129108c1cbebe942b32e6ba616/lib/devise/models/confirmable.rb
For new versions of devise 3.x :
See a different answer http://stackoverflow.com/a/20630036/2832282
For old versions of devise 2.x :
(Original answer)
but you should be able to put a before_save callback on the user (extra credit for using an observer) and check if confirmed_at was just set by devise. You can do something like:
send_the_email if self.confirmed_at_changed?
http://api.rubyonrails.org/classes/ActiveModel/Dirty.html for more details on checking the change on the field.
You can override the confirm!
method:
def confirm!
super
do_something
end
Discussion about the topic is at https://github.com/plataformatec/devise/issues/812. They say that there are no callbacks like after_confirmation :do_something
because that approach would require a lot of different callbacks.
Rails 4:
combining multiple answers above
def first_confirmation?
previous_changes[:confirmed_at] && previous_changes[:confirmed_at].first.nil?
end
def confirm!
super
if first_confirmation?
# do first confirmation stuff
end
end
according to the Devise 3.5.9 source code, you can simply define a method on the Devise Resource model, e.g.:
class User < ActiveRecord::Base
...
def after_confirmation
do_something
end
end
See: Devise 3.5.9 Source Code: https://github.com/plataformatec/devise/blob/d293e00ef5f431129108c1cbebe942b32e6ba616/lib/devise/models/confirmable.rb
I don't see that callback too, maybe you can try to override the confirmation method and call your callback there.
def send_confirmation_instructions(attributes={})
super(attributes)
your_method_here
end
You can override the confirm!
method on your model
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
def confirm!
super
do_something
end
end
There is a discussion about the topic is https://github.com/plataformatec/devise/issues/812. I tried this way, and it worked great.
We're combining answers from @Bernát and @RyanJM:
def confirm!
super
if confirmed_at_changed? and confirmed_at_was.nil?
do_stuff
end
end
This seems a bit more performance aware and safe than the two answers separately.
精彩评论