ryanb / letter_opener

Preview mail in the browser instead of sending.
MIT License
3.73k stars 238 forks source link

Stop letter_opener when seeding the DB #117

Closed davidmles closed 8 years ago

davidmles commented 9 years ago

Is it possible to stop letter_opener when seeding the DB?

I have added this snippet at the beginning of my seeds.rb file:

ActionMailer::Base.perform_deliveries = false
ActionMailer::Base.delivery_method = :smtp

But lots of windows open. No matter where I move that snippet, I have tried to place it just before the code that triggers those emails, but I have the same problem.

This is happening on my development environment.

jwgoh commented 9 years ago

You can put them in the environment-specific configuration files, so for development it is config/environments/development.rb.

# Turn off deliveries
config.action_mailer.perfom_deliveries = false
davidmles commented 9 years ago

Thanks, it worked. I hope this helps people coming here with the same issue :)

davidmles commented 9 years ago

Uhm... it's working because I have disabled it for development. So if it's disabled for development, what's the point for letter_opener? It's intended for the development environment, so this solution is not ideal.

I'm reopening the issue.

jwgoh commented 9 years ago

Well, you can disable letter_opener when seeding your db and re-enable it again after the seeding is done. How often do you "seed" your db? The only time I seed is when I am creating a new database. Am I missing out on something here?

davidmles commented 9 years ago

I seed it more often, because I create and update my models several times. What's more, other (non-technical) people in the team follow the instructions in the Readme to seed the DB.

That's what we are going to do, but since it's not ideal I would love to know another more suitable solution.

nashby commented 9 years ago

@davidmles can you try to change delivery method from :smtp to :test?

davidmles commented 9 years ago

@nashby I just tried it, same problem.

Let me know if you need me to do something to debug this, please.

nashby commented 9 years ago

@davidmles that's strange. Actually it works with adding only ActionMailer::Base.perform_deliveries = false to the seeds file for me. Can you please provide a sample application that reproduces the error?

davidmles commented 9 years ago

I have tried it with a new application, and it actually works.

I'm thinking it's because I use Sidekiq. Maybe that cannot be controlled by the perform_deliveries option? Disabling Sidekiq when seeding obviously works, and that's the fix for my issue for now.

If that's the reason, I'm happy to close the issue.

nashby commented 9 years ago

@davidmles hmm, that's strange. Looking at the code I can see that sidekiq uses deliver method which respects perform_deliveries option. What version of rails and sidekiq are you using?

davidmles commented 9 years ago

I'm using the latest version of Rails and Sidekiq, and using the deliver_later method. I will test it better tomorrow.

davidmles commented 9 years ago

Steps to reproduce the issue:

gem 'sidekiq'
gem 'sinatra', require: nil
group :development do
  gem 'letter_opener'
end
---
:concurrency: 5
:queues:
  - mailers
  - default
config.action_mailer.delivery_method = :letter_opener
class ApplicationMailer < ActionMailer::Base
  def sample_email
    mail from: 'example@example.org', to: 'example@example.com', subject: 'This is an example'
  end
end
This is an example.
ActionMailer::Base.perform_deliveries = false
ApplicationMailer.sample_email.deliver_later

You should see the email actually being sent and letter opener opening it in a browser.

jwgoh commented 9 years ago

Hmmm deliver_now doesn't seem to deliver the email for me. I modified the sample_email method to take in an optional parameter to differentiate the emails sent out (if there are 2).

ActionMailer::Base.perform_deliveries = false
ApplicationMailer.sample_email.deliver_later
ApplicationMailer.sample_email("Now").deliver_now # no email
davidmles commented 9 years ago

Yes, as @jwgoh says, deliver_now does not send the email, but deliver_later does.

Is this bug related to letter_opener? Or is it something Sidekiq is not doing correctly? Or maybe a Rails bug? What do you think @nashby ?

shadwell commented 9 years ago

@davidmies Sidekiq will be running a separate instance of the environment so it will still have the usual configuration of perform_deliveries=true.

You've only set that deliveries won't be performed in the instance of the environment where your seeds are being executed. That's why deliver_now isn't sending them: because it is running in the thread where you've set mails not to be delivered.

davidmles commented 9 years ago

Thanks @shadwell, that makes sense. So, isn't it possible to deny it to send them using deliver_later?

shadwell commented 9 years ago

No, not by temporarily changing the configuration I think. You've have to temporarily change it in the thread that actually sends the emails. You may have more luck skipping the actual delivery of the emails when seeding rather than trying to get letter_opener to suppress its delivery.

nashby commented 8 years ago

@davidmles is it still an issue for you? I think you can try to disable sidekiq in the seed file somehow since you don't really need it there, do you?. Probably this would work https://github.com/mperham/sidekiq/wiki/Testing. Closing this for now.

jackkinsella commented 5 years ago

I'm late to the party on this one, but for what it's worth, my solution was to create a separate Rails environment seed.rb that inherits from development as per a technique from DHH. Within this env file, I changed the relevant settings in a way that can handle running separate processes (although I also disable the job queue and make it inline instead therefore reduced the problem).

require Rails.root.join('config/environments/development_base')

Rails.application.configure do
  # Avoid async difficulties when seeding data
  config.active_job.queue_adapter = :inline
  # Do not pop up emails in browser when seeding (due to letter_opener gem)
  config.action_mailer.delivery_method = :test
  config.action_mailer.perform_deliveries = false
end
hakunin commented 4 years ago

Rather than having to rely on an extra environment, I just disable these in my seed script:

ActiveJob::Base.queue_adapter = :inline
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = false