2

I have the following custom route in my routes.rb file:

match '/security_users/:id/email_confirmation/:activation_code' => 'email_confirmation#new'

and want to create custom helper that generate the path above for specified SecurityUser. In my application_controler.rb file I have the method above:

class ApplicationController < ActionController::Base

  protect_from_forgery

  private

    def email_confirmation_path(security_user)
      "/security_users/#{security_user.id}/email_confirmation/#{security_user.activation_code}"
    end

    helper_method :email_confirmation_path

end

But when I call it in my /views/security_user_mailer/email_confirmation.text.erb template like this:

<%= email_confirmation_path(@security_user) %>

I get the following error:

NoMethodError at /security_users undefined method `email_confirmation_path' for #<#:0x6340ff53>

Could you advice?

EDIT:

Below you can find the process workflow:

First, when user is created the following line is executed

@security_user.send_email_confirmation

The method above is defined in the object model file like follows:

def send_email_confirmation
  SecurityUserMailer.email_confirmation(self).deliver
end

Then in the mailer controller, the method below is invoked:

def email_confirmation(security_user)
  @security_user = security_user
  mail to: security_user.email, subject: 'Account Created'
end

The previous method is using my template in which I need to call the custom path generator method:

<%= email_confirmation_path(@security_user) %>

but I get error that it is undefined.

gotqn
  • 42,737
  • 46
  • 157
  • 243

2 Answers2

3

Helper methods from controllers aren't available in mailer views. You should put your method to a helper module, for example app/helpers/application_helper.rb:

module ApplicationHelper

    def email_confirmation_path(security_user)
      "/security_users/#{security_user.id}/email_confirmation/#{security_user.activation_code}"
    end

end

And then you should say to your mailer class to use that helper module (suppose your mailer is app/mailers/mailer.rb):

class Mailer < ActionMailer::Base
  add_template_helper(ApplicationHelper)
end

After that you'll be able to use that helper in your mailer's views.

p.s. also notice that the private modifier in Ruby doesn't restrict access to a method only to class where it is defined. Subclasses are also able to call it. Private means that a method can not be called in relation to an object like so obj.my_method but can only be implicitly called in relation to self like so my_method.

trushkevich
  • 2,657
  • 1
  • 28
  • 37
1

The method is private in the ApplicationController, so subclasses cannot access it. You should put it in protected or public part of your class.

Ermin Dedovic
  • 907
  • 4
  • 6
  • Hi, I have made it public and it is giving me the same error. Also, as I have read the helper_method directive makes the method visible for all views - http://stackoverflow.com/questions/3992659/in-rails-what-exactly-do-helper-and-helper-method-do – gotqn Jun 15 '13 at 10:51
  • Did you put the helper declaration out of private section? – Ermin Dedovic Jun 15 '13 at 11:10
  • Can you try to restart rails server and post controller which renders template you mentioned? – Ermin Dedovic Jun 15 '13 at 12:01
  • Thanks, I have restarted the server but nothing changed. I have added to the question the process workflow - is it this what you need? – gotqn Jun 15 '13 at 12:12
  • Weird.. Can you confirm that your mailer controller is derived from ApplicationController? – Ermin Dedovic Jun 15 '13 at 12:20
  • Yes, it is. Any ideas what could I check or try in order to debug this> – gotqn Jun 15 '13 at 13:40
  • +1, Thanks for trying help me. It appears that controller helper methods are not visible in mailer views. – gotqn Jun 15 '13 at 17:22