Search code examples
ruby-on-railsrubyroutesacts-as-votable

NoMethodError in PostsController#upvote undefined method `upvote_by' for nil:NilClass


screenshot

Currently I'm using acts_as_votable gem along with bootstrp-sass gem,I want to upvote the post when glyphicon icon is clicked, instead it throws me above errors. This is my posts_controller.rb file

class PostsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]

  def search
    if params[:search].present?
        @posts = Post.search(params[:search])
    else
        @posts = Post.all
    end 
  end

  def index
    @posts = Post.all.order('created_at DESC')      
  end

  def new   
    @post = Post.new    
  end

  def create
    @post = Post.new(post_params)

    if @post.save   
        redirect_to @post
    else
        render 'new'
    end
  end

  def show
    @post = Post.find(params[:id])      
  end

  def edit
    @post = Post.find(params[:id])      
  end

  def update
    @post = Post.find(params[:id])

    if @post.update(params[:post].permit(:title, :date, :time, :location))
        redirect_to @post
    else
        render 'edit'
    end 
  end

  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    redirect_to root_path       
  end

  def upvote
    @post.upvote_by current_user
    redirect_to :back
  end

  private
  def post_params
    params.require(:post).permit(:title, :date, :time, :location)
  end
end

This is my show.html.erb file

<div id="post_content">
<h1 class="title">
    <%= @post.title %>
</h1>

<p class="date">
    Submitted <%= time_ago_in_words(@post.created_at) %> Ago
    <% if user_signed_in? %>
    | <%= link_to 'Edit', edit_post_path(@post) %>
    | <%= link_to 'Delete', post_path(@post), method: :delete, data: { confirm: 'Are you sure?' } %>
    <% end %>
</p>

<p class="date">
    <%= @post.date %>
</p>

<p class="time">
    <%= @post.time %>
</p>

<p class="location">
    <%= @post.location %>
</p>

<div id="comments">

  <div class="btn-group pull-left">
    <%= link_to like_post_path(@post), method: :put, class: "btn btn-default" do %>
      <span class="glyphicon glyphicon-heart"></span>
      <%= @post.get_upvotes.size %>
    <% end %>
  </div>

    <h2><%= @post.comments.count %> Comments</h2> 
    <%= render @post.comments %>

    <h3>Add a comment:</h3>
    <%= render "comments/form" %>
</div>

This is my routes.rb file

    Rails.application.routes.draw do

    mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
    devise_for :users
      resources :posts do
       resources :comments
       collection do
         get 'search'
       end

       member do
            put "like", to: "posts#upvote"
       end
    end

   root "posts#index"

   get '/about', to: 'pages#about'
end

And this is my post model

class Post < ActiveRecord::Base

   acts_as_votable
   searchkick
   has_many :comments, dependent: :destroy
   validates :title, presence: true, length: {minimum: 5}
   validates :date, :time, :location, presence: true
   belongs_to :user
end

Solution

  • NoMethodError in PostsController#upvote undefined method `upvote_by' for nil:NilClass

    The error is because you didn't initialized @post in upvote method so @post is nil

    def upvote
      @post = Post.find(params[:id])
      @post.upvote_by current_user
      redirect_to :back
    end