ActionView is missing template in Preview. How to resolve? - ruby-on-rails

I am currently trying to have ActionMailer send an email with Letter_Opener gem. When I try to view the preview with localhost:3000/mailer/order_mailer the terminal logs this error:
app/mailers/order_mailer.rb:10:in `new_order_email'
Started GET "/rails/mailers/order_mailer/new_order_email" for ::1 at 2023-01-27 16:27:38 -0800
Processing by Rails::MailersController#preview as HTML
Parameters: {"path"=>"order_mailer/new_order_email"}
OrderMailer#new_order_email: processed outbound mail in 1.2ms
Completed 500 Internal Server Error in 24ms (Allocations: 9119)
ActionView::MissingTemplate (Missing template order_mailer/new_order_email with "mailer".
Searched in:
* "order_mailer"
):
app/mailer/order_mailer.rb:
class OrderMailer < ApplicationMailer
default from: 'actionMailerTester2301#gmail.com'
# layout "order_mailer"
def new_order_email
#email = 'joeDANE#example.com'
mail(to: #email, subject: "Thank you for your donation.")
end
end
On the browser, the mail(to:..... line is pointed out. I've looked through multiple stackoverflow entries and I can't figure it out, though I chalked it up to my unfamiliarity with Ruby to not being about to understand the problem.
I'm hoping if I can figure out why the preview isn't working that I'll figure out the secondary problem with the Letter Opener gem.

Ruby on Rails prefers following certain conventions over configuration. In most cases, it is much easier and straight-forward to just follow the Rails' way instead of over-customizing your application.
In this specific example, I suggest to not change or re-configure where Rails finds the mailer views, but to just place the views in the default folder.
Following the conventions, for the mailer views and how your mailer and its method is named, the views should be named and located like this in the app/views folder (not in app/mailers/views):
app/views/order_mailer/new_order_email.html.erb
app/views/order_mailer/new_order_email.text.erb
Read about mailer view naming in the official Rails Guides.

Related

Rails: Use of absolute path in Rails 6

Recently, I've upgraded a Rails app that I'm maintaining to Rails 6 RC2 (coming from 5.2.3). So, right after upgrading, I ran the automated tests (RSpec) and the test output gave me lots of deprecation warnings. One of those warnings was:
DEPRECATION WARNING: render file: should be given the absolute path to a file
So I went to the view file that triggered the warning, and made the changes as follows,
Before:
render file: 'devise/sessions/new'
After:
render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html.slim')
I ran the tests again, no output of deprecation warnings was seen. However, after switching to absolute paths, the view is now only rendering plain HTML code but if I remove the .slim extension, i.e.
render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html')
The corresponding view is rendered properly but now the test will complain about not using absolute paths. Is there a way to fix this or is this a Rails/Slim bug?
In your case it looks like you want to render a normal view, i.e. a template.
In that case using the file option is not the recommended way. Instead you should be using the template option.
render template: 'devise/sessions/new'
Or even better, you can use this shortcut:
render 'devise/sessions/new'
Background
The file option is intended to render a view which is outside your Rails application, where you can't rely on Rails' view lookup logic. Consequently Rails wants to have an absolute path. Demanding an absolute path also forces the developer to think about relative path segments (/../).
Omitting the .slim extension and then having the file processed by the template engine is a feature intended for templates. Using file seems to provide the very same functionality, but my guess is that this is just a side effect of the internal workings of the view path lookup. It looks like the Rails developers want to improve the distrinction between files and templates in the future and deprecating relative files is an intermediate step to not break too many existing applications which rely on using file and still expect the features of a template.
PS: It is not necessary to manually split your path. So if you for some reason still want to use file with an absolute path, instead of
render file: Rails.root.join('app', 'views', 'devise', 'sessions', 'new.html.slim')
use this
render file: Rails.root.join('app/views/devise/sessions/new.html.slim')
I had this same challenge when working on Rails 6 API-only application.
I wanted to render a static page from a controller called home_controller.rb
Here's my code:
require 'rails/application_controller'
class HomeController < Rails::ApplicationController
def index
render file: Rails.root.join('public/index.html')
end
end
But when I try accessing the page I get the error:
Started GET "/favicon.ico" for ::1 at 2021-02-23 16:25:41 +0100
Processing by HomeController#index as */*
Parameters: {"other"=>"favicon"}
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms | Allocations: 301)
ArgumentError (`render file:` should be given the absolute path to a file. '/home/my-computer/Projects/MyWebsite/public/index.html' was given instead):
Here's how I solved it:
The issue was that I was missing the file index.html in the directory public, so Rails could not locate it.
All I had to do was to add the file index.html in the directory public. This time when I tested it was fine.
That's all.
I hope this helps

Rails controller wrong template location

I have a model, controller and routes configured sucessfully with the name animegif.
In my show method, it looks under application/show instead of views/animegif/show.
Missing template animegif/show, application/show
"searched in /Users/myName/Desktop/testapp/app/views
My easy fix was adding this method to my animegif controller but I do not understand why is it not searching under views/animegif/show by default.
When I followed the rails tutorial by Michael Hartl, the paths were located correctly. Is there something I am doing wrongly?
Name of controller: animegifs_controller, model: animegif
For my routes I am using resources to generate the default routes for the model
def self.controller_path
"animegif"
end
If you read the error message once again you can see it first animegif/show directory of your views. If rails does not find the required template in that directory then it falls back to app/views. You are only getting this error message because either the show.html.erb is not there or you have any typo error.
If you are more curious about how rails finds your views, please refer to this post by Andy Wang. He has explained it in a better way.
Regarding the error message it is looking in app/views/animegif/ and app/views/application/ but cannot find the template. So you probably have a typo in the template's name show.html.erb (or other formats than html) in the respective directory.

sending emails using templates in Mandrill

I've read through the docs and still am unclear on how to actually use these templates in mandrill.
Currently I have a rails app with the standard Rails mailers (located in: App > views > welcome_mailer > welcome_email.html.erb) being sent through the Mandrill SMTP setup. This is working fine.
Now, I have a template in Mandrill ready to go, now what?
How do I actually use this template, do I need to adjust the code on my app to make a different call, or do I need to do something on the mandrill dashboard to tell it to use the new template instead of the rails version being sent now.
How do I actually use this template?
Thank you in advance.
You can use mandrill_mailer gem, inherit your mailer from MandrillMailer::TemplateMailer and then send it as usual InvitationMailer.invite(invitation).deliver.
Without any gems :
To use mandrill template you first need to create one in your mandrill account and then in your mailer add a correct header which tells the name of the template. Then mandrill will by magic automatically call that template.
Example:
# app/mailers
class CardMailer < ActionMailer::Base
default from: "admin#domain.ch"
def welcome(card)
mail to: card.responsable.email,
from: "\"Andrey\" <admin#domain.ch>",
subject: 'Welcome in my website'
headers['X-MC-MergeVars'] = "{\"TYPE\":\"#{card.card_type.name}\"}" # variables
headers['X-MC-Template'] = "welcome" # template
headers['X-MC-AutoText'] = 1 # generate text version
headers['X-MC-InlineCSS'] = "true" # inline css
end
end
In my case, it uses my "welcome" template. Just use the name of your mandrill template.
As you can see, there are many other headers available. See the full-list here.
Note : even if you don't use rails template any more, you still need one in your view.

Where is the default "Welcome Aboard" page located in my app?

I scoured my app's directories, and I can't find the html page for the default rails Welcome Aboard page. I also cannot find a route for the default Welcome Aboard page in routes.rb. How does my rails app route http://localhost:3000/ to a non-existent page in my app?
The rails server produces this information:
Started GET "/" for 127.0.0.1 at 2013-07-31 02:00:13 -0600
Processing by Rails::WelcomeController#index as HTML
Rendered /Users/7stud/.rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/railties-4.0.0/lib/rails/templates/rails/welcome/index.html.erb (0.1ms)
Completed 200 OK in 3ms (Views: 2.5ms | ActiveRecord: 0.0ms)
So it looks to me like there is a controller buried in a gem somewhere that handles the request.
Since Rails 4, the "Welcome aboard" page is no longer located in public/index.html. It is - as you've already detected - located inside one of the Rails gems.
So you already answered the question yourself; the "Welcome aboard" page is - in your case - located at /Users/7stud/.rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/railties-4.0.0/lib/rails/templates/rails/welcome/index.html.erb
To get rid of it, following the instructions on the page. Basically they are:
Create a controller
Add a root route in config/routes.rb to route to that newly created controller.
As for how the request to your application ends up at a controller inside railties, let's dig into the gem: Inside Rails::Application::Finisher we find this:
initializer :add_builtin_route do |app|
if Rails.env.development?
app.routes.append do
get '/rails/info/properties' => "rails/info#properties"
get '/rails/info/routes' => "rails/info#routes"
get '/rails/info' => "rails/info#index"
get '/' => "rails/welcome#index"
end
end
end
This block adds a few routes to your application when running in development mode - one of those is the route to the "Welcome aboard" action: get '/' => "rails/welcome#index"
This - like any other initializer - is done when your start your application server (running rails server or however you do it). In the case of Finisher, all its initializer are run after all other initializers are run.
Note how the routes are appended so that they are appear last in the Routeset. This, combined with the fact that Rails uses the first matching route it finds, ensures those default routes will only get used if no other route is defined.

Rails 3 renders Haml file as Html

Following the guide at http://github.com/fortuity/rails3-mongoid-devise I've managed to setup Rails3 with Haml, Devise, and Mongoid. (As a side-note, the guide is really detailed; recommended reading for new Rails users!)
Only problem is I can't get Rails to render my Haml views:
Started GET "/" for 127.0.0.1 at 2010-07-01 14:40:23 +0200
Processing by HomeController#index as HTML
MONGODB miabreto_development['users'].find({}, {})
Rendered home/index.html.haml within layouts/application (4.2ms)
Completed 200 OK in 21ms (Views: 21.0ms)
Note that it doesn't return a missing template error, it just renders the view as plain html. The filename follows the convention:
app/views/home/index.html.haml
and in the Gemfile I have:
# Bundle gems needed for Haml
gem 'haml', '3.0.13'
gem "rails3-generators", :group => :development
Since I am new to Rails, I am not sure what the execution path looks like for deciding what renderer to use, etc. Can someone suggest what I may have missed in my setup or where to look for errors? (This is Rails.3.beta4)
Couple of things
First of all, rails will render index.html.erb if it is present in the views folder. It will do this before it renders index.html.haml. So, take a look in your views folder and if you do have a file called index.html.erb, then just delete it and rails should start doing haml for you
Secondly, even when it does render the haml version of your file, it will still read " Processing by HomeController#index as HTML"
Hope this helps, and yeah, it's a great tutorial, read it myself a few days ago
PS - two ways to tell if your template is doing haml
add the words "hello from haml" into your haml file
look at the output server output you should see something along the lines of:
Rendered home/index.html.haml within layouts/application (42.9ms)

Resources