6
votes

I recently upgraded from Devise 1.2 to 1.4.9 and everything seems to work except my confirmable module. Email works as well as the entire process. But the confirmation page is always blank. It works and it confirms the email account, but it does not redirect the user and throws a 406 error. It does the same for false confirmation attempts.

Routes seem to work fine, I have confirmable specified in my user model, and nothing else has changed.

Any ideas? Am I missing some settings or something I need to update for 1.4.9?

UPDATE

It seems to be a problem with the URL being generated. For some unknown reason it is prepending the confirmations URL with the user name? and that is causing it to break. But i'm still not sure how to fix it.

http://localhost:5000/users/confirmation.someusername?confirmation_token=R7apAPhC5c3rszvhsowp

The username in the URL above causes the process not to work.

I checked the diff between the controller in 1.2 (which works) and the new version.

1.2

  # GET /resource/confirmation?confirmation_token=abcdef
  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])

    if resource.errors.empty?
      set_flash_message :notice, :confirmed
      sign_in_and_redirect(resource_name, resource)
    else
      render_with_scope :new
    end
  end

1.4.9

  # GET /resource/confirmation?confirmation_token=abcdef
  def show
    self.resource = resource_class.confirm_by_token(params[:confirmation_token])

    if resource.errors.empty?
      set_flash_message(:notice, :confirmed) if is_navigational_format?
      sign_in(resource_name, resource)
      respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
    else
      respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
    end
  end

  protected

    # The path used after resending confirmation instructions.
    def after_resending_confirmation_instructions_path_for(resource_name)
      new_session_path(resource_name)
    end

    # The path used after confirmation.
    def after_confirmation_path_for(resource_name, resource)
      after_sign_in_path_for(resource)
    end

error

Started GET "/users/confirmation.sdfsdfsd?confirmation_token=vmxmx73xvM7sUfcvH9CX" for 127.0.0.1 at 2011-10-31 13:30:33 +0100
  Processing by Devise::ConfirmationsController#show as 
  Parameters: {"confirmation_token"=>"vmxmx73xvM7sUfcvH9CX"}
  SQL (1.1ms)   SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
 FROM pg_attribute a LEFT JOIN pg_attrdef d
 ON a.attrelid = d.adrelid AND a.attnum = d.adnum
 WHERE a.attrelid = '"users"'::regclass
 AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum

  User Load (1.2ms)  SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = 'vmxmx73xvM7sUfcvH9CX' LIMIT 1
  SQL (0.7ms)   SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
 FROM pg_attribute a LEFT JOIN pg_attrdef d
 ON a.attrelid = d.adrelid AND a.attnum = d.adnum
 WHERE a.attrelid = '"users"'::regclass
 AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum

Completed 406 Not Acceptable in 28ms
5
it is obvious that url is causing 406 /users/confirmation.someusername?... ".someusername" (includes dot) will be treated as format of response you want back. So maybe if you try prepand route rule in your route.rb file could fix this get /users/confirmation.:username", :controller => :users, :action=> confirmation ...Milan Jaric

5 Answers

5
votes

Look and see if you copied the have devise views, they may be out of date.

I had a similar issue getting odd user ids in my url, devise no longer uses user_confirmation_url in favor of confirmation_url (as of 1.0?, but it still worked a bit longer) so you might either delete your custom devise views or update the url helper.

7
votes

Someone else pointed me in the right direction but here's my exact solution. The problem was in the devise view templates which I had copied over from 1.2? It looks like they changed the link helper from user_confirmation_url() to simply confirmation_url().

old confirmation email

<p>Welcome <%= @resource.email %>!</p>

<p>You can confirm your account through the link below:</p>

<p><%= link_to 'Confirm my account', user_confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>

new confirmation template

<p>Welcome <%= @resource.email %>!</p>

<p>You can confirm your account through the link below:</p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>
1
votes

The latest devise code is

<p><%= link_to 'Confirm my account', model_confirmation_url(:confirmation_token => @model.confirmation_token) %></p>

version
devise-2.1.2

0
votes

For my case, I had custom views under views/devise e.g. views/devise/confirmations/new.html.erb using users_confirmation_url. I don't get any more errors after I moved those to under views/users and used confirmation_url.

0
votes

For my case (Rails 4.2 and devise 3.4.1)

fixing the generated view (in app/views/devise/mailer/confirmation_instructions.html.erb) required removing the @resource in the user_confirmation_url to just :

@token ) %>