rails: Mailer classes do not load until console is reloaded (reload! is called)

Steps to reproduce

Create a mailer using generator or manually. Add methods to this class. Start rails console and try to use these methods from this class on the console. Example

class ReportMailer < ApplicationMailer
  def daily_report(args)
     #do stuff
   end
end

Expected behavior

Method should have worked.

Actual behavior

NameError (uninitialized constant ReportMailer) my mailer is called ReportMailer

System configuration

Rails 6.0.1 Ruby 2.5.0

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 6
  • Comments: 38 (23 by maintainers)

Commits related to this issue

Most upvoted comments

This issue occurs because all listeners are stopped (but not all restarted) when a previously non-existent watched directory is created, e.g. test/mailers/previews. I intend to fix this, but guard/listen#476 needs to be resolved first, which I am working on.

I have same problem too. try spring stop . It works for me.

> rails g mailer Happy
> rails r HappyMailer
uninitialized constant HappyMailer
> spring stop
Spring stopped.
> rails c
2.7.1 :001 > HappyMailer
 => HappyMailer
Rails 6.0.3.2
Ruby 2.7.1p83

Interesting, thanks!

I have some busy days, but will eventually dig into this.

I also had this issue and spring stop works.

@alea12 could you please try disabling Spring?

rails new console_mailer_load_test --skip-spring

ah d’oh! well if helpful I can delete these comments ! thanks for your help!

Yup, this is happening to me too. @fxn / @alea12 comment on disabling Spring was the workaround for me as well. I’ve been using generators for my models that past few days and the models are working as expected. This does seem more specific to ActionMailers for some reason.

I’m on Rails 6.0.2

Hey! Heads up, I have been able to reproduce something weird that seems probably related (irrelevant output cut):

% rails new issue_38714 --no-rc
% cd issue_38714
% spring status
Spring is not running.
% rails g mailer MyMailer
Running via Spring preloader in process 34902
% rails r MyMailer
Running via Spring preloader in process 35110
uninitialized constant MyMailer

If you then do something as simple as

% echo "Foo = 1" > app/models/foo.rb

The constant Foo is not found either:

% rails r Foo
uninitialized constant Foo

I have added some traces and the problem is that, for some reason, Spring does not notice the project has changed and it does not trigger a reload.

If you stop Spring, or perform that process with Spring disabled, this does not happen.

It does seem related to mailers, because if you try to do the same steps with an innocent

% rails g job foo

FooJob is found as usual. Same with models, etc. That is, Spring reloads.

Excellent, weird though. Let’s close to keep issues low (so to speak, haha), but please reopen if you find a way to reproduce.