From 094ae1eb31d07ea6fdfdbdc50e0e4cfbc7d4f120 Mon Sep 17 00:00:00 2001 From: Zaid Zawaideh Date: Tue, 31 Dec 2013 12:33:47 -0500 Subject: [PATCH 1/2] confirmation emails get sent inifinitely when an invited user signs up --- lib/devise_invitable/model.rb | 9 +++++++-- test/functional/registrations_controller_test.rb | 9 +++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/devise_invitable/model.rb b/lib/devise_invitable/model.rb index e1d56918..31761cd0 100644 --- a/lib/devise_invitable/model.rb +++ b/lib/devise_invitable/model.rb @@ -38,7 +38,7 @@ module Invitable include ActiveSupport::Callbacks define_callbacks :invitation_accepted before_update :generate_confirmation_token, :if => :confirmation_required_for_invited? - after_update :send_on_create_confirmation_instructions, :if => :confirmation_required_for_invited? + after_update :send_invited_confirmation_instructions, :if => :confirmation_required_for_invited? attr_writer :skip_password @@ -164,6 +164,11 @@ def encrypted_invitation_token self.invitation_token end + def send_invited_confirmation_instructions + send_confirmation_instructions + @confirmation_sent_at = Time.now + end + protected # Overriding the method in Devise's :validatable module so password is not required on inviting def password_required? @@ -171,7 +176,7 @@ def password_required? end def confirmation_required_for_invited? - respond_to?(:confirmation_required?, true) && confirmation_required? && invitation_accepted? + respond_to?(:confirmation_required?, true) && confirmation_required? && invitation_accepted? && @confirmation_sent_at.blank? end # Checks if the invitation for the user is within the limit time. diff --git a/test/functional/registrations_controller_test.rb b/test/functional/registrations_controller_test.rb index e29db3a8..de8011f6 100644 --- a/test/functional/registrations_controller_test.rb +++ b/test/functional/registrations_controller_test.rb @@ -33,6 +33,15 @@ def setup end @invitee = User.where(:email => invitee_email).first + + # only one confirmation email gets sent + assert_difference('ActionMailer::Base.deliveries.size', 1) do + @invitee.bio = "I am a robot" + @invitee.save! + @invitee.bio = "I am a human" + @invitee.save! + end + assert_present @invitee.encrypted_password assert_not_nil @invitee.invitation_accepted_at assert_nil @invitee.invitation_token From d1529ccfc220e9b2e6918dd97be0331fe094d960 Mon Sep 17 00:00:00 2001 From: Zaid Zawaideh Date: Tue, 31 Dec 2013 14:09:42 -0500 Subject: [PATCH 2/2] sending the confirmation email from the registration controller directly instead of in a callback --- .../devise_invitable/registrations_controller.rb | 1 + lib/devise_invitable/model.rb | 12 +++--------- test/functional/registrations_controller_test.rb | 4 ++-- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/app/controllers/devise_invitable/registrations_controller.rb b/app/controllers/devise_invitable/registrations_controller.rb index 9eb1ef51..c2806fa8 100644 --- a/app/controllers/devise_invitable/registrations_controller.rb +++ b/app/controllers/devise_invitable/registrations_controller.rb @@ -7,6 +7,7 @@ def build_resource(hash = nil) self.resource = resource_class.where(:email => hash[:email], :encrypted_password => '').first if self.resource self.resource.attributes = hash + self.resource.send_confirmation_instructions if self.resource.confirmation_required_for_invited? self.resource.accept_invitation end end diff --git a/lib/devise_invitable/model.rb b/lib/devise_invitable/model.rb index 31761cd0..d25c7fe2 100644 --- a/lib/devise_invitable/model.rb +++ b/lib/devise_invitable/model.rb @@ -37,8 +37,6 @@ module Invitable include ActiveSupport::Callbacks define_callbacks :invitation_accepted - before_update :generate_confirmation_token, :if => :confirmation_required_for_invited? - after_update :send_invited_confirmation_instructions, :if => :confirmation_required_for_invited? attr_writer :skip_password @@ -164,9 +162,8 @@ def encrypted_invitation_token self.invitation_token end - def send_invited_confirmation_instructions - send_confirmation_instructions - @confirmation_sent_at = Time.now + def confirmation_required_for_invited? + respond_to?(:confirmation_required?, true) && confirmation_required? end protected @@ -175,10 +172,7 @@ def password_required? !@skip_password && super end - def confirmation_required_for_invited? - respond_to?(:confirmation_required?, true) && confirmation_required? && invitation_accepted? && @confirmation_sent_at.blank? - end - + # Checks if the invitation for the user is within the limit time. # We do this by calculating if the difference between today and the # invitation sent date does not exceed the invite for time configured. diff --git a/test/functional/registrations_controller_test.rb b/test/functional/registrations_controller_test.rb index de8011f6..c5fc974c 100644 --- a/test/functional/registrations_controller_test.rb +++ b/test/functional/registrations_controller_test.rb @@ -34,8 +34,8 @@ def setup @invitee = User.where(:email => invitee_email).first - # only one confirmation email gets sent - assert_difference('ActionMailer::Base.deliveries.size', 1) do + # do not send emails on model changes + assert_difference('ActionMailer::Base.deliveries.size', 0) do @invitee.bio = "I am a robot" @invitee.save! @invitee.bio = "I am a human"