Episodes
RailsCod3rFuture said over 4 years ago on User Notifications :
If its not too much to ask. Can you please make a similar video for **activity_notification** gem? Its almost identical to this one, but it may be more optimized. https://github.com/simukappu/activity_notification

blimey85 said over 4 years ago on User Notifications :
Second vote for the activity_notification. It looks very slick and something I'm gonna add in to my project soon.

David Kimura PRO said over 4 years ago on User Notifications :
I've had a chance to look at this gem. Its documentation is pretty extensive which is always nice to see. I'll consider covering this gem in the future. One thing that I highly dislike about this gem is that it seems a lot more invasive in the models. It also has a lot of added complexity based on the documentation and I'm not convinced that it's necessary to accomplish what they're doing. Overall the gem does look pretty cool and for a large complex app, this may be a good fit.

azback5 said almost 2 years ago on User Notifications :
Hey  ... I'm having some trouble implementing the notifications feature into my rails app.

The notifications counter updates perfectly in my app layout view, but when I try to click on the notifications url I keep receiving a 500  NameError and it's parsing through and fussing with a link to root_path in my app/layout which doesn't make sense, to me as I know that works fine.


in my comment.rb model

class Comment < ApplicationRecord


  after_commit :create_notifications, on: :create

  belongs_to :commentable, polymorphic: true
  has_many :comments, as: :commentable
  belongs_to :user, optional: true

  validates :body, presence: true

  def deleted?
    user.nil?
  end

  private

  def create_notifications
   Notification.create do |notification|
     notification.notify_type = 'commentable'
     notification.actor = self.user
     notification.user = self.commentable.user
     notification.target = self
     notification.second_target = self.commentable
   end
 end

end


in my views/notifications/_commentable.html.erb
<div class=''>
  <%= link_to notification.actor.email, main_app.user_path(notification.actor) %> has commented in

</div>

<div class=''>
  <%= notification.target.body %>
</div>


Do you have any ideas as to what might be creating the fuss?

Thanks a lot!

Aaron

David Kimura PRO said almost 2 years ago on User Notifications :
  Are you clicking on the email link which is then giving the NameError? Can you post the error?

azback5 said almost 2 years ago on User Notifications :
No, I'm clicking on the notifications_path  in my app/layout view
  <%= link_to pluralize(Notification.unread_count(@current_user), 'Notification'), notifications_path %>

The error is :

Showing timesink/app/views/layouts/application.html.erb where line #25 raised:

