1
votes

I'm using Rails 4, subdomains with Apartment gem, and Devise (3.4.1). I have a problem with the email confirmation link generated by Devise Confirmable. When a user creates an account, they get an email:

You can confirm your account email through the link below:

http://lvh.me:3000/users/confirmation?confirmation_token=xsTNUw5oQYTPf_CBwZXD

However, it doesn't work since the user's subdomain is not on the link, it should be e.g.

http://mysubdomain.lvh.me:3000/users/confirmation?confirmation_token=xsTNUw5oQYTPf_CBwZXD

If I manually add the subdomain link on the browser, it does confirm the account.

How could I change the confirmation_instructions.html.erb link_to to generate a confirmation_url with the subdomain in front of it? For example:

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

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

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

I tried e.g. https://github.com/plataformatec/devise/wiki/How-To:-Send-emails-from-subdomains and https://github.com/fortuity/rails3-subdomain-devise/wiki/Tutorial-%28Walkthrough%29 But neither worked for me, I got an error:

 "NoMethodError in Accounts#create, undefined method `subdomain' for #<User:0x...>"

Here is the create action in my AccountsController:

def create
  @account = Account.new(account_params)
    if @account.valid? && verify_recaptcha
       Apartment::Tenant.create(@account.subdomain)
       Apartment::Tenant.switch(@account.subdomain)
       @account.save
       @account.create_default_lists
       redirect_to new_user_session_url(subdomain: @account.subdomain)
    else
       render action: 'new'
    end
end

Here are my routes:

user_confirmation     POST   /users/confirmation(.:format)                         devise/confirmations#create
new_user_confirmation GET    /users/confirmation/new(.:format)                   devise/confirmations#new
                      GET    /users/confirmation(.:format)                       devise/confirmations#show

In development.rb I have set:

config.action_mailer.default_url_options = { host: "lvh.me:3000" }

In ApplicationController I have:

protect_from_forgery
before_filter :authenticate_user!, :set_mailer_host

private

def current_account
   @current_account ||= Account.find_by(subdomain: request.subdomain)
end

helper_method :current_account

def set_mailer_host
   subdomain = current_account ? "#{current_account.subdomain}." : ""
   ActionMailer::Base.default_url_options[:host] = "#{subdomain}lvh.me:3000"
end

end

And here is the error on the console:

ActionView::Template::Error (undefined method `subdomain' for #<User:0x007fbfcc27e5a0>):
    2: 
    3: <p>You can confirm your account email through the link below:</p>
    4: 
    5: <p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token, **:subdomain => @resource.subdomain**) %></p>
  app/views/devise/mailer/confirmation_instructions.html.erb:5:in `_app_views_devise_mailer_confirmation_instructions_html_erb___2999600516167812245_702'
  app/controllers/accounts_controller.rb:14:in `create'
2
Too funny! I have the exact opposite problem. I got my links to show the subdomain, but they only work to confirm if I delete the subdomain and submit.Jon Kern

2 Answers

4
votes

I managed to solve this by using the following in confirmation_instructions.html.erb. This works for my setup, since I'm using the Apartment gem:

<%= link_to 'Confirm my account', user_confirmation_url(confirmation_token: @token, subdomain: Apartment::Tenant.current) %>
0
votes

Did you confirm that in your link_to, the :subdomain => @resource.subdomain part actually has a legit value? In other words, that your "resource" (probably User model) has a subdomain method?