Question

I am using Rails 4.01 and Devise 3.2.1 I need a user to be able to register on the site without a password, then when they click the email confirmation, they are sent to a page where they choose a password before the confirmation is complete. Then they should automatically be logged into the site.

I followed the tutorial at the Devise page but my code is not working properly. When you click the link in the email you are automatically confirmed and redirected to the signin page. Of course you can't sign in because you have never created a password.

I think the issue is in my controller but I'm not sure. My Confirmations Controller code is:

class ConfirmationsController < Devise::ConfirmationsController

def show
  self.resource = resource_class.find_by_confirmation_token(params[:confirmation_token]) if params[:confirmation_token].present?
  super if resource.nil? or resource.confirmed?
end

def confirm
  self.resource = resource_class.find_by_confirmation_token(params[resource_name][:confirmation_token]) if params[resource_name][:confirmation_token].present?
  if resource.update_attributes(params[resource_name].except(:confirmation_token).permit(:password, :password_confirmation)) && resource.password_match?
    self.resource = resource_class.confirm_by_token(params[resource_name][:confirmation_token])
    set_flash_message :notice, :confirmed
    sign_in_and_redirect(resource_name, resource)
  else
    render action: "show"
  end
end
  end

My routes have been modified as follows:

MYAPP::Application.routes.draw do
root :to => "home#index"
devise_for :users, controllers: {registrations: 'registrations', confirmations: 'confirmations'}
devise_scope :user do
    patch "/confirm" => "confirmations#confirm"
end
resources :users
end

I've added a couple new methods in my User Controller to deal with the password:

 class User < ActiveRecord::Base
    rolify
      devise :database_authenticatable, :registerable,
      :recoverable, :rememberable, :trackable, :validatable, :confirmable

  def password_required?
    super if confirmed?
  end

  def password_match?
    self.errors[:password] << "can't be blank" if password.blank?
    self.errors[:password_confirmation] << "can't be blank" if     password_confirmation.blank?
    self.errors[:password_confirmation] << "does not match password" if password != password_confirmation
    password == password_confirmation && !password.blank?
  end

end

And here is the show.html.erb file:

<h2>You're almost done! Now create a password to securely access your account.</h2>
<%= simple_form_for(resource, as: resource_name, url: confirm_path, html: {class: 'custom' }) do |f| %>
  <%= f.error_notification %>
  <%= display_base_errors resource %>
  <%= f.input :password, autofocus: true, required: true %>
  <%= f.input :password_confirmation, required: true %>
  <%= f.input :confirmation_token, as: :hidden %>
  <%= f.button :submit, 'Confirm Account', class: 'button tiny radius' %>
<% end %>

And finally here is the relevant bit from my log:

Started GET "/users/confirmation?confirmation_token=js66pGHqdsi9NobJxBGT" for 127.0.0.1 at 2013-11-19 12:15:34 -0700
Processing by ConfirmationsController#show as HTML
  Parameters: {"confirmation_token"=>"js66pGHqdsi9NobJxBGT"}
  [1m[35mUser Load (0.1ms)[0m  SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = 'js66pGHqdsi9NobJxBGT' LIMIT 1
  [1m[36mUser Load (0.1ms)[0m  [1mSELECT "users".* FROM "users" WHERE "users"."confirmation_token" = '9e4fa1cf31a96f1ac1087efa9f086e2cfce8d3f101fbe8f77180710dbeab0c90' ORDER BY "users"."id" ASC LIMIT 1[0m
  [1m[35m (0.1ms)[0m  begin transaction
  [1m[36mSQL (0.5ms)[0m  [1mUPDATE "users" SET "confirmation_token" = ?, "confirmed_at" = ?, "updated_at" = ? WHERE "users"."id" = 13[0m  [["confirmation_token", nil], ["confirmed_at", Tue, 19 Nov 2013 19:15:34 UTC +00:00], ["updated_at", Tue, 19 Nov 2013 19:15:34 UTC +00:00]]
  [1m[35m (5.8ms)[0m  commit transaction
Redirected to http://localhost:3000/users/sign_in
Completed 302 Found in 67ms (ActiveRecord: 7.3ms)

There is a similar question here but it doesn't provide a solution for me.

Was it helpful?

Solution

I'll answer my own question. With a few modification, this page provided the answer I needed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top