質問

I am trying to generate mails with rails action mailer, but it seems like it is not doing everything completely right:

Here's where I create my mail:

class UserNotifier < ActionMailer::Base
    default from: 'mail@mail.com'

    def forgot_password(user)
        setup_email(user)
        @subject += "Password restoration"
        @url = url_for :controller => 'user_session', :action => 'reset_password',
                                        :id => user.pw_reset_code, :only_path => true
    end

    protected
    def setup_email(user)
        @subject = "[MY APP] "
        @sent_on = Time.now
        @user = user
        @content_type = "text/html"
        mail to: user.email
    end
end

And here's the html.erb that contains the mail.

<%= @user.name %>,
<br/><br/>
Restore password:
<%= @url %>

However, the subject of the mail is not what I said it should be.

But most importantly, @url is nil in the html.erb, however it is generated correctly in forgot_password, I tested it.

Why is it nil? And what can I do to render the URL?

役に立ちましたか?

解決

Mails are sent when you call method deliver on ActionMailer::Base object.
Your method forgot_password does not return this object.
the line mail(to: .....) should be the last one in the forgot_password routine

Run rails console and type this to see what returns

ActionMailer::Base::mail(to: 'example.com', subject: 'hello')

then call #deliver on it.

他のヒント

The line

mail to: user.email

Is actually causing your email to send.

Because you are calling this in setup_email, you are actually sending the email AND THEN trying to change the subject and URL after it is sent.

If you ignore the setup method that you have for a second, this is what your code would look like in the order you currently have it:

    @subject = "[MY APP] "
    @sent_on = Time.now
    @user = user
    @content_type = "text/html"
    mail to: user.email  << MAIL IS SENT HERE
    @subject += "Password restoration"
    @url = url_for :controller => 'user_session', :action => 'reset_password',
                                    :id => user.pw_reset_code, :only_path => true

Update your code to call the mail command last, for example:

def forgot_password(user)
    setup_email(user)
    @subject += "Password restoration"
    @url = url_for :controller => 'user_session', :action => 'reset_password',
                                    :id => user.pw_reset_code, :only_path => true
    mail to: user.email
end

protected
def setup_email(user)
    @subject = "[MY APP] "
    @sent_on = Time.now
    @user = user
    @content_type = "text/html"
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top