Rails send individual email to each user? - ruby-on-rails-3

I'm sending around 100 emails at a time using the following mailer in my Rails 3 application:
def new_resource_notification(resource, user)
#resource = resource
#user = user
mails = User.where(:email_subscribe => true).map(&:email)
mail(:to => "admin#domain.com", :bcc => mails, :subject => "New item added")
end
When I look at the outgoing email logs it's sending each email to admin#domain.com and adding all users to the bcc field as expected.
What I would prefer, if possible, is for each email to be sent to the users email without any bcc entries.
Is this possible and/or recommended?

Yes, it is possible, but you will have to do a loop, which will send single e-mail to each user. It will take much more rescources and will be slower; that's why lots of mailers do "BCC method" rather than send single emails.

Related

Skip email confirmation when creating a new user using Devise

I have a user registration page and will send the information to couple of admin users that one new user registered in the site.
Now, I created the seed data with list of users (200+). So, It'll send the 200+ email to the respective admin users. Hence, I want to stop send the mail confirmation to admin users when creating new user.
For Devise, add user.skip_confirmation! before saving.
user = User.new(
:email => 'person#example.com',
:password => 'password1',
:password_confirmation => 'password1'
)
user.skip_confirmation!
user.save!
Cite: https://github.com/plataformatec/devise/pull/2296
Another option is to do something like
user = User.new.tap do |u|
u.email = 'email#server.com'
u.password = 'hackme!'
u.password_confirmation = 'hackme!'
u.skip_confirmation!
u.save!
end
In that way, you instantiate the object, skip the confirmation and save it in one step and return it to the user variable.
It's just another way to do the same in one step.

Send email to all users in rails

I am trying to create a method that, when called send a email to all users.
My ultimate goal is to call this method via a scheduler (i already got the scheduler working) And the method will go thought all users and send emails to some of then if some pre-requisites are met.
Right now i just want to learn how i make a simplest stuff that is to send a custom email to every user in the table.
My first issue is:
def send_digest
#users = User.all
#users.each do |user|
#time = Time.now
mail(to: user.email, subject: user.name)
end
end
This method (is inside app/mailer/user_mailer.rb) only is sending one e-mail to the guy with biggest ID in the table. Why that?
Also, what i need to do to access the variable "user.name" inside the email?
EDIT:
There a better way for accessing user variable inside the mail body than doing #user = user?
def send_digest(user)
#time = Time.now
#user = user
mail(to: user.email, subject: 'mail message')
end
For each call to the mailer method one email is sent
in scheduled worker
def calling_method
#users.each do |user|
send_digest(user.email, user.name)
end
end
in user mailer
def send_digest(user_email, user_name)
mail(to: user_email, subject: user_name)
end

Access a mailer method without sending the email

I have a working mailer in Rails 3.
I want to have some logic inside the mailer methods which will decide if to email it or not.
I cannot have this logic outside the mailer, since I am using Delayed_job with a delay. I delay the email for an hour. If a condition hasn't been met, I send the email.
1. Is there a way to enter the mailer method and not complete the sending (gracefully)
2. Is there a better way of achieve what I am trying?
Code Sample
This is the mailer
class MessagesMailer < ActionMailer::Base
def message_notification(user, message)
#user = user
#msg = message
mail(to: #user.email, from: "#{#msg.sender.name} <me#myapp.com>", subject: "You have recieved a new message from #{#msg.sender.name}")
end
end
MessagesMailer.delay(:run_at => 5.minutes.from_now).message_notification(#user, #message) is being called throughout the app, particularly from MessagesController
I want to check if #user has already read that message. If so, not send the email.
Delay_job would perform message_notification in 5 minutes, but once that method is complete the email is sent regardless of what happens inside of it.
Is there a way to cancel delivery upon a condition (#user read the message)?

How do I make Devise verify if the user has an email before try to send a new password?

I have a Rails app where I am using Devise for authentication. Devise lets users click to get an email containing a link to reset their password.
My problem is that the email field is not required in the table "user". There's a login field to authenticate, that is sincronized from another system. I can't set email to required.
I want to verify the email field and return a custom message to the user, if the email is not set. If it is, then Devise will continue and reset the password.
I saw in another post, that I have to override the method "email_required?" in the user model, but I still get the error message "Email cant be blank".
def email_required?
false
end
In your user model you should probably have some kind of validation for email like so
validates_presence_of :email
Also if you wanted to migrate the database to have email as not null it would be like so
change_column :users, :email, :string, :null => false

Log emails sent by devise in rails

I am using devise for user authentication in rails. How can I log the emails sent by devise. I have a model for storing the emails. How can I hook in so that before devise sends emails for new registration, change password, forgot password etc, I can just store the emails in the db?
Create a file called config/initializers/devise_mail_logger.rb and re-open the Devise::Mailer class
devise_mail_logger.rb:
Devise::Mailer.class_eval do
def devise_mail_with_logger(record, action)
email = devise_mail_without_logger(record, action)
#code to log this email to DB goes here
end
alias_method_chain :devise_mail, :logger
end
The email object will have the message body, subject, recipient details. You can pass this object to the model you have to store emails.