Hi guys (and gals),
I have the most strange issue that I just cannot figure out. It
doesn’t make sense at all why it’s happening, and had a fellow Rails
developer friend of mine from the UK look at it with me last night,
and still couldn’t figure it out.
Ok, so I have a helpdesk ticketing system wrote in Rails 2.3.5. The
app itself has lots of models and controllers, respectively.
The 2 models in the app that I’m working with (well 3 considering the
mailer model), is Ticket and Customer. My mailer class is called
TicketMailer.
To make sense of it for you all, Ticket belongs_to Customer, Customer
has_many tickets. That’s the relationship between the two.
Tickets are created from the customer, so a user has to navigate to
the customer in the view and click on the create ticket, which nests
the customer_id into the ticket, which is saved to the ticket during
the create action.
With that said, I created the TicketMailer model, and what I am after,
is to deliver an e-mail to the customer when a ticket is created.
Here is my TicketMailer model:
class TicketMailer < ActionMailer::Base
def newticket(ticket)
ticket = @ticket
subject ‘A new ticket has been created for you’
recipients ticket.customer.email
from ‘[email protected]’
sent_on Time.now
end
def ticketstatus(sent_at = Time.now)
subject ‘The status of your ticket has changed’
recipients ticket.customer.email
from ‘[email protected]’
sent_on sent_at
end
end
The other method is commented out for now, as it hasn’t been
implemented, and so I will fight that battle later…
Here is the view of the e-mail, titled newticket.erb:
Hello <%= ticket.customer.first_name %>,
A new ticket titled “<%= ticket.title %>” has been created for you on
the Student Helpdesk Portal.
You can view your ticket at <%= link_to ticket %>.
You may submit comments on the ticket to provide questions or feedback
concerning the ticket.
As always, feel free to call us anytime at 1-866-888-3768, and we will
be happy to help.
Thank you for using the Student Helpdesk Portal, and have a great day.
Regards,
The Helpdesk Team
And here is my create action in my Tickets controller:
def create
@ticket = Ticket.new(params[:ticket])
@ticket.notes.first.user_id = current_user.id
TicketMailer.deliver_newticket(@ticket)
logger.debug("@@@ - Customer email is
#{@ticket.customer.email}")
respond_to do |format|
if @ticket.save
TicketMailer.create_newticket(@ticket)
TicketMailer.deliver_newticket(@ticket)
flash[:notice] = ‘Ticket was successfully created.’
format.html { redirect_to(@ticket) }
format.xml { render :xml => @cticket, :status
=> :created, :location => @ticket }
else
format.html { render :action => “new” }
format.xml { render :xml => @ticket.errors, :status
=> :unprocessable_entity }
end
end
end
For clarification, I placed the deliver above if @ticket.save for now
to get it working, since I don’t want new tickets getting created
before the mailer is working.
The problem I am having, is when I try to create a new ticket, I get
the error:
NoMethodError (undefined method customer' for nil:NilClass): app/models/ticket_mailer.rb:7:in
newticket’
app/controllers/tickets_controller.rb:84:in `create’
Which I know simply put is telling me the customer doesn’t exist,
because customer_id would be nil, so there is no association. But
there is.
Here are the params that get passed into the create action. Not the
logger.debug message I put which just reiterates that the exact
attribute I’m calling is available.
Processing TicketsController#create (for 127.0.0.1 at 2010-03-21
00:05:11) [POST]
Parameters: {“ticket”=>{“platform_id”=>"", “title”=>“Testing
mailer”, “app_version”=>"", “app_id”=>"", “category_id”=>“5”,
“user_id”=>“2”, “os_version”=>"", “status_id”=>“1”, “desc”=>“Seeing if
the mailer works.”, “customer_id”=>“1”,
“notes_attributes”=>{“0”=>{“body”=>“Testing mailer.”}}},
“commit”=>“Create”, “action”=>“create”,
“authenticity_token”=>“lFPGXK8LdqYArXPb02lvF9RSywEiK1HehoPQv7etE/c=”,
“controller”=>“tickets”}
[4;36;1mUser Columns (3.4ms) [0m [0;1mSHOW FIELDS FROM
users
[0m
[4;35;1mUser Load (0.6ms) [0m [0mSELECT * FROM users
WHERE
(users
.id
= 2) LIMIT 1 [0m
[4;36;1mRole Load (1.5ms) [0m [0;1mSELECT roles
.* FROM roles
INNER JOIN assignments
ON roles
.id = assignments
.role_id WHERE
((assignments
.user_id = 2)) [0m
[4;35;1mRole Columns (5.4ms) [0m [0mSHOW FIELDS FROM roles
[0m
[4;36;1mTicket Columns (2.1ms) [0m [0;1mSHOW FIELDS FROM
tickets
[0m
[4;35;1mNote Columns (1.9ms) [0m [0mSHOW FIELDS FROM notes
[0m
[4;36;1mCustomer Columns (1.9ms) [0m [0;1mSHOW FIELDS FROM
customers
[0m
[4;35;1mCustomer Load (0.4ms) [0m [0mSELECT * FROM customers
WHERE (customers
.id
= 1) [0m
@@@ - Customer email is [email protected]
ActionView::TemplateError (undefined method `customer’ for
nil:NilClass) on line #1 of app/views/ticket_mailer/newticket.erb:
1: Hello <%= @ticket.customer.first_name %>,
2:
3: A new ticket titled “<%= @ticket.title %>” has been created for you
on the Student Helpdesk Portal.
4:
app/views/ticket_mailer/newticket.erb:1
app/controllers/tickets_controller.rb:85:in `create'
Rendered rescues/_trace (141.3ms)
Rendered rescues/_request_and_response (0.7ms)
Rendering rescues/layout (internal_server_error)
[4;36;1mSQL (0.1ms) [0m [0;1mSET NAMES ‘utf8’ [0m
[4;35;1mSQL (0.1ms) [0m [0mSET SQL_AUTO_IS_NULL=0 [0m
As you can see, as I put in the create action, @ticket.customer.email
displayed the value in the logger.debug message. So, the customer is
made available to the new action before hand, so the customer is
already there for the create action.
The solution has got to be something silly that I am just not seeing.
If someone could help shed some light on this for me, I’d be much
appreciative.
Thanks,
Justin