NoMethodError для неопределенного метода `ots_against'

Я получаю сообщение об ошибке NoMethodError для неопределенного метода 'voice_against' при попытке отобразить счетчик голосов в представлении моего шоу. Однако я реализовал гем act_as_votable, но у меня возникли трудности с отображением голосов. Это означает, что если пользователь нажимает thumbs_up, вы видите цифру 1, если другой пользователь нажимает на изображение thumbs_up, эта цифра увеличивается до 2.

В частности, ошибка возникает для строки: <% = @ post.votes_against%> на моей странице show.html.

Заранее спасибо.

Post Rb

class Post < ActiveRecord::Base

    belongs_to :user

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

    validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png"]

    validates :description, presence: true
    validates :image, presence: true

  scope :subscribed, ->(following) { where user_id: following }

  acts_as_votable

    # Returns posts from the users being followed by the given user.
  def self.from_users_followed_by(user)
    followed_user_ids = user.followed_user_ids
    where("user_id IN (:followed_user_ids) OR user_id = :user_id",
          followed_user_ids: followed_user_ids, user_id: user)
  end

end

Пользователь Rb

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

  has_many :posts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id",
                                   class_name:  "Relationship",
                                   dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower
  has_many :following, :through => :relationships, :source => :followed

  has_many :subscribed, class_name: "Relationship", foreign_key: "follower_id"


  validates :name, presence: true

  acts_as_voter

  has_one :profile

  belongs_to :user

  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "150x150>" }, :default_url => "/assets/avatar.png"
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/


  def feed
    Post.from_users_followed_by(self)
  end

  def following?(other_user)
    relationships.find_by(followed_id: other_user.id)
  end

  def follow!(other_user)
    relationships.create!(followed_id: other_user.id)
  end

  def unfollow!(other_user)
    relationships.find_by(followed_id: other_user.id).destroy
  end

end

Post Controller

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


  def index
    @posts = Post.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 40)
  end


  def show
  end


  def new
    @post = current_user.posts.build
  end


  def edit
  end


  def create
    @post = current_user.posts.build(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render action: 'show', status: :created, location: @post }
      else
        format.html { render action: 'new' }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end


  def update
    respond_to do |format|
      if @post.update(post_params)
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end


  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url }
      format.json { head :no_content }
    end
  end


 def vote_for
      @post = Post.find(params[:id])
      current_user.vote_for(@post)
      respond_to do |format|
        format.js
      end
  end


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

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def post_params
      params.require(:post).permit(:description, :image)
    end

  end

Маршруты

devise_for :admins
  devise_for :users

  resources :posts

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

  resources :relationships, only: [:create, :destroy]
  resources :user_friendships do 
      member do
        put :accept
      end
     end   


resources :posts do 
    member do
      post :vote_for 
      post :vote_against
    end
  end

show.html.erb

<div class="row">
    <div class="col-md-offset-4 col-med-8">
        <div class="panel panel-default">
        <div class="panel-heading center">

        <% if @post.image.url %>
            <%= image_tag @post.image.url(:medium) %>

        <% elsif @post.video.url %>
            <%= video_tag @post.video.url(:medium), controls: true, type: "video/mp4" %>
        <% end %>


        <p>
            <strong>Votes For:</strong>
            <%= @post.votes_for %>
        </p>


        <%=link_to image_tag('thumbs_up', :border => 0), vote_for_post_path(@post) %>
        <%=link_to image_tag('thumbs_down', :border => 0), vote_against_post_path(@post) %>

        </div>
        <div class="panel-body">
        <p><%= @post.description %></p>

        <% user = @post.user %>
        <p><strong><%= link_to(user.name, user_path(user)) if @post.user %></strong></p>

        <% if @post.user == current_user %>
            <%= link_to edit_post_path(@post) do %>
            <span class="glyphicon glyphicon-edit"></span>
            Edit
          <% end %>
        <% end %>
        <%= link_to 'Back', posts_path %>
        </div>
</div>

1 ответ

Решение

Как я уже упоминал в моем комментарии, вы получаете эту ошибку, потому что нет никакого метода "voice_against". Если вы посмотрите на acts_as_votables repo, у вас есть методы "get_likes" и "get_upvotes" для получения ваших голосов "за" и методы "get_dislikes" и "get_downvotes" для получения голосов "за"

# tally them up!
@post.votes_for.size # => 5
@post.get_likes.size # => 3
@post.get_upvotes.size # => 3
@post.get_dislikes.size # => 2
@post.get_downvotes.size # => 2

Как я могу получить подсчет голосов для отображения? Нужно ли добавлять get_upvotes и.get_downvotes в мой контроллер?

Нет, вам не нужно определять эти методы, так как Gem Act_as_votable уже делает это для вас. Для показа количества голосов вверх и вниз вы можете сделать:

<p>
   <strong>Votes For:</strong>
   <%= @post.get_likes.size%>
</p>

<p>
   <strong>Votes Against:</strong>
   <%= @post.get_dislikes.size%>
</p>
Другие вопросы по тегам