Why "Action Mailer" is not rendering the email template? - ruby

I am using "Action Mailer" in Ruby on Rails application to send emails. I have the following action mailer:
class SecurityUserMailer < ActionMailer::Base
default from: 'myemail#gmail.com'
def password_reset(security_user)
#security_user = security_user
mail to: security_user.email, subject: 'Password Reset'
end
def email_confirmation(security_user)
#security_user = security_user
mail to: security_user.email, subject: 'Account Created'
end
end
I am successfully sending emails but the second method (email_confirmation) is not using the corresponding template.
The email templates are in views/security_users_mailer folder and named as follows:
email_confirmation.txt.erb
password_reset.txt.erb
Why only the password_reset template is used?
Note, firstly, I thought that maybe there is something wrong with the code in my template but then I replace it with text content and it is not rendered again.

Rails 4 I had this same issue, but mine was caused by having an empty layout in layouts/mailer.html.erb

The issue was caused by file extension TYPO. I have
email_confirmation.txt.erb
and a mailer template should be with extension text or html.
As you see from the official docs - the template with the same mailer action is used by default if exists.

I believe an alternative would be to specify the template you would like to render the following is an example how you may go about this
class SecurityUserMailer < ActionMailer::Base
default from: 'myemail#gmail.com'
def password_reset(security_user)
#security_user = security_user
mail to: security_user.email, subject: 'Password Reset'
end
def email_confirmation(security_user)
#security_user = security_user
mail (:to => security_user.email,
:subject => 'Account Created',
:template_path => 'email_confirmation.txt.erb',
:template_name => 'another')
end
end
Take a look at the following should provide some further insight:
Mailer Views
or look at
Api Ruby on Rails You will see example where it says Or even render a special view so that alternatively you could have inside your mail block the following:
mail (:to => security_user.email,
:subject => 'Account Created') do |format|
format.html { render 'another_template' }
format.text { render :text => 'email_confirmation.txt.erb' }
end
This should shed some light on what you are trying to accomplish

Related

How do I create a dashboard link in my Rails user controller?

I’m using Rails 5. When my user is logged in, I want to replace the ‘/users/4’ action with a generic ‘/dashboard’ home link. I would also like the remove the user’s ability to typing in ‘/users/##’ into the browser, instead only allowing them to visit ‘/dashboard’. How do I do this? Currently, in my config/routes.rb I have
get '/dashboard', to: 'users#show'
resources :users
and in my users_controller.rb file I have
def show
#user = User.find(params[:id])
#user_subscriptions = UserSubscription.find_active_subscriptions_by_user(#user)
end
But currently when I visit “/dashboard” in my browser, I get the error
Couldn't find User with 'id'=
How can I set up my route to disable the show action but allow /dashboard to successfully navigate to the action above?
What I like to do is something like this
get '/dashboard' => 'users#show', as: :dashboard
now on your view you can do
link_to 'Dashboard', dashboard_path(current_user)
and in the controller you can do
def show
params[:id] == current_user.id unless params[:id]
#user = User.find(params[:id])
#user_subscriptions = UserSubscription.find_active_subscriptions_by_user(#user)
end

How do I configure Pony/Sinatra to send data from two different forms?

I've a web page with two forms on it.
There is a general contact form and a shopping cart like response section from customers for sale people to respond to with the customer's choices.
I know nothing about Ruby and I'm having trouble assimilating on just how this is supposed to work with the routes pointing to the Sinatra email template.
Code as follows...
**** Mailer.rb ****
require 'sinatra'
require 'pony'
Pony.options = {
via: :smtp,
via_options: {
openssl_verify_mode: OpenSSL::SSL::VERIFY_NONE,
address: 'mail.myserver.com',
port: '587',
user_name: 'test#myserver.com',
password: '********',
authentication: :plain,
domain: "mail.myserver.com" # the HELO domain provided by the client to the server
}
}
class Mailer < Sinatra::Base
post '/contact' do
options = {
from: "test#myserver.com",
to: 'client#clientaddress.com',
subject: "Contact Form",
body: "#{params['name']} <#{params['email']}> \n" + params['message']
}
Pony.mail(options)
redirect '/'
end
post '/build-tool' do
options = {
from: "test#myserver.com",
to: 'client#clientaddress.com',
subject: "Custom Build Form",
body: "#{params['name']} <#{params['email']}> \n" + params['message']
}
Pony.mail(options)
redirect '/'
end
end
***** HTML Form One *****
<form class="form-horizontal" method="POST" action="/contact">
contact information inputs
</form>
***** HTML Form Two *****
<form class="form-horizontal" method="POST" action="/build-tool">
build tool inputs
</form>
***** Config.rb *****
map '/contact' do
run Mailer
end
map '/build-tool' do
run Mailer
end
Sinatra directly figures out routes, so if you make a POST request to '/contact', it will invoke the code inside the post '/contact' definition, so you don't have to do whatever you're doing in config.rb.
When you redirect '/', it means that the server expects a root route to be defined, which is missing in your class definition.
The HTML tags go into a view which gets rendered via Sinatra.
These are the three things that require changes. First we define a / route which renders the HTML form elements we need:
# mailer.rb
require 'sinatra/base' # note the addition of /base here.
require 'pony'
# pony options code same as before
class Mailer < Sinatra::Base
get '/' do
erb :index
end
# post routes same as before
end
HTML gets rendered from a view template. By default, Sinatra will look up views inside the views/ directory.
# views/index.erb
<form class="form-horizontal" method="POST" action="/contact">
contact information inputs
submit button
</form>
<form class="form-horizontal" method="POST" action="/build-tool">
build tool inputs
submit button
</form>
ERB is a templating languages that's bundled with the Ruby language, so you don't have to install any new gem. There are more languages listed in the documentation.
And the config.ru will look like:
# config.ru
# Note the file change. This is called a Rackup file. config.rb is
# a more general purpose file used by many libraries, so it's better
# to keep this separate.
require_relative 'mailer.rb'
run Mailer
The problem here is that each form corresponds to a specific route, sending the form data to that action. In other words, "form one" sends all input fields it contains in a POST request to /contact and "form two" sends all its input fields in a POSTto /build-tool.
My suggestion would be to incorporate both forms together into one form and just play with the styling of the page to make it look like two. That way you will get all input fields submitted to your Sinatra app together and you can send whatever mail best applies to what was input.

sinatra-flash gem isn't working

I attempted to use the sinatra-flash gem with my application and get an "undefined local variable or method 'flash'" error when I try to run it.
my_app:
require 'sinatra/base'
require 'sinatra/flash'
class GGInfraUserManager < Sinatra::Base
enable :sessions
register Sinatra::Flash
...(rest of app)
post '/' do
flash[:error] = "Password must be a minimum of 8 characters" unless new_password.match /.{8}/
log.info "#{Time.now} password meets policy requirements"
end
redirect '/'
end
In my erb view file (at the top):
<div id="flash" class="notice">
<a class="close" data-dismiss="alert">×</a>
<%= flash.now[:error] %>
</div>
Can someone please tell me how to correct this error so that the flash functionality will work?
While the gem seems comfortable enough to use why not implement it yourself. It's in fact just a couple of lines:
#in your app.rb:
helpers do
#a partial helper
def partial(template, locals = {})
slim template, :layout => false, :locals => locals
end
#the flash helper
def flash
#flash = session.delete(:flash)
end
end
get '/' do
session[:flash] = ["Some happy news", "alert-success"]
end
Then you can add a partial view which I called partial_flash.slim
-if flash
-message, status = #flash
.alert class=(status) = message
You call that partial usually from your layout file or any other view that needs a flash message:
==partial :partial_flash
So a route is called, the layout is loaded and checks if flash. If there is, it displays a flash message with a specified class. I use Twitter Bootstrap, so alert-success is a green message box.
You can see an example app here: https://github.com/burningTyger/farhang-app

Rails - trying to create simple ajax example

The code below is not working for some reason. As I click at "test" it redirects me to /home/test and shows nothing.
view/home/index.html.erb
<%= link_to "test", { :controller => "home", :action => "test" }, :remote => true %>
<div id='test_div'>
</div>
view/home/index.js.erb
$("#test_div").html("some text");
controller
class HomeController < ApplicationController
def test
"test123 test456"
respond_to() do |format|
format.js {render :layout => false}
end
end
end
What should I do to refresh div_test using ajax?
What does your routes file look like? Can you post it on here? Do a rake routes and post the output.
Here are some things that may help you:
Rails documentation for routing
Also, check out the Ajax on Rails Documentation and the section on link_to_remote. The link_to_remote function is not in Rails. What version of rails are you on? Bash: $ rails -v
Look at this answer on S.O. regarding AJAX on Rails calls.
Edit: Here is another answer regarding this that may help.
Another answer on SO for updating existing element
Edit: looking over this again, I dont think you need () after respond_to or the {...} in link_to. Look at the third link. I think you need to put the page in a partial and render it. Its not rendering right now since its render :layout => false

Ruby w/ Sinatra: Could I have an example of a jQuery AJAX request?

%a{:href => "/new_game?human_is_first=true", :remote => "true"}
%span Yes
Above is my link. Just wondering how to handle this. I need to be able to execute some javascript. Below is a .js.erb file from back when I using rails.
$('.welcome_container').fadeOut(500, function(){
$( '.shell' ).html( "<%= escape_javascript( render( :partial => "board/board" ) ) %>" );
$('.board_container').fadeIn(500);
});
So, my question is, Once /new_game is called in app.rb, I want to be able to send some javascript to the current page (without leaving the page, and have the partial rendered)
See my answer to your other recent question for a comprehensive setup for sending and receiving HTML partials in a production Sinatra app.
As Sinatra is a nice lightweight framework, you are free (forced?) to come up with your own workflow and code for implementing partials and handling such calls. Instead of my explicit route-per-partial, you might choose to define a single regex-based route that looks up the correct data based on the URL or param passed.
In general, if you want Sinatra to respond to a path, you need to add a route. So:
get "/new_game" do
# This block should return a string, either directly,
# by calling haml(:foo), erb(:foo), or such to render a template,
# or perhaps by calling ...to_json on some object.
end
If you want to return a partial without a layout and you're using a view, be sure to pass layout:false as an option to the helper. For example:
get "/new_game" do
# Will render views/new_game.erb to a string
erb :new_game, :layout => false
end
If you want to return a JSON response, you should set the appropriate header data:
get "/new_game" do
content_type :json
{ :foo => "bar" }.to_json
end
If you really want to return raw JavaScript code from your handler and then execute that...well, here's how you return the JS:
get "/new_game" do
content_type 'text/javascript'
# Turns views/new_game.erb into a string
erb :new_game, :layout => false
end
It's up to you to receive the JS and *shudder* eval() it.

Resources