Send mail at particular time in action mailer using delayed job - ruby-on-rails

def time_confirmation(user)
#user = user
if(#time == (Time.now()))
mail(:to => user.email)
end
end
Is this right? Mail has to be sent at current time.

On your controller do something like:
def create
#user = User.create(user_params)
DelayedEmailJob.new(#user.email).enqueue(wait: 30.minutes)
redirect_to root_path
end

Related

Rails: Why is only one email sent to the last member of a loop?

I am very much a rails novice!
I am trying to write a method for a kind of on-line committee meeting. There are a fixed number(9) of users. When a user proposes a topic for discussion and/or voting the submit button needs to send an email to all members.
in app/mailers/user_mailer.rb I have:-
class UserMailer < ApplicationMailer
def new_topic_alert(topic)
#users = User.all
#users.each do |user|
mail to: user.email, subject: "New topic alert"
end
end
end
as part of app/controllers/topics_controller.rb I have:-
def send_alert
#topic = Topic.new(topic_params)
UserMailer.new_topic_alert(#topic).deliver_now
end
and:-
def create
#topic = Topic.new(topic_params)
if #topic.save
send_alert
flash[:info] = "New Topic alert emails sent."
redirect_to root_url
else
render 'new'
end
end
Please, why does the loop in user_mailer only send an email to the final person of the list. By incorporating "byebug" I have shown that it goes through all the user emails.
Try like below:
def send_alert
#topic = Topic.new(topic_params)
users = User.all
users.each do |u|
UserMailer.new_topic_alert(#topic, u).deliver_now
end
end
and update the mailer like
class UserMailer < ApplicationMailer
def new_topic_alert(topic,user)
mail to: user.email, subject: "New topic alert"
end
end

How I Pass parameters from View to Controller In Ruby

#app/controllers/sessions_controller.rb
class SessionController < ApplicationController
def new
#session = Session.new
end
def fetch
##user = User.session(params [:user])
redirect_to "http://www.google.com"
end
def create
emai = params[:email]
puts emai
user = User.find_by(:email => session[:emai])
#user = User.find_by (params [:email])
#user = User.find_by email: 'abc#xyz.com'
#user = User.find_by(params[:Email])
#if (session[:Email] = user.email)
if (user)
redirect_to "http://www.yahoo.com"
flash[:notice] = "You signed up successfully"
flash[:color]= "valid"
else
flash[:notice] = "Form is invalid"
flash[:color]= "invalid"
redirect_to "http://www.google.com"
end
#redirect_to "http://www.yahoo.com"
end
end
every time i execute my view i get redirected to google.com even though i pass the parameters.
Edit by R Peck:
My logic should send people to Yahoo if the params are set, but still sends to Google, how can I fix this?
Try:
user = User.find_by(:email => params[:sessions][:emai])
You are not getting the value of email if you only call params[:email] you should call parent first before calling the child params[:sessions][:email].
Several things wrong with your code.
Here's what I'd write:
#app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
#session = Session.new
end
def create
email = params[:sessions][:email]
user = User.find_by email: email
url = user ? "google" : "yahoo"
colour = user ? "valid" : "invalid"
notice = user ? "You signed up successfully" : "Your form is invalid"
redirect_to "http://#{url}.com", notice: notice, color: colour
end
private
def session_params
params.require(:session).permit(:session, :params)
end
end
OOP
I think this may be a little advanced but I'll write it anyway, for my own benefit.
Rails is object orientated (it's built on Ruby which is an OOP language). This means that each time you create/call a controller, it should be centered around objects.
A good example for you would be the Devise controllers.
This has a sessions_controller which essentially allows you to CRUD (Create Read Update Destroy) a session. This is the correct way to use a controller.
Your implementation seems to be dealing with a user, rather than a session, and as such you'd be best using a users_controller to fix it:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new
#user.save
end
end
Having said that, it does seem that you're probably going to resolve the issue to make it so that you can use the User to build a new session.
I guess it's best to remember that you have to ensure you're able to appreciate a good structure for your application

how to identify the method name that calling the particular function?

I want to change the subject of mail according to actions(create, update), that call the mailer. How to do this? (ex. during creation, subject is User created and for update , user updated)
def create
#user = User.new(params[:user])
#user.save
Mailer.notify(#user).deliver
end
def update
#user = User.find(params[:id])
#user.update
Mailer.notify(#user).deliver
end
mailers.rb
def notify(user)
#user =user
mail(:to =>#use.mail :subject => "created")
end
# controller
def create
#user = User.create(params[:user])
Mailer.notify(#user, 'created').deliver
end
def update
#user = User.find(params[:id])
#user.update
Mailer.notify(#user, 'updated').deliver
end
# mailers.rb
def notify(user, action_name)
#user = user
mail(:to => #user.mail, :subject => "User #{action_name}")
end
You can get the name of the calling method by using
caller_locations(1)[0].label
Example:
def bar
caller_locations(1)[0].label
end
def foo
bar
end
foo # => "foo"

Use different variable depending on which view was used in Rails 4

I'm using Mailboxer so that users can reply to posts in my site. There are two types of post models in my site which users might reply to, Requests and Offers.
Here is my messages controller:
class MessagesController < ApplicationController
# GET /message/new
def new
#request = Request.find(params[:request])
#message = current_user.messages.new
#user = #request.user
end
def reply
#conversation ||= current_user.mailbox.conversations.find(params[:id])
end
# POST /message/create
def create
#user = User.find(params[:user])
#body = params[:body]
#subject = params[:subject]
current_user.send_message(#user, params[:body], params[:subject])
flash[:notice] = "Message has been sent!"
redirect_to :conversations
end
end
In the new action, I'm using #request, but if I reply to an Offer post, I'll need to use an #offer variable. Is there a way I can use an if statement to choose between an #offer and #request depending on the view the new action is called from? Is this the best way to go about this?
It's not the most graceful thing in the world but something as simple as this should work.
if params[:request]
#request = Request.find(params[:request])
else
#offer = Offer.find(params[:offer])
end

Rails - Mailer Instance Variable Nil in Email View

I am attempting to create beta invitations using the structure from railscasts episode 124, updated for rails 3.2.8.
Currently, the invitation email gets sent, but does not contain the url (which includes the invitation token) for users to follow to sign up because the instance variable I am creating in ActionMailer (#invitation_link) is nil in the view. Inspecting #invitation_link in the ActionMailer controller shows that it is pointing to the correct url, but it is nil in the view.
I have also checked out the following questions and none of the solutions have worked for me:
How do you use an instance variable with mailer in Ruby on Rails?
https://stackoverflow.com/questions/5831038/unable-to-access-instance-variable-in-mailer-view
Actionmailer instance variable problem Ruby on Rails
ActionMailer pass local variables to the erb template
Relevant code snippets below:
invitations_controller.rb
class InvitationsController < ApplicationController
def new
#invitation = Invitation.new
end
def create
#invitation = Invitation.new(params[:invitation])
#invitation.sender = current_user
if #invitation.save
if signed_in?
InvitationMailer.invitation(#invitation).deliver
flash[:notice] = "Thank you, invitation sent."
redirect_to current_user
else
flash[:notice] = "Thank you, we will notify when we are ready."
redirect_to root_url
end
else
render :action => 'new'
end
end
end
in invitation_mailer.rb file
class InvitationMailer < ActionMailer::Base
default from: "holler#thesite.com", content_type: "text/html"
def invitation(invitation)
mail to: invitation.recipient_email, subject: "Invitation"
#invitation_link = invited_url(invitation.token)
invitation.update_attribute(:sent_at, Time.now)
end
end
views/invitation_mailer/invitation.text.erb
You are invited to join the site!
<%= #invitation_link %> # INSTANCE VARIABLE THAT IS NIL IN VIEW
routes.rb (only showing relevant line)
match '/invited/:invitation_token', to: 'users#new_invitee', as: 'invited'
try this way
This is your InvitationMailer
def invitation(invitation)
#invitation = invitation
mail(:to => #invitation.recipient_email, :subject => "Invitation")
end
now, in your InvitationsController
if signed_in?
#invitation.update_attribute(:sent_at, Time.now)
InvitationMailer.invitation(#invitation).deliver
...
else
...
end
now, views/invitation_mailer/invitation.text.erb
You are invited to join the site!
<%= invited_url(#invitation.token) %> # INSTANCE VARIABLE THAT IS NIL IN VIEW
try this...
#invitation_link = invited_url(invitation.token, :host => "localhost:3000")

Resources