Почему этот код голосования Ruby on Rails не работает? - PullRequest
1 голос
/ 19 марта 2011

Так что я действительно думал, что это сработает для создания системы голосования, как у нас здесь на SO:

def create       
  @video = Video.find(params[:video_id])
  @vote = current_user.video_votes.find_or_create_by_video_id(@video.id)

  if @vote.value.nil?
    if params[:type] == "up"
      @vote.value = 1
    else
      @vote.value = -1
    end
  elsif (params[:type] == "up" && @vote.value == 1) || (params[:type] == "down" && @vote.value == -1)
    @vote.value = 0
  elsif ((params[:type] == "up" && @vote.value == -1) || (params[:type] == "down" && @vote.value == 1)) || (@vote.value == 0)
    if params[:type] == "up"
      @vote.value = 1
    else
      @vote.value = -1
    end
  end  

  if @vote.save
    respond_to do |format|
      format.html { redirect_to @video }
      format.js
    end
  else
    respond_to do |format|
      format.html { redirect_to @video }
      format.js {render 'fail_create.js.erb'}
    end
  end   
end

Я попытался последовать примеру первого ответа в этом вопросе: Почему нетэтот код Ruby on Rails работает так, как я намереваюсь? Однако мой код не позволяет мне впервые проголосовать за видео из-за этой ошибки:

TypeError (nil can't be coerced into Fixnum):
app/models/video_vote.rb:11:in `update_vote_sum'
app/controllers/video_votes_controller.rb:4:in `create

Вотмоя модель видеовота:

class VideoVote < ActiveRecord::Base
  belongs_to :user
  belongs_to :video
  validates_uniqueness_of :user_id, :scope => :video_id

  after_create :update_vote_sum

  private

    def update_vote_sum
      video.update_attributes!(:vote_sum => video.vote_sum + value)
    end
end

И в случае, если это необходимо, вот мой метод vote_sum из моей модели видео:

def vote_sum
  video_votes.sum(:value)
end

Ответы [ 2 ]

3 голосов
/ 19 марта 2011

В вашем методе after_create в VideoVote.rb вы суммируете все голоса, включая только что созданный, с нулевым значением. Переключите after_create на after_update или установите значение по умолчанию для value на VideoVote.

Если посмотреть на это, если vote_sum вызывает каждый раз каждый голос sum для всех ваших голосов, вам, вероятно, даже не понадобится метод after_create или after_update, если для голосов установлено значение по умолчанию.

-

Вы также можете заменить всю эту систему драгоценным камнем thumbs_up и избавить себя от хлопот.

0 голосов
/ 19 марта 2011

Не уверен, что вы пытаетесь сделать здесь. vote_sum - это метод, который суммирует количество голосов, которые имеет видео, из того, что я вижу, так почему вы пытаетесь обновить его как атрибут? Он всегда будет возвращать правильную оценку видео, вам не нужно обновлять его вручную, поскольку это не атрибут, а вычисленный результат метода.

...