Skip to content

Instantly share code, notes, and snippets.

@zippy
Created January 9, 2011 13:58
Show Gist options
  • Save zippy/771706 to your computer and use it in GitHub Desktop.
Save zippy/771706 to your computer and use it in GitHub Desktop.
Implementation of getting user password as part of confirmation for Devise 1.2.x
#This is for Devise 1.2.x
# To your routes file add:
as :user do
match '/user/confirmation' => 'confirmations#update', :via => :put, :as=> :update_user_confirmation
end
# Add this inherited confirmations controller as app/controllers/confirmations_controller.rb
class ConfirmationsController < Devise::PasswordsController
skip_before_filter(:authenticate_user!)
# PUT /resource/confirmation
def update
with_unconfirmed_confirmable do
if @confirmable.has_no_password?
@confirmable.attempt_set_password(params[:user])
if @confirmable.valid?
do_confirm
else
do_show
@confirmable.errors.clear #so that we wont render :new
end
else
self.class.add_error_on(self, :email, :password_allready_set)
end
end
if [email protected]?
render_with_scope :new
end
end
# GET /resource/confirmation?confirmation_token=abcdef
def show
with_unconfirmed_confirmable do
if @confirmable.has_no_password?
do_show
else
do_confirm
end
end
if [email protected]?
render_with_scope :new
end
end
protected
def with_unconfirmed_confirmable
@confirmable = User.find_or_initialize_with_error_by(:confirmation_token, params[:confirmation_token])
if [email protected]_record?
@confirmable.only_if_unconfirmed {yield}
end
end
def do_show
@confirmation_token = params[:confirmation_token]
@requires_password = true
self.resource = @confirmable
render_with_scope :show
end
def do_confirm
@confirmable.confirm!
set_flash_message :notice, :confirmed
sign_in_and_redirect(resource_name, @confirmable)
end
end
<% @title = 'Account Activation' %>
<%= form_for resource, :as => resource_name, :url => update_user_confirmation_path, :html => {:method => 'put'}, :id => 'activation-form' do |f| %>
<%= devise_error_messages! %>
<fieldset>
<legend>Account Activation<% if resource.user_name %> for <%= resource.user_name %><% end %></legend>
<% if @requires_password %>
<p><%= f.label :password,'Choose a Password:' %> <%= f.password_field :password %></p>
<p><%= f.label :password_confirmation,'Password Confirmation:' %> <%= f.password_field :password_confirmation %></p>
<% end %>
<%= hidden_field_tag :confirmation_token,@confirmation_token %>
<p><%= f.submit "Activate" %></p>
</fieldset>
<% end %>
<%= javascript_tag('Form.focusFirstElement("activation-form");') %>
# Add these methods to your user model
# new function to set the password without knowing the current password
# used in our confirmation controller.
def attempt_set_password(params)
p = {}
p[:password] = params[:password]
p[:password_confirmation] = params[:password_confirmation]
update_attributes(p)
end
# new function to return whether a password has been set
def has_no_password?
self.encrypted_password.blank?
end
# new function to provide access to protected method unless_confirmed
def only_if_unconfirmed
unless_confirmed {yield}
end
@thoughtshop
Copy link

I'm getting an error: undefined method `only_if_unconfirmed'. I'm using devise 1.2rc

@skyporter
Copy link

I have the same error with devise 1.2rc
solution :

  • replace method "only_if_unconfirmed" by "unless_confirmed"

and another problem is with @confirmable.has_no_password? => replace by "@confirmable.password.blank?"

@zippy
Copy link
Author

zippy commented Jan 18, 2011

Sorry guys, I forgot to include the additions to your user model necessary to get this to work. I've added them above.

@skyporter
Copy link

Ok, I understand why it didn't work :)
Thanks for updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment