0

我的应用程序中有三个模型,一个用于帖子、报价和用户,现在我已经建立了一个用户可以喜欢帖子的点赞系统,我没有为此使用任何 gem,现在在我使用过的报价模型中添加投票yththeacts_as_votable gem,要使用我acts_as_voter在用户模型acts_as_votable中添加的 gem 和引号 mo everdel,我运行服务器一切正常,但是当我尝试喜欢一个帖子(不是引号)时,我在控制台上收到此错误:

Completed 500 Internal Server Error in 20ms (ActiveRecord: 4.7ms)

NoMethodError (undefined method `vote_by' for nil:NilClass):
  app/models/user.rb:64:in `add_like_to'
  app/controllers/api/likes_controller.rb:11:in `create'

我已经尝试了很多方法来解决它,但没有任何效果,最后我acts_as_voter从我的用户模型中删除,它再次开始工作,但是对我的报价进行投票不起作用。

我的用户模型

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, :omniauth_providers => [:facebook, :twitter, :google_oauth2]
  validates :username, presence: true
  validate :avatar_image_size

  has_many :posts, dependent: :destroy
  has_many :quotes, dependent: :destroy
  has_many :responses, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liked_posts, through: :likes, source: :likeable, source_type: "Post"
  has_many :liked_responses, through: :likes, source: :likeable, source_type: "Response"

  has_many :bookmarks, dependent: :destroy
  has_many :bookmarked_posts, through: :bookmarks, source: :bookmarkable, source_type: "Post"
  has_many :bookmarked_responses, through: :bookmarks, source: :bookmarkable, source_type: "Response"

  has_many :notifications, dependent: :destroy, foreign_key: :recipient_id

  after_destroy :clear_notifications
  after_commit :send_welcome_email, on: [:create]

  mount_uploader :avatar, AvatarUploader

  include UserFollowing
  include TagFollowing
  include SearchableUser
  include OmniauthableUser

  extend FriendlyId
  friendly_id :username, use: [ :slugged, :finders ]

  def add_like_to(likeable_obj)
    likes.where(likeable: likeable_obj).first_or_create
  end

  def remove_like_from(likeable_obj)
    likes.where(likeable: likeable_obj).destroy_all
  end

  def liked?(likeable_obj)
    send("liked_#{downcased_class_name(likeable_obj)}_ids").include?(likeable_obj.id)
  end

  def add_bookmark_to(bookmarkable_obj)
    bookmarks.where(bookmarkable: bookmarkable_obj).first_or_create
  end

  def remove_bookmark_from(bookmarkable_obj)
    bookmarks.where(bookmarkable: bookmarkable_obj).destroy_all
  end

  def bookmarked?(bookmarkable_obj)
    send("bookmarked_#{downcased_class_name(bookmarkable_obj)}_ids").include?(bookmarkable_obj.id)
  end

  private

    # Validates the size on an uploaded image.
    def avatar_image_size
      if avatar.size > 5.megabytes
        errors.add(:avatar, "should be less than 5MB")
      end
    end

    # Returns a string of the objects class name downcased.
    def downcased_class_name(obj)
      obj.class.to_s.downcase
    end

    # Clears notifications where deleted user is the actor.
    def clear_notifications
      Notification.where(actor_id: self.id).destroy_all
    end

    def send_welcome_email
      WelcomeEmailJob.perform_later(self.id)
    end
end

我的报价模型

class Quote < ActiveRecord::Base
    acts_as_votable

    validates :author, presence: true, length: { maximum: 150 }
    validates :quote, presence: true, length: { maximum: 300 }, uniqueness: true
    is_impressionable
    belongs_to :user

    def most_significant_word
      quote.split.map { |quote| quote.gsub(/\W/, '') }.sort_by(&:length)[-1]
    end
end

用于帖子的 likes_controller api

# This controller serves as a parent controller for other likes_controllers. 
# Posts::LikesController for example.
# Child controller that inherit from this LikesController should implement 
# before_action :set_likeable, which sets @likeable.
class API::LikesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_likeable
  skip_before_action :verify_authenticity_token

  def create
    current_user.add_like_to(@likeable)
    notify_author
    render json: { liked: true, count: @likeable.reload.likes.size, type: @likeable.class.to_s, id: @likeable.id }, status: 200
  end

  def destroy
    current_user.remove_like_from(@likeable)

    render json: { liked: false, count: @likeable.reload.likes.size, type: @likeable.class.to_s, id: @likeable.id }, status: 200
  end

  private


    def notify_author
      unless current_user?(@likeable.user)
        Notification.create(recipient: @likeable.user, actor: current_user, action: "liked your", notifiable: @likeable, is_new: true)
      end
    end
end
4

1 回答 1

0

问题是它是acts_as_votable gem 中likes的别名方法。vote_up_for(见这里

如果您想同时使用两者,我建议为关联likes提供别名

has_many :post_likes, class_name: "Like", dependent: :destroy
于 2018-05-31T17:29:56.100 回答