Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to notify the commenter?

If I write a comment on your status and then you comment back I don't get a notification to let me know you commented.

Currently only the owner of the status gets notifications. How can we make is where anyone who commented on a status should get notified too?

models

class Comment < ActiveRecord::Base
  after_save :create_notification
  has_many :notifications
  def create_notification
    author = valuation.user
    notifications.create(
      comment:      self,
      valuation:    valuation,
      user:         author,      
      read:         false
    )
  end
end

class Notification < ActiveRecord::Base
  belongs_to :comment
  belongs_to :valuation
  belongs_to :user
end

class Valuation < ActiveRecord::Base
  belongs_to :user
  has_many :notifications
  has_many :comments
end

controllers

class CommentsController < ApplicationController
  before_action :set_commentable, only: [:index, :new, :create]
  before_action :set_comment, only: [:edit, :update, :destroy]

  def create
    @comment = @commentable.comments.new(comment_params)
    if @comment.save
      redirect_to @commentable, notice: "Comment created."
    else
      render :new
    end
  end

  private

  def set_commentable
    @commentable = find_commentable
  end

  def set_comment
    @comment = current_user.comments.find(params[:id])
  end

  def find_commentable
    if params[:goal_id]
      Goal.find(params[:goal_id])
    elsif params[:habit_id]
      Habit.find(params[:habit_id])
    elsif params[:valuation_id]
      Valuation.find(params[:valuation_id])
    elsif params[:stat_id]
      Stat.find(params[:stat_id])
    end
  end
end

class NotificationsController < ApplicationController
  def index
    @notifications = current_user.notifications
    @notifications.each do |notification|
      notification.update_attribute(:read, true) 
    end
  end
end

views

#notifications/_notification.html.erb
commented on <%= link_to "your value", notification_valuation_path(notification, notification.valuation_id) %>

#comments/_form.html.erb
<%= form_for [@commentable, @comment] do |f| %>
  <%= f.text_area :content %>
<% end %>
like image 535
AnthonyGalli.com Avatar asked Sep 26 '22 16:09

AnthonyGalli.com


1 Answers

Instead of creating one notification for the author, you have to retrieve the list of users who have commented on the valuation. I don't see a belongs_to :user in the Comment model, but I'll assume there is one, as you are able to do a current_user.comments in CommentsController.

Let's add a has_many relation in Valuation to retrieve all the commentators for a given valuation:

class Valuation < ActiveRecord::Base
  belongs_to :user
  has_many :notifications
  has_many :comments
  has_many :commentators, -> { distinct }, through: :comments, source: :user
end

If you are using a version of Rails < 4, you should replace -> { distinct } by uniq: true

Then, you can simply use this new relation to create notifications for all the commentators in the Comment model:

class Comment < ActiveRecord::Base
  after_save :create_notification
  belongs_to :user
  belongs_to :valuation
  has_many :notifications

  def create_notification
    to_notify = [valuation.user] + valuation.commentators
    to_notify = to_notify.uniq
    to_notify.delete(user)  # Do not send notification to current user
    to_notify.each do |notification_user|
      notifications.create(
        comment:      self,
        valuation:    valuation,
        user:         notification_user,      
        read:         false
      )
    end
  end
end
like image 79
haradwaith Avatar answered Sep 30 '22 06:09

haradwaith