Action Mailer - weird rendering issues

Hello,

While sending email notifications from ThoughtNotifier, I am getting
weird
exceptions, which sometimes occur on the production machine, but I
haven’t
been able to reproduce on my development machine.

There should be no error while rendering
thought_notifier/share_notification.rhtml' template, but if for some reason it is rendering comment_notifier/share_notification.rhtml:1:’
then there will definitely be an error.

I cannot understand why should the backtrace contain reference to
comment_notifier/share_notification, why is the mailer trying to render
that
file, and then why showing thought_notifier/share_notification.rhtml be
shown.

Please help.

undefined method `user’ for nil:NilClass
On line #1 of app/views/thought_notifier/share_notification.rhtml

1: <%= h(@thought.user.display_name) %> has sent you this thought.
2:   <%= h(excerpt_thought(@thought)) %>
3:
4: To view/edit the entire thought or comment on it, visit

#{RAILS_ROOT}/app/views/comment_notifier/share_notification.rhtml:1:in 

_run_rhtml_share_notification' /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:314:in compile_and_render_template’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:290:in
render_template' /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:249:in /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_view/base.rb:272:in render’
/usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.1/lib/action_mailer/base.rb:363:in
render' /usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.1/lib/action_mailer/base.rb:358:in render_message’
/usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.1/lib/action_mailer/base.rb:306:in
create!' /usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.1/lib/action_mailer/base.rb:267:in initialize’
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:21:in new' /usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.1/lib/action_mailer/base.rb:227:in method_missing’
#{RAILS_ROOT}/app/models/thought_observer.rb:17:in after_save' #{RAILS_ROOT}/app/models/thought_observer.rb:5:in after_save’

The line 17 of thought_observer.rb contains
ThoughtNotifier.deliver_share_notification(thought,user,notification.notification_code)

Thanks.

Surendra S.
http://ssinghi.kreeti.com, http://www.kreeti.com
Read my blog at: http://cuttingtheredtape.blogspot.com/
,----
| “All animals are equal, but some animals are more equal than others.”
| – Orwell, Animal Farm, 1945
`----

Surendra S. [email protected] writes:

then there will definitely be an error.

I cannot understand why should the backtrace contain reference to
comment_notifier/share_notification, why is the mailer trying to render that
file, and then why showing thought_notifier/share_notification.rhtml be shown.

Please help.

On further investigation, I have found that, if action mailer templates
have
the same name (but belong to different mailers), then somehow Rails
confuses
them, and uses the last used template, even if it belongs to a different
mailer.

So, for example, in the above problem, I restarted lighty, and first
made use
of an action which exercises
thought_notifier/share_notification.rhtml'. This time it worked fine, but then when I used an action which needs comment_notifier/share_notification.rhtml:1:’

it used the `thought_notifier/share_notification.rhtml’ template, and
gave a
similarly confusing backtrace and code snippet.

Guess, there is some sort of internal caching which is causing this
problem.

This ticket might be related.
http://dev.rubyonrails.org/ticket/5466

Regards.

Surendra S.
http://ssinghi.kreeti.com, http://www.kreeti.com
Read my blog at: http://cuttingtheredtape.blogspot.com/
,----
| “O thou my friend! The prosperity of Crime is like unto the lightning,
| whose traitorous brilliancies embellish the atmosphere but for an
| instant, in order to hurl into death’s very depths the luckless one
| they have dazzled.” – Marquis de Sade
`----

Hello,
I have discovered some issues with Action Mailer. To reproduce them:

Create multiple mailers with the same action say, (FirstMailer and
SecondMailer) with action `share’.

Now, the way the action mailer code is currently written,
‘compile_and_render_template’ function will assign the same function to
the
action in both the mailers. To test, this make both the FirstMailer and
then
SecondMailer send email. ‘compile_and_render_template’ will now store
the
rendered value of the template for SecondMailer mailer.
And while sending the mails using FirstMailer, always the SecondMailer
template will be used.

I have added a patch and test which will fix this.

Without applying the patch to base.rb, if the patch to test files is
applied,
and the tests are run, it will cause an assertion failure.

<“first mail”> expected but was <“second mail”>.

Showing the scenario which I discussed above.

If there are any issues with the patch, I will do my best to help. I
would
like this patch or something else which fixes this problem as soon as
possible.

It might also fix ticket - http://dev.rubyonrails.org/ticket/5466

I have also added this patch as a ticket.

http://dev.rubyonrails.org/ticket/5520

Thanks and regards.
P.S.- the diffs are against edge rails

On 6/27/06, Surendra S. [email protected] wrote:

template, but if for some reason it is rendering
the same name (but belong to different mailers), then somehow Rails confuses

Guess, there is some sort of internal caching which is causing this problem.

This ticket might be related.
http://dev.rubyonrails.org/ticket/5466

Sounds like it is related. I’m the one that filed that ticket, and my
temporary solution was to ‘touch’ the template that is supposed to be
used before ActionMailer goes to render it.

Chris

Here’s an annoyance I’ve run into before, and a simple patch to fix
it. Say I want to export some data as xml. I should be able to fire
up a script or rake task with my environment, grab some data, then
render an rxml template. However, ActionView::Base makes the
assumption that I have a controller somewhere and sets tries to set
content type headers on it.

The only workaround I’ve found to date is to create a TestRequest and
TestResponse, build an action that loads the data I want and renders
with the template I want, expose the action through a real
controller, then call the TestRequest and scrape the body of the
TestResponse. It works, but it feels…wrong.

This patch skips setting content-type header if there is no
controller object, and allows for “standalone” ActionView? use like so:

contacts = Contact.find(:all)
builder = ActionView::Base.new
xml = builder.render( :inline => File.open(‘template.rxml’).read,
:type => :rxml,
:locals => { :contacts => contacts } )

This isn’t limited to rxml, obviously – you can use ERb templates
for other data formats.

I’ve opened this as a ticket: http://dev.rubyonrails.org/ticket/5496

Patch follows and is attached to the ticket.

Thanks!

Solomon



Index: vendor/rails/actionpack/lib/action_view/base.rb

— vendor/rails/actionpack/lib/action_view/base.rb (revision 4450)
+++ vendor/rails/actionpack/lib/action_view/base.rb (working copy)
@@ -438,10 +438,10 @@
body = case extension.to_sym
when :rxml
“xml = Builder::XmlMarkup.new(:indent => 2)\n” +

  •          "@controller.headers['Content-Type'] ||= 'application/
    

xml’\n" +

  •          (@controller.nil? ? "" : "@controller.headers['Content-
    

Type’] ||= ‘application/xml’\n") +
template
when :rjs

  •          "@controller.headers['Content-Type'] ||= 'text/
    

javascript’\n" +

  •          (@controller.nil? ? "" : "@controller.headers['Content-
    

Type’] ||= ‘text/javascript’\n") +
“update_page do |page|\n#{template}\nend”
end
else