Episodes

Resources

Download Source Code

Summary

# Gemfile
gem 'public_activity'

# Terminal
rails g public_activity:migration

# app/models/post.rb
class Post < ApplicationRecord
  has_many :comments, as: :commentable
  belongs_to :user
  include PublicActivity::Model

  def parent_post
    self
  end
end

# app/models/comment.rb
class Comment < ApplicationRecord
  has_many :comments, as: :commentable
  belongs_to :user, optional: true
  belongs_to :commentable, polymorphic: true

  include PublicActivity::Model
  
  ...

  def parent_post
    return commentable if returnables.include?(commentable.class)
    returnable_parent(commentable)
  end

  # POST > Comment > Comment

  private

  def returnable_parent(parent)
    return parent if returnables.include?(parent.class)
    returnable_parent(parent.commentable)
  end

  def returnables
    [Post]
  end
end

# posts_controller.rb
def create
  @post = current_user.posts.new(post_params)
  if @post.save
    current_user.friends.each do |user|
      @post.create_activity :create, owner: current_user, recipient: user
    end
    redirect_to @post, notice: 'Post was successfully created.'
  else
    render :new
  end
end

# dashboard_controller.rb
@activities = PublicActivity::Activity.includes(:trackable)
                                      .where(recipient: current_user)
                                      .order(id: :desc)
                                      .limit(5)

# dashboard/index.html.erb
<ul class="list-unstyled">
  <%= render_activities(@activities) %>
</ul>

# views/public_activity/post/_create.html.erb
<li class='media alert alert-info'>
  <div class='media-body'>
    <%= link_to activity.trackable.title, activity.trackable %>
    posted by
    <%= activity.owner.email %>
  </div>
</li>

# views/public_activity/comment/_create.html.erb
<li class='media alert alert-info'>
  <div class='media-body'>
    <%= activity.owner.email %>
    created a comment on
    <%= link_to activity.trackable.parent_post.title, activity.trackable.parent_post %>
  </div>
</li>