action-mailer 4.2 question regarding custom templates

I have a custom template file that resides in a non-standard (for RoR) location. I wish to use this template for text format messages generated by a stand-alone script. I also wish to incorporate it into a new RoR app that is related to the existing script. The mailer and templates reside in this directory structure:

lib ├── hll_action_mailer │ ├── hll_action_mailer.rb │ ├── hll_th_forex_mailer │ │ ├── hll_th_forex_cacb_update_notice.rb │ │ ├── hll_th_forex_mailer.rb │ │ └── views │ │ ├── hll_th_forex_cacb_update_notice.text.erb │ │ └── hll_th_forex_commercial_rates_notice.text.erb

``

I have discovered that passing a do block after the call to the mail method discards any template_path and template_name keys passed in the argument list. See: ActionMailer::Base#mail should allow overriding template_name for default template rendering when a block is passed by betesh · Pull Request #18412 · rails/rails · GitHub. However I cannot seem to discover any way at all to use my custom template path and name with a do block.

I have tried this:

this_template_name = "hll_th_forex_commercial_rates_notice.text.erb"
this_template = File.join(  "/", File.dirname( __FILE__ ),
                            "/views",
                            this_template_name )
mail( :to => recipients,
      :from => fm_address,
      :subject => subject,
    ) \
    do |format|
      format.text do
        render( this_template )
      end
    end

``

But this causes this error:

 Missing template home/byrnejb/Projects/Software/theHeart/code/hll_th_main/lib/hll_action_mailer/hll_th_forex_mailer/views/hll_th_forex_commercial_rates_notice.text.erb with {:locale=>[:en], :formats=>[:text], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
    * "/home/byrnejb/Projects/Software/theHeart/code/hll_th_main/lib/hll_action_mailer/hll_th_forex_mailer"
    * "/home/byrnejb/Projects/Software/theHeart/code/hll_th_main/app/views"

I considered the lack of a leading / on the reported path as the source of the problem but an inspection of the contents of this_template immediately before the call to render shows this:

    do |format|
      format.text do

puts( this_template.inspect ) render( this_template ) end end

``

which gives:

“/home/byrnejb/Projects/Software/theHeart/code/hll_th_main/lib/hll_action_mailer/hll_th_forex_mailer/views/hll_th_forex_commercial_rates_notice.text.erb”

So what is happening inside render? How do I specify a mailer template in a non-standard location in render or is that not possible and I must set an explicit default? well that does not work either:

class HllThForexMailer < ActionMailer::Base default( :template_path => Pathname.new( File.join( File.dirname( FILE ), “views” ) ).realpath.to_s ) . . . mail( :to => recipients, :from => fm_address, :subject => subject, :template_name => “hll_th_forex_commercial_rates_notice.text.erb” )

``

gives this:

  Missing template /home/byrnejb/Projects/Software/theHeart/code/hll_th_main/lib/hll_action_mailer/hll_th_forex_mailer/views/hll_th_forex_commercial_rates_notice.text.erb with "mailer". Searched in:
    * "/home/byrnejb/Projects/Software/theHeart/code/hll_th_main/lib/hll_action_mailer/hll_th_forex_mailer/views"

Which is at least what I expected. However the message says that it cannot find the template file. Yet when I do this using the exact path string copied from the ‘Missing template message’ I see this:

ls -l /home/byrnejb/Projects/Software/theHeart/code/hll_th_main/lib/hll_action_mailer/hll_th_forex_mailer/views/hll_th_forex_commercial_rates_notice.text.erb

-rw-rw-r–. 1 byrnejb byrnejb 2010 Oct 20 16:10 /home/byrnejb/Projects/Software/theHeart/code/hll_th_main/lib/hll_action_mailer/hll_th_forex_mailer/views/hll_th_forex_commercial_rates_notice.text.erb

So something is seriously screwed up with either what action-mailer is doing or with the error message it is reporting since the template file is exactly where AM says it could not find it.

How do I get this to work?

I have not used it, but since no-one else has suggested anything, perhaps prepend_view_path is an option.

Colin

Thanks. Funnily enough that is what I started with:

  self.prepend_view_path(     Pathname.new(       File.join( File.dirname( __FILE__ ) )                 ).realpath.to_s                         )

Which does work in the stand-alone script using actionmailer (4.0.13) but which seems not to work inside a Rails-4.2 project. At least not the way I think that it should. From what I have read the prepend_path adds to the existing Rails constructed path which will always include the root portion of the calling controller name, in the case of the currencies_controller this would prepend the value to '/currencies' rather than stipulate an absolute search path.

I strongly suspect that something RoR is doing in the background is causing these problems. I just cannot seem to find a way to avoid or undo it for this specific controller.

In the RoR app a link is called from the currencies_controller.

  # Send an email with the latest commerical forex rates
  # POST /forex/send/commercial/rates
  def hll_th_forex_send_commercial_rates_notice

    @comm_curr = HLLCommercialForexRatesNotice.find_and_email_rates

class HLLCommercialForexRatesNotice
. . .
    @comm_curr.each do |currency|
      unless currency.currency_code == currency.default_base_currency
       # mail_rtn = MailerPublic.deliver_forex_hll_commercial_rates(
        HllThForexMailer.hll_th_forex_commercial_rates_notice(
          currency,
          date,
          to_address,
          fm_address ).deliver_now # or: #deliver_later
      end
    end
. . .

In the stand alone script the mailer is directly invoked.

```ruby
&nbsp;&nbsp;&nbsp;&nbsp;@comm\_curr\.each do |currency|
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless currency\.currency\_code == currency\.default\_base\_currency
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HllThForexMailer\.hll\_th\_forex\_send\_commercial\_rates\_notice\(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currency, date, to\_address, fm\_address \)\.deliver
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
&nbsp;&nbsp;&nbsp;&nbsp;end
\`\`\`

The behaviour of the do-end block with respect to the render method and the template_path/template_name keys in the method argument list is by design. These two keys are intentionally discarded by the render method.

However, it there also appears to be a problem when passing the template_path/template_name keys in the method argument list without using a block. In this case the key values also appear to be ignored. Finally, setting the default template_path in the class also seems to fail. I have opened two github issues for these:

https://github.com/rails/rails/issues/22045 https://github.com/rails/rails/issues/22047

But if anyone can point out some error I am committing that is causing these problems then please let me know.