“Undefined local variable or method” error when us

2019-02-25 04:37发布

问题:

I made a website in which people can share photo's (they are called pins in my code). I wanted to add a system in which, when someone clicks on the picture, they can comment on it. I decided to use the commontator gem and I installed it. My problem is that the commenting system does not show up below posts like it's supposed to and I get an undefined local variable or method error for my pins controller.

routes.rb

Photo::Application.routes.draw do
resources :pins

devise_for :users
root "pins#index"
get "about" => "pages#about"
mount Commontator::Engine => '/commontator'

show.html.erb

<%= link_to 'Back', pins_path %>
<div class="row">
  <div class="col-md-offset-2 col-md-8">
    <div class="panel panel-default">
      <div class="panel-heading center">
        <%= image_tag @pin.image.url(:medium) %>
      </div>
      <div class="panel-body">
      <p><%= @pin.description %></p>
      <p><strong><%= @pin.user.name if @pin.user %></strong></p>
      <%= commontator_thread(commontable) %>

      <% if @pin.user == current_user %>
          <%= link_to edit_pin_path(@pin) do %>
              <span class="glyphicon glyphicon-edit"></span>            
          <% end %>
      <% end %>
    </div>
  </div>
</div>

pin.rb

class Pin < ActiveRecord::Base
    belongs_to :user
    acts_as_commentable

    has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }

    validates :image, presence: true
    acts_as_commontator
    acts_as_commontable
end

pins_controller.rb

class PinsController < ApplicationController
    before_action :set_pin, only: [:show, :edit, :update, :destroy]
    before_action :correct_user, only: [:edit, :update, :destroy]
    before_action :authenticate_user!, except: [:index, :show]

    def index
       @pins = Pin.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 8)
    end

    def show
    end

    def new
        @pin = current_user.pins.build
    end

    def edit
    end

    def create
        @pin = current_user.pins.build(pin_params)
        if @pin.save
          redirect_to @pin, notice: 'Pin was successfully created.'
        else
          render action: 'new'
        end
    end

    def update
        if @pin.update(pin_params)
            redirect_to @pin, notice: 'Pin was successfully updated.'
        else
           render action: 'edit'
        end
    end

    def destroy
        @pin.destroy
        redirect_to pins_url
    end

    private
        # Use callbacks to share common setup or constraints between actions.
    def set_pin
        @pin = Pin.find(params[:id])
    end

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

    def pin_params
      params.require(:pin).permit(:description, :image)
    end
end

User model user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

    has_many :pins, dependent: :destroy 
validates :name, presence: true
acts_as_commontator
end

error I am getting on show.html.erb

NameError in Pins#show
undefined local variable or method `commontable' for #<#<Class:0x007f9d8ccec328>:0x007f9d8df68768>
Extracted source (around line #12):

                   <div class="panel-body">
                   <p><%= @pin.description %></p>
                   <p><strong><%= @pin.user.name if @pin.user %></strong></p>
                               **<%= commontator_thread(commontable) %>**

                   <% if @pin.user == current_user %>
                           <%= link_to edit_pin_path(@pin) do %>

回答1:

As there is no stacktrace added, a couple of observations.

  1. acts_as_commontator and acts_as_commontable are added in same model.

    As per documentation at https://github.com/lml/commontator

    • acts_as_commontator // to be added in user model(s) (or any models that should be able to post comments)
    • acts_as_commontable // to be added in models you want to be able to comment on

      So can you try moving acts_as_commontator to user model?

  2. In pin.rb line no. 3,.remove the line acts_as_commentable which is not used by your gem commontator



回答2:

Assuming that you have added acts_as_commontable to the Pin model,

In the pins/show.html.erb,

Replace

<%= commontator_thread(commontable) %>

With

<%= commontator_thread(@pin) %> 

As per the Commontator Usage Documentation,

In <%= commontator_thread(commontable) %>

commontable is an instance of a model that acts_as_commontable.

which in your case is @pin.