Hemant Patil
Hemant Patil

Reputation: 351

Resend Confirmation instructions to the user using devise

I want to resend confirmation instructions to the user if the user has not confirmed his account after sign up. I am using rails 4. I have this code but its not working.

def resend_confirmation_instructions
  users = User.where('confirmed_at IS ?', nil)
  users.each do |user|
    if (user.created_at < (Date.today - 8))
      end_date = (user.created_at.to_date)
      start_date = Date.today()
      date_diff = (start_date - end_date).to_i
      if (date_diff == 3) or (date_diff == 6)
       user.send_confirmation_instructions
      end
    end
  end
end

I am using whenever gem to schedule this task every day.

Upvotes: 2

Views: 2170

Answers (1)

tompave
tompave

Reputation: 12412

Your code seems alright, but you might have a performance problem when you do users.each with too many users.

Basically users will be an ActiveRecord::Relation, that is an object containing a collection of query parameters. Calling each on it will convert it to an Array as cause the query to be executed. If you have too many objects, that might kill your DB or ruby process.

What about using find_each, to see if it makes a difference?

You are also loading a lot of users that you will probably don't need, as you're executing this check inside the loop:

user.created_at < (Date.today - 8)

That's something else that can affect performance and kill your process. It would be better to add that filter to the active record query.

Try with:

def resend_confirmation_instructions
  today = Date.today
  users = User.where(confirmed_at: nil)
              .where('created_at < ?', (today - 8))

  users.find_each(batch_size: 100) do |user|
    end_date = user.created_at.to_date
    date_diff = (today - end_date).to_i

    if date_diff == 3 || date_diff == 6
      user.send_confirmation_instructions
    end
  end
end

Upvotes: 3

Related Questions