Search code examples
ruby-on-railsrubycommentspublic-activity

How to like comments?


Used http://www.sitepoint.com/activity-feeds-rails/ to add "Liking" feature to valuations. Within valuations#show people can comment. I want people to be able to also like comments.

I used railscasts to enable polymorphic comments: http://railscasts.com/episodes/154-polymorphic-association-revised

_comments.html.erb

<% @comments.each do |comment| %>
  <%= User.find(comment.user_id).name %>
  <%= simple_format comment.content %> #Give User ability to like this content.

  <span class="label label-default"><%= pluralize(comment.likes, 'like') %></span>
  <%= link_to content_tag(:span, '', class: 'glyphicon glyphicon-thumbs-up') + ' Like it', method: :post %>
<% end %>

When I click "like" the page refreshes from http://0.0.0.0:3000/valuations/3 to this http://0.0.0.0:3000/valuations/3?method=post and the integer doesn't increase +1.

I tried 20 different variations in the _comments.html.erb code so I think solving this problem lies deeper.

comments_controller

def like
  @comment.increment!(:likes)
  @comment.create_activity :like
  flash[:success] = 'Thanks for liking!'
end

schema

create_table "comments", force: true do |t|
  t.text     "content"
  t.integer  "commentable_id"
  t.string   "commentable_type"
  t.integer  "user_id"
  t.datetime "created_at",       null: false
  t.datetime "updated_at",       null: false
  t.integer  "likes"
end

routes.rb

resources :comments do
 member do
  post :like
 end
end

Side question is public_activity the best gem to achieve a facebook/twitter like newsfeed where one can comment and like on the actual feed? I find that I'm going to have to do a lot of customization to the public_activity gem to achieve what is probably a very common goal for many app creators.

Thank you for your time and expertise!

My code is very similar to the links provided, but if you need more code or have questions please don't hesitate!

UPDATE

valuations_controller

class ValuationsController < ApplicationController
  before_action :set_valuation, only: [:show, :edit, :update, :destroy, :like]
  before_action :logged_in_user, only: [:create, :destroy]

  def index
    if params[:tag]
      @valuations = Valuation.tagged_with(params[:tag])
    else
      @valuations = Valuation.order('RANDOM()')
    end
  end

  def show
    @valuation = Valuation.find(params[:id])
    @commentable = @valuation
    @comments = @commentable.comments
    @comment = Comment.new
  end

  def new
    @valuation = current_user.valuations.build
  end

  def edit
  end

  def create
    @valuation = current_user.valuations.build(valuation_params)
    if @valuation.save
      redirect_to @valuation, notice: 'Value was successfully created'
    else
      @feed_items = []
      render 'pages/home'
  end
end

  def update
    if @valuation.update(valuation_params)
      redirect_to @valuation, notice: 'Value was successfully updated'
    else
      render action: 'edit'
  end
end

  def destroy
    @valuation.destroy
    redirect_to valuations_url
  end

  def like
    without_tracking do
      @valuation.increment!(:likes)
    end
    @valuation.create_activity :like
    flash[:success] = 'Thanks for sharing your Value!'
    redirect_to valuation_path(@valuation)
  end

private

    def without_tracking
      Valuation.public_activity_off
      yield if block_given?
      Valuation.public_activity_on
    end

    def set_valuation
      @valuation = Valuation.find(params[:id])
    end

    def correct_user
      @valuation = current_user.valuations.find_by(id: params[:id])
      redirect_to valuations_path, notice: "Not authorized to edit this valuation" if @valuation.nil?
    end

    def valuation_params
      params.require(:valuation).permit(:name, :private_submit, :tag_list, :content, :commentable, :comment, :like)
    end
end

routes.rb

Rails.application.routes.draw do

  get 'auth/:provider/callback', to: 'sessions#facebook'
  get 'auth/failure', to: redirect('/')
  get 'signout', to: 'sessions#destroy', as: 'signout'

  get 'password_resets/new'

  get 'password_resets/edit'

  resources :users do
    resources :comments
  end

  resources :habits do
    resources :comments
    resources :levels do
      # we'll use this route to increment and decrement the missed days
      resources :days_missed, only: [:create, :destroy]
    end
  end

  resources :goals do
    resources :comments
  end

  resources :valuations do
    resources :comments
    member do
      post :like
    end
  end

  resources :quantifieds do
    resources :comments
  end
  
  resources :results do
    resources :comments
  end

  resources :comments do
    resources :comments
    member do
      post :like
    end
  end

  resources :users

  resources :account_activations, only: [:edit]

  resources :activities

  resources :password_resets,     only: [:new, :create, :edit, :update]

  resources :relationships,       only: [:create, :destroy]

  get 'tags/:tag', to: 'pages#home', as: :tag

  resources :users do
    member do
      get :following, :followers
    end
  end

  get    'about'   => 'pages#about'
  get    'signup'  => 'users#new'
  get    'login'   => 'sessions#new'
  post   'login'   => 'sessions#create'
  delete 'logout'  => 'sessions#destroy'

  root 'pages#home'


Solution

  • I simulate your code, and this works:

    In the view change this line:

    <%= link_to content_tag(:span, '', class: 'glyphicon glyphicon-thumbs-up') + ' Like it', like_comment_path(:id => comment.id), method: :post %>
    

    And in the controller:

    def like
      @comment = Comment.find(params[:id])
      @comment.increment!(:likes)
      @comment.create_activity :like
      flash[:success] = 'Thanks for liking!'
      redirect_to valuation_path(:id => @comment.commentable_id) // If doesnt work -> redirect_to(:back)
    end
    

    And in routes.rb after 'resources :comments do...'

    resources :comments