Reputation: 1123
So, I have this website that I've built http://leapfm.com/ and more and more users are joining which is fantastic. I've noticed that users sign back on to check if their song has been up-voted. I'd like to automate this process for them.
So, I'd like to implement a feature that sends the user an email when their song is up-voted. I'm not sure if this is possible with my stack specifically.
E.g. for up voting I'm using this gem.
Can I implement somethin' like this? If you need me to provide any additional information, don't be afraid to ask.
song_controller snippit (create action):
def create
@song = Song.new(song_params)
@song.user = current_user
respond_to do |format|
if @song.save
format.html { redirect_to @song, notice: 'Song was successfully created.' }
format.json { render action: 'show', status: :created, location: @song }
else
format.html { render action: 'new' }
format.json { render json: @song.errors, status: :unprocessable_entity }
end
end
end
Upvotes: 3
Views: 4011
Reputation: 9138
This should be fairly straightforward. What you would want to do is send an email each time a vote record is created.
First, within your Vote model, you would set up an after_commit
handler when an instance is created.
class Vote
...
after_commit :send_email, :on => :create
def send_email
# send the email to whoever owns votable
end
end
Within the # send the email
part, there are several options. The simplest would be to simply configure ActionMailer and deliver emails within that send_email
method. There are several methods for setting this up. The one I most recently used was Postmark, for which you would install postmark-rails
and add something like the following to your config/environments/production.rb
.
config.action_mailer.delivery_method = :postmark
config.action_mailer.postmark_settings = { :api_key => 'your-api-key' }
However, I encourage you to check out the various providers to find one that fits your needs (I can think of Postmark, SendGrid, Mailgun).
Then, run rails generate mailer VoteMailer
, which will create a VoteMailer class under app/mailers/vote_mailer.rb
. Edit it to fit your needs.
class VoteMailer < ActionMailer::Base
default from: '[email protected]'
def vote_notification(voter, song)
@voter = voter
@song = song
@user = @song.user
mail(to: @user.email, subject: 'Someone voted on your song!')
end
end
Now, you create a template in app/views/vote_mailer/vote_notification.text.erb
.
Hey <%= @user.name %>,
Someone voted on your song, <%= @song.name %>!
Congrats!
Then, use the mailer in your send_email
method.
class Vote
...
def send_email
VoteNotifier.vote_notification(voter, voteable).deliver!
end
end
This should get you started.
People were commenting earlier about needing to use Delayed Job. This is because sending email can be a slow process. If every time a user clicks 'upvote', they have to wait 5 seconds while the email is sent, they will become dissatisfied with the service.
To avoid this problem, people will take the more time consuming parts of their server request and stick them into a job queue, which will be processed by another server. To achieve this with your emails, you would install delayed_job_active_record
and change your send_email
method:
class Vote
...
def send_email
VoteNotifier.delay.vote_notification(voter, voteable)
end
end
And then in a separate process on your server, run the jobs:work
Rake task.
bundle exec rake jobs:work
This process should be running 24/7, just like your web server process.
Upvotes: 8