Controller
def mail_test
#user = User.all.first
#course = Course.all.first
examplemailer.student_reminder(#user, #course).deliver
redirect_to '/'
end
Mailer controller
def student_reminder(user, course)
#user = user
#course = course
#url = 'http://www.google.com'
mail to: #user.email, subject: "Good Job!"
end
Here, I need to use <%=#user.name%> and <%= #course.title%>.
However, that code doesn't work, ending in the error
ArgumentError in Rails::MailersController#preview
wrong number of arguments (1 for 2)
at
def student_reminder(user, course)
I think I have proper number of arguments (user and course)
As noted above, the error was in the MailerController#preview method.
Related
I get this error when I try to sign in a user, and can't figure out why. It's weird because when I run the following code I get the BCrypt Error, however when I change the find_by line (line 7) from can_email (candidate's email) to can_name (candidate's first name) I don't get the error at all, it just doesn't sign in the user presenting an "invalid password/email combination" error message on the webpage regardless if the combination is right or not. It's something to do with the password but I can't pin point it.
class SessionsController < ApplicationController
def new
end
def create
candidate = Candidate.find_by_can_email(params[:can_email])
if candidate && candidate.authenticate(params[:password]) **Error highlights this line**
session[:candidate_id] = candidate.id
redirect_to candidate
else
flash.now[:error]="Invalid email/password combination"
render 'new'
end
end
def destroy
if signed_in?
session[:candidate_id] = nil
else
flash[:notice] = "You need to log in first"
end
redirect_to login_path
end
end
Having the SessionController i am assuming you have a route as follows
# This is just a sample
post 'login' => "sessions#create" # gives login_path
Since there will be no session model i assume you have the form as follows
form_for(:session, url: login_path)
Now if you are collecting eg can_email and password you get
{session: {password: 'foo', can_email: 'foo#bar.com'}}
Accessing params[:session] returns the hash containing email and passowrd
So i think you should obtain them as follows
def create
candidate = Candidate.find_by(can_email: params[:session][:can_email])
if candidate && candidate.authenticate(params[:session][:password])
# login the user
else
# whatever
end
end
I got this error too, but in my case it was the result of myself having changed the encrypted_password value of my user in the database a while back and then forgetting about it.
This was easily fixed just by updating the password :)
I am working through the rails tutorial, and am on chapter 10 setting up mailers. Right now I am on the account_activation email. To ensure I am setting it up the correct way, I have even double checked my code based on the sample repo, and I am setting it up just like he has.
The full error is: ArgumentError in Rails::MailersController#preview wrong number of arguments (0 for 1) and is pointing to the code in my user_mailer#account_activation method
def account_activation(user) #here
#user = user
mail to: user.email, subject: "Account activation"
end
the test code this is checking against is this
class UserMailerPreview < ActionMailer::Preview
# Preview this email at http://localhost:3000/rails/mailers/user_mailer/account_activation
def account_activation
user = User.first
user.activation_token = User.new_token
UserMailer.account_activation(user) #setting up the method call here
end
end
I am not sure why this is happening, because I pass the correct number of arguments via UserMailer.account_activation(user). My only guess is maybe it could be looking at the UserMailerPreview#account_activation (which takes no argument) method and is trying to mirror the method at UserMailer#account_activation which does take an argument.
Does anyone see what I'm doing wrong? Any help at all would be greatly appreciated.
If you're calling class method and not instance method then it should be
def self.account_activation(user)
#user = user
mail to: user.email, subject: "Account activation"
end
and then
UserMailer.account_activation(user)
I have been trying to solve the following problem for a couple of days. Forgive me if this is a common problem as I am new to rails and probably couldn't query the right question/keyword in stackoverflow or google.
I am building a system where a user will get an invite via email, click on a unique link, be taken to a page where he/she can accept or decline the invitation. I am getting stuck at the part where the user accepts or declines the invitation.
I've built it around two controllers: an invitations controller and a confirmations controller.The invitations controller creates a record containing a name, an email, and a uniquely generated token. The controller then emails a link with the token to the defined email. The link points to the confirmations controller and passes the unique token from the invitation. However, when clicking on the link and accepting the invitation, I get the following error:
NoMethodError in ConfirmationController#confirm
undefined method `update_attribute' for nil:NilClass
Here is some of the code for solving this issue:
Confirmation_controller.rb
class ConfirmationController < ApplicationController
def new
#confirmation = Invitation.find_by_invite_token(params[:invite_token])
end
def confirm
if #confirmation.update_attribute(:accepted, true)
flash[:success] = "Invitation confirmed!"
redirect_to 'static_pages/home'
else
flash[:notice] = "Failed :("
redirect_to 'static_pages/home'
end
end
end
routes.rb
match '/confirmation/:invite_token', to: 'confirmation#new'
match '/confirmation/:invite_token/confirm', to: 'confirmation#confirm'
app/views/confirmation/new.html.erb
Click here to accept:
<%= link_to "Confirm", :controller => "confirmation", :action => "confirm" %>
You need to get your Invitation in the confirm method too.
If you want rails to raise an exception if no invitation was found
def confirm
#confirmation = Invitation.find_by_invite_token!(params[:invite_token])
#confirmation.update_...
end
No exception will be raise. You may want to check manually with a condition in the following case.
def confirm
#confirmation = Invitation.find_by_invite_token(params[:invite_token])
if #confirmation
#confirmation.update_...
else
# do something
end
end
You should find confirmation record before calling update_attribute on it, like you did it in new action:
#confirmation = Invitation.find_by_invite_token(params[:invite_token])
Or, to throw exception when the record is not found and to render 404 page to the user:
#ocnfirmation = Invitation.find_by_invite_token!(params[:invite_token])
The problem is that you never told the program what #confirmation is. What you should do is find it first then run the update. Note this is different from the different answers, just thought I would throw in some variety.
def confirm
# You're missing this line below. Basic search for the confirmation.
# Note too that you will have to pass in the parameter `invite_token` for it to work
# I'm also assuming invite_token is unique among each invitation
confirmation = Invitation.where(invite_token: params[:invite_token])
# Notice that I'm first checking to see if the confirmation record exists, then doing an update
if confirmation and confirmation.update_attribute(:accepted, true)
flash[:success] = "Invitation confirmed!"
redirect_to 'static_pages/home'
else
flash[:notice] = "Failed :("
redirect_to 'static_pages/home'
end
end
I'm using code identical to my password_reset code for my email change code.
User wants change their email address so they type in their email address click a button and they're logged out.
An email is sent to them containing a link they click containing a code as id which is then matched up with the one stored in the db to confirm they are in fact the accounts owner. Any way when I click the I get the error shown below.
Problem is I'm getting this error:
ArgumentError in EmailsController#edit
comparison of String with ActiveSupport::TimeWithZone failed
Rails.root: /Users/greg/site
Application Trace | Framework Trace | Full Trace
app/controllers/emails_controller.rb:19:in `<'
app/controllers/emails_controller.rb:19:in `edit'
Request
Parameters:
{"id"=>"KdFTTeWuOGqpDm6F_iY7aw"}
Show session dump
Show env dump
Response
Headers:
None
Emails controller create:
def create
#user = User.find_by_email(params[:email_change][:email])
logout if logged_in?
#user.generate_and_store_email_change_token && UserMailer.email_change(#user).deliver if #user
flash[:success] = "Email sent with email reset instructions."
redirect_to root_url
end
Emails controller edit:
def edit
#user = User.find_by_email_change_token(params[:id])
if #user.nil?
flash[:error] = "The email change link you clicked has been used."
redirect_to root_url
elsif #user.email_change_sent_at < 2.hours.ago
flash[:error] = "Email change token has expired."
redirect_to email_change_url
end
end
User model:
def generate_and_store_email_change_token
self.email_change_token = SecureRandom.urlsafe_base64
self.email_change_sent_at = Time.zone.now
save!(:validate => false)
end
def remove_used_email_change_token
self.email_change_token = nil
save!(:validate => false)
end
This is strange because the exact same code works for my password reset. I tested again and I don't get the error the email version giving me.
Kind regards
Seems like email_change_sent_at type is a string. You should change it to datetime
Hi I want to send emails to all the email comma addresses entered in text field. I have following controller for doing so.
def send_invites #friend invites
#emails_txt = params[:emails_txt]
#emails = #emails_txt.split(/\s*,\s*/)
#ve = []
#emails.each do |email|
if email =~ /\b[A-Z0-9._%a-z-]+#(?:[A-Z0-9a-z-]+.)+[A-Za-z]{2,4}\z/
#ve << email
end
end
#all_ok = true
#errors = []
#ve.each do |email|
#invitation = Invitation.new
#invitation.sender = current_user
#invitation.recipient_email = email
if #invitation.save
UserMailer.invitation_notification(current_user, #invitation, new_user_registration_url+"/#{#invitation.token}").deliver
else
#all_ok = "false"
#errors << #invitation.errors
end
end
end
It was working fine but now it is giving error as follows
NoMethodError in InvitationsController#send_invites
undefined method `username' for nil:NilClass
whats the problem please help me. Thank you
It looks like you are perhaps referencing a nil object in your email view.
I would look in your view for the UserMailer#invitation_controller action and see where you reference username.
Then, once you found that, trace back the object and find out why its nil, then add some testing around that (i.e. if current_user.nil? ...).