plataformatec/devise — Issue #1708: send_confirmation_instructions called on UserObserver update when reconfirmation_required? == false
Author: aprescott
Created: 2012-03-09 14:47:51+00:00
State: open

I've seen this on Rails 3.2.1 with both Devise 2.0.0 and 2.0.4. The result of this in my specific case is that a second confirmation email is being sent. I believe it's a bug, having searched on Google with no luck other than finding two mailing list posts[1] with a similar issue of confirmation emails being sent twice.

I have a `User` model which is using confirmable. There is a `UserObserver` which has an `after_create` method which calls `user.update_attribute(:foo, "bar")`. Before the `update_attribute` method is called, the value of `user.send(:reconfirmation_required?)` is `false` (`send` is used because it's a protected method).

On creating a new user, the first confirmation email goes out, then a second one with "Welcome !" (showing the `@resource` instance var isn't being set properly) and a different confirmation token value. When the `user.update_attribute(:foo, "bar")` called in `UserObserver` is commented out, the second confirmation isn't sent and everything's fine.

Looking at [confirmable.rb](https://github.com/plataformatec/devise/blob/a909bfaf85a07e94da8f15fdeb22101606dea57c/lib/devise/models/confirmable.rb), I can see that there is a callback defined:

```ruby
after_update :send_confirmation_instructions, :if => :reconfirmation_required?
```

Despite the condition of `reconfirmation_required?` being false (as shown by the `send(:reconfirmation_required?) == false`), when creating a new user, a confirmation email is sent out with the confirmation token of `foo` and immediately after that, a second confirmation email is sent out with a confirmation token different from `foo` and with an opening line of "Welcome !" in the body.

I've checked that `send_confirmation_instructions` is the thing actually being called by simply defining

```ruby
def user.send_confirmation_instructions
raise :foo
end
```

which raises. Since `send_confirmation_instructions` had `send_on_create_confirmation_instructions` split off from it, the `after_update` callback is the only thing I can find which is calling `send_confirmation_instructions`.

Having explained all that, if, before confirming the new user by clicking the link, you fire up the Rails console and retrieve it with `User.last`, then call `update_attribute(:foo, "bar")` on it, no additional confirmation email is sent out. But in the `UserObserver` the second email *does* get sent out. In `UserObserver`, `send(:reconfirmation_required?)` is `false`, and in the console it's `nil`.

[1]: http://groups.google.com/group/plataformatec-devise/browse_thread/thread/4ccb926ea3b25f5b and http://groups.google.com/group/plataformatec-devise/browse_thread/thread/3e062cf1d30755d8