Eric Poretsky Eric Poretsky - 5 months ago 50
Ruby Question

Action Mailer Missing Template error unless body is specified

Hello I am getting a missing template error in my code for a contact form I am making despite the files being in what I believe to be the proper place and everything else exactly like the action mailer basics tutorial I followed. I even remade the mailer and it still won't work.

contactmailer

class ContactMailer < ApplicationMailer

default from: 'test@example.com'

layout 'mailer'

def notify(contact)
@contact = contact
mail(to: 'text@example.com', subject: 'Notification')
end
end


contact controller

def create

@contact = Contact.new(contact_params)

if @contact.save

ContactMailer.notify(@contact).deliver_now
redirect_to root_path

else
render :new

end


end


views/contact_mailer/notify.text.erb
Test

config/development.rb

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false

# Do not eager load code on boot.
config.eager_load = false

# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false

# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = true

# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log

# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load

# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true

# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
config.assets.digest = true

# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true

config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
# SMTP settings for gmail
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:enable_starttls_auto => true,
:user_name => 'example@gmail.com',
:password => 'examplepassword',
:authentication => "plain",
:ssl => false
:openssl_verify_mode => 'none'
}
end


IF i add a body param to mail it works but doesn't work otherwise.

EDIT: ERROR I RECEIVE

ContactMailer#notify: processed outbound mail in 31.9ms
Completed 500 Internal Server Error in 61ms (ActiveRecord: 3.7ms)

ActionView::MissingTemplate (Missing template layouts/mailer with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :slim, :coffee, :jbuilder]}. Searched in:
* "/home/ubuntu/workspace/autosales2/app/views"
):
app/mailers/contact_mailer.rb:7:in
notify'
app/controllers/contacts_controller.rb:15:in
create'

Rendered /usr/local/rvm/gems/ruby-2.2.2/gems/actionpack-4.2.5.1/lib/action_dispatch/middleware/templates/rescues/_source.erb (11.1ms)
Rendered /usr/local/rvm/gems/ruby-2.2.2/gems/actionpack-4.2.5.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (5.2ms)
Rendered /usr/local/rvm/gems/ruby-2.2.2/gems/actionpack-4.2.5.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.3ms)
Rendered /usr/local/rvm/gems/ruby-2.2.2/gems/actionpack-4.2.5.1/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb within rescues/layout (93.5ms)

Answer

You only have plain text template in place. What about the .html.erb?

Try this code to limit your mailer to only sending plain text emails if that's what you want:

def notify(contact)
    @contact = contact
    mail(to: 'text@example.com', subject: 'Notification') do |format|
        format.text
    end
end

Otherwise, if you want html emails, provide their template as well.

UPDATE

From the error text it is apparent that the mailer's layout template cannot be found. You have this in your mailer:

layout 'mailer'

This means any particular action template will be rendered as part of the mentioned layout template. Therefore you need this layout template in place. You can see that the mailer expects it to be called layouts/mailer and looks for it in app/views, which makes it

app/views/layouts/mailer.html.erb # for html emails
app/views/layouts/mailer.text.erb # for plain text emails

If you do not need a common layout for the emails, you can just remove the layout 'mailer' line and it should work.