1

So I really thought this would work to create the voting system like we have here on 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

I tried to follow the example of the first answer in this question: Why doesn't this Ruby on Rails code work as I intend it to? My code, however, doesn't let me vote on a video for the first time because of this error:

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

Here's my videovote model:

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

And in case this is needed, here's my vote_sum method from my Video model:

def vote_sum
  video_votes.sum(:value)
end
Community
  • 1
  • 1
Justin Meltzer
  • 13,318
  • 32
  • 117
  • 182
  • Looks like your error is in your vote model so you should show us `vote.rb`. – thenengah Mar 19 '11 at 17:38
  • possible duplicate of [Why doesn't this Ruby on Rails code work as I intend it to?](http://stackoverflow.com/questions/5360914/why-doesnt-this-ruby-on-rails-code-work-as-i-intend-it-to) – the Tin Man Mar 19 '11 at 20:28

2 Answers2

3

In your after_create method in VideoVote.rb, you're summing over all votes, including the one you've just created with a nil value. Switch after_create to after_update, or set a default for value on VideoVote.

In looking at that, if vote_sum is calling sum on all of your votes every time anyways, you probably don't even need an after_create or after_update method if votes have a default value set.

--

You could also replace this entire system with the thumbs_up gem, and save yourself some hassle.

Dominic
  • 3,304
  • 19
  • 22
  • 1
    Thumbs up gem might be the way to go. – thenengah Mar 19 '11 at 17:44
  • still have the same error... I kinda want to implement it myself :) – Justin Meltzer Mar 19 '11 at 17:45
  • As is often the case in Rails work, convention over configuration. Why reinvent the wheel when voting and karma are already handled pretty well :) Implementing yourself can always be fun though. – Dominic Mar 19 '11 at 17:45
  • I feel like there would be some overhead for me to understand how to use the plugin. I also wouldn't understand how it works internally, while I think I'm almost already done with implementing it on my own. – Justin Meltzer Mar 19 '11 at 17:49
  • sweet, thanks!!! I'm kinda proud that a figured out the logic behind the create method :) I just started programming a month ago. – Justin Meltzer Mar 19 '11 at 17:56
  • by the way, do you mean I can get rid of the `update_vote_sum` method as well? – Justin Meltzer Mar 19 '11 at 17:58
  • Glad it worked! Yes, I believe you can remove your `update_vote_sum` method. re: understanding other gems: There is always overhead to learning and using someone else's library, but it often comes with the benefit of (hopefully!) stable, secure and well-tested code that makes your actual application logic simpler and easier to enhance in the future. Congratulations on getting your implementation working! It's always a good feeling :) – Dominic Mar 19 '11 at 18:02
0

Not sure what you are trying to do here. vote_sum is a method that sums up the number of votes that a video has, from what I can see, so why are you trying to update it as an attribute? It will always return the correct score of a video, you shouldn't need to manually update it, since it is not an attribute, but a calculated result of a method.

Fareesh Vijayarangam
  • 5,037
  • 4
  • 23
  • 18