I am a trainee full stack developer learning ruby on rails and am in month 1 of a 6 month intensive course.
I am working on a 'reddit' style app where users can create topics, posts and comments.
I am trying to automatically email a user when they create a new post.
I am using ActionMailer for this.
I am working on an after_create callback in my post model and a method in a mailer called 'favorite_mailer'.
The problem I am facing, is that I am unable to successfully implement an after_create callback, which triggers an email to be automatically sent to a user after they create a post.
I have defined a method in my mailer called new_post, which should receive 2 arguments (user, post).
I have defined a callback method in my Post model called send_new_post email but can't make it pass my Rspec tests.
Any help will be greatly appreciated.
I have created the following Post model spec:
describe "send_new_post_email" do
it "triggers an after_create callback called send_new_post_email" do
expect(post).to receive(:send_new_post_email).at_least(:once)
post.send(:send_new_post_email)
end
it "sends an email to users when they create a new post" do
expect(FavoriteMailer).to receive(:new_post).with(user, post).and_return(double(deliver_now: true))
post.save
end
end
Here is my Post Model (the relevant bit being the send_new_post_email callback):
class Post < ActiveRecord::Base
belongs_to :topic
belongs_to :user
has_many :comments, dependent: :destroy
has_many :votes, dependent: :destroy
has_many :favorites, dependent: :destroy
has_many :labelings, as: :labelable
has_many :labels, through: :labelings
after_create :create_vote
after_create :create_favorite
after_create :send_new_post_email
default_scope { order('rank DESC') }
validates :title, length: { minimum: 5 }, presence: true
validates :body, length: { minimum: 20 }, presence: true
validates :topic, presence: true
validates :user, presence: true
def up_votes
votes.where(value: 1).count
end
def down_votes
votes.where(value: -1).count
end
def points
votes.sum(:value)
end
def update_rank
age_in_days = (created_at - Time.new(1970,1,1)) / 1.day.seconds
new_rank = points + age_in_days
update_attribute(:rank, new_rank)
end
private
def create_vote
user.votes.create(value: 1, post: self)
end
def create_favorite
user.favorites.create(post: self)
end
def send_new_post_email
FavoriteMailer.new_post(self.user, self)
end
end
Finally, here is my mailer:
class FavoriteMailer < ApplicationMailer
default from: "[email protected]"
def new_comment(user, post, comment)
# #18
headers["Message-ID"] = "<comments/#{comment.id}@your-app-name.example>"
headers["In-Reply-To"] = "<post/#{post.id}@your-app-name.example>"
headers["References"] = "<post/#{post.id}@your-app-name.example>"
@user = user
@post = post
@comment = comment
# #19
mail(to: user.email, subject: "New comment on #{post.title}")
end
def new_post(user, post)
# #18
headers["Message-ID"] = "<post/#{post.id}@your-app-name.example>"
headers["In-Reply-To"] = "<post/#{post.id}@your-app-name.example>"
headers["References"] = "<post/#{post.id}@your-app-name.example>"
@user = user
@post = post
# #19
mail(to: user.email, subject: "You have favorited #{post.title}")
end
end