Send email to all users in rails - ruby-on-rails-3

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

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.

Rails send individual email to each user?

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.

Rails Omniauth-github (422) The change you wanted was rejected

I have had this solution for Omniauth & Github implemented and working fine but sometime in the last few months it stopped working.
The error I'm getting when I try to login is: (422) The change you wanted was rejected.
Specifically in the Heroku logs I'm seeing:
ActiveRecord::RecordInvalid (Validation failed: Password can't be blank):
app/models/user.rb:18:in `create_from_omniauth'
app/models/user.rb:14:in `from_omniauth'
app/controllers/sessions_controller.rb:4:in `create'
Do I need to save the credentials when I create the user?
My user model:
def self.from_omniauth(auth)
where(auth.slice("provider", "uid")).first || create_from_omniauth(auth)
end
def self.create_from_omniauth(auth)
create! do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.name = auth["info"]["nickname"]
user.email = auth["info"]["email"]
user.image = auth["info"]["image"]
end
end
Sessions controller:
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to root_url, notice: "Signed in!"
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Signed out!"
end
end
Facebook's omniauth error "the change you wanted was rejected"
might appear because of your validations set in the model. I had to refactor my validation for users having one unique email, which wasn't working when a user would try to facebook login with the same email.
Look at your logs. heroku logs -t
It looks like you're either validating presence of the password field in your User model or using has_secure_password, which does that under the covers.
If you're doing that validation yourself, you can just add a clause like :if => :password_changed? to the validation.
If you're using has_secure_password, it depends which version of Rails you're using. Any version with these two changes (I believe only Rails 4) support passing a validations: false option to has_secure_password. Otherwise, there's not really a good solution, other than maybe setting a random dummy password when you create the user then letting them change it immediately.
I had this issue when the time on my gitlab server was out of sync, i restarted ntpd, which corrected the time on the server and the problem was resolved

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