undefined local variable or method `root_path' for #<#<Class:0x00007fb4d1e8b498>:0x00007fb4d91abd38>
Did you mean?  font_path


David Kimura PRO said almost 2 years ago on User Notifications :
Try changing it to main_app.root_path as the notification engine doesn't have context of root_path and needs the main app's root path.

azback5 said almost 2 years ago on User Notifications :
That worked!

But now I'm left with this error, which I was receiving before too at some point.

It's with the line in my views/notifications/_notification.html.erb

<%= render partial: "/notifications/#{notification.notify_type}", locals: { notification: notification } %>

timesink/app/views/notifications/notifications/_notification.html.erb where line #11 raised:issing partial notifications/_comment with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :arb, :jbuilder]}. Searched in:
  * "/Users/aaronzomback/Sites/timesink/app/views"
  * "/Users/aaronzomback/.rvm/gems/ruby-2.7.0/gems/notifications-1.1.0/app/views"
  * "/Users/aaronzomback/.rvm/gems/ruby-2.7.0/gems/devise-4.7.2/app/views"
  * "/Users/aaronzomback/.rvm/gems/ruby-2.7.0/gems/activeadmin-2.7.0/app/views"
  * "/Users/aaronzomback/.rvm/gems/ruby-2.7.0/gems/kaminari-core-1.2.1/app/views"
  * "/Users/aaronzomback/.rvm/gems/ruby-2.7.0/gems/form_slider-0.0.5/app/views"
  * "/Users/aaronzomback/.rvm/gems/ruby-2.7.0/gems/actiontext-6.0.3.2/app/views"
  * "/Users/aaronzomback/.rvm/gems/ruby-2.7.0/gems/actionmailbox-6.0.3.2/app/views"

Any idea what causes this? It's confounding me!

David Kimura PRO said almost 2 years ago on User Notifications :
It looks like the engine is trying to render the partial because of the "duplicate" notifications in the path timesink/app/views/notifications/notifications/_notification.html.erb

azback5 said almost 2 years ago on User Notifications :
David, thanks for all of your help. 

I've been having trouble continuing to set this up with my nested Comments which belong to both a BlogPost & a Review.

For example, I only want a user to receive a notification if another User has commented on their comment. NOT on a BlostPost - which acts as a commentable and which  below each post are the nested comments.

What I've done is the following in my Comment model:

class Comment < ApplicationRecord



  belongs_to :commentable, polymorphic: true
  has_many :comments, as: :commentable
  belongs_to :user, optional: true

  acts_as_votable

  validates :body, presence: true

    def deleted?
      user.nil?
    end

    after_commit :create_notifications, on: :create

    private


  def create_notifications
   Notification.create do |notification|
     notification.notify_type = 'commentable'
     notification.actor = self.user
     notification.user = self.commentable.user
     notification.target = self
     notification.second_target = self.commentable
   end
 end

end



And I receive this error:

NoMethodError (undefined method `user' for #<BlogPost:0x00007fc3cab54fd8>
Did you mean?  super):
  
app/models/comment.rb:26:in `block in create_notifications'
app/models/comment.rb:23:in `create_notifications'
app/controllers/comments_controller.rb:17:in `create'


Which makes sense because a BlogPost doesn't belong to a User, so it can't find a user. So it is blocking the ability of a User to add a new comment beneath the BlogPost.

Is there a way I can write an argument like:

 if self.commentable = self
     notification.user = commentable.user
    end

Meaning if the commentable IS a comment and NOT a BlogPost, then the user to receive the notification is the user of the comment (and not incorrectly the BlogPost)

Your tutorial is very clear, but I'm hitting some weeds when I try to then implement this into the nested comments.

Hopefully this is making sense to you, and if not I'm happy to provide a link to my repo if needed.

Thanks for any help that you might be able to provide!

Cheers,

Aaron

(p.s. I've actually followed your previous nested comments tutorial and it is all set up and working great).

David Kimura PRO said almost 2 years ago on User Notifications :
  ruby object and instantiating it in the comment controller create action

def create
  @comment = Comment.new(comment_params)
  if @comment.save
    CommentNotifier.call(@comment)
    ...
  else
    ...
  end
end

From there, you can make the Comment Notifier have guard clauses, do any checks and pass in any other additional parameters needed. (like passing in the current user to have a guard clause return unless current_user == comment.user) to prevent the current user getting a notification if they reply to their own comment.

azback5 said almost 2 years ago on User Notifications :
Ok, I think I get the logic, but not sure if I've gotten the syntax correct. 

  def create

      @comment = @commentable.comments.new(comment_params)
      @comment.user = @current_user
      if @comment.save
        CommentNotifier.call(@comment)
        if @comment = @commentable
        else 
          nil
        end
        respond_to do |format|
          format.html { redirect_to @commentable }
          format.js # create.js.erb
        end

Basically, if the commentable object is a comment, then the user of that commentable comment SHOULD receive a notification. 
Else, if commentable is a not a comment (i.e. a BlogPost) they shouldn't!

How would you include the guard clause return unless current_user == comment.user in there as well?

Thanks David!

David Kimura PRO said almost 2 years ago on User Notifications :
  Can you post your Ruby class for the CommentNotifier?

azback5 said almost 2 years ago on User Notifications :
  I actually didn't create a Ruby Class for it, I just assumed that it was a native feature of the Notifications gem...

Where would you create the Ruby class for CommentNotifier? I'm not sure if I'm following you.



azback5 said almost 2 years ago on User Notifications :
Ah, create CommentNotifier method in Comment model you mean? If so, I'm just wondering how you would define it.

Thanks David!

David Kimura PRO said almost 2 years ago on User Notifications :
   You can put it in your app/models or create a new folder in app like services and put it in there.


azback5 said almost 2 years ago on User Notifications :
I've placed it in my Comment model and here is how I've tried to define it so far, but I doubt that it makes sense..

In my Comment model ...
  def CommentNotifier
      if self = @commentable
      else 
        nil
      end
    end




David Kimura PRO said almost 2 years ago on User Notifications :
  The CommentNotifier would be it's own class. 

# app/models/comment_notifier.rb
class CommentNotifier
  # this is a class method, so it will be called like CommentNotifier.call(@comment, current_user) from your controller
  def self.call(commnet, current_user)
    new.call(comment, current_user)
  end

  # initialization stuff for the CommentNotifier instance
  attr_accessor :comment, :current_user
  def initialize(comment, current_user)
    @comment = comment
    @current_user = current_user
  end

  # this is your main method where the business logic will happen.
  def call
    Rails.logger.info comment
    Rails.logger.info current_user
    # thanks to attr_accessor, I can simple reference to commant and current_user without the @comment or @current_user

    # example guard clauses
    return unless current_user
    return unless comment
    return unless user_same_as_commenter

    # do other actions and checks
  end

  private

  # because we create a methods within this class, we can call on these methods since we initialized a new object in the (new.call(comment, current_user))
  def user_same_as_commenter
    current_user == comment.user
  end
end


azback5 said almost 2 years ago on User Notifications :
  Thanks, so I just implemented this in a CommentNotifier model as you've written (correcting the typo above in your def self.call at the beginning 'comnet' to 'comment' and here is how the create method looks in my Comments Controller...

  def create

      @comment = @commentable.comments.new(comment_params)
      @comment.user = @current_user
      if @comment.save
        CommentNotifier.call(comment, current_user)
        respond_to do |format|
          format.html { redirect_to @commentable }
          format.js # create.js.erb
        end
      else
        redirect_to cookies[:original_referrer]
        flash[:error] = "Comment could not be created."
      end
    end

But I receive this error 

NameError (undefined local variable or method `comment' for #<BlogPosts::CommentsController:0x00007fd7bfe4c818>
Did you mean?  @comment):
  
app/controllers/comments_controller.rb:18:in `create'

which is puzzling because it seems to point to my namespaced BlogPosts::CommentsController < CommentsController

class BlogPosts::CommentsController < CommentsController

    before_action :set_commentable

    def new
     @comment = Comment.new(commentable: @commentable)
   end


  private

  def set_commentable
    @commentable = BlogPost.friendly.find(params[:blog_post_id])
  end
end

I'll be happy to send you a link to my GitHub repo if that will help provide more insight!

Thanks for your time and consideration...


David Kimura PRO said almost 2 years ago on User Notifications :
You need @comment because comment is not defined

azback5 said almost 2 years ago on User Notifications :
  do you mean @comment here in my Comments Controller create action?

CommentNotifier.call(@comment, @current_user)

If I enter this then I get this error...

ArgumentError (wrong number of arguments (given 1, expected 2)):
  
app/models/comment_notifier.rb:12:in `initialize'
app/models/comment_notifier.rb:5:in `call'
app/controllers/comments_controller.rb:18:in `create'



David Kimura PRO said almost 2 years ago on User Notifications :
  you're method on line 12 in the comment_notifier is accepting only one argument, but you're passing in two in the call.

azback5 said almost 2 years ago on User Notifications :
  Why would it be only accepting one argument? 

Login to Comment