0

I am implementing the Active Record Reputation System as described in Railscast 364.

I've got most of it working, including the voting and the totaling (per user and per post).

I have a problem when trying to hide the voting options when a user has already voted. The Railscast uses a function voted_for? to do this hiding. I've looked around for the answer but either no one else has had this problem (unlikely) or I can't transpose their issue back to mine (likely).

My adapted code, with 4 lines I run separately, reads:

# snippet of User.rb:

has_many :evaluations, class_name: "RSEvaluation", as: :source
has_reputation :votes, source: {reputation: :votes, of: :microposts}, aggregated_by: :sum

def voted_for?(micropost)
  evaluations.where(target_type: micropost.class, target_id: micropost.id).present? #1.
  evaluations.exists?(target_type: micropost.class, target_id: micropost.id)        #2.
  true                                                                              #3.
  evaluations.exists?(target_type: "Micropost", target_id: 1)                       #4.
end

Explanation of lines marked 1-4:

  1. is adapted from the Railscast and doesn't hide the voting options
  2. is apparently more efficient but produces the same problem
  3. proves the rest of the code works: ALL the links hide when this option runs
  4. produces this SQL (as taken from the development.log):

    SELECT COUNT(*) FROM "rs_evaluations"
    WHERE "rs_evaluations"."target_id" = 1           # this should be "source_id"
    AND "rs_evaluations"."target_type" = 'User'      # this should be "source_type"
    AND "rs_evaluations"."target_type" = 'Micropost' # correct
    AND "rs_evaluations"."target_id" = 302           # correct
    

So I've found the problem. If I run the SQL with the correct column names, it works as expected.

How do I fix this in my rails code?

Lindsayts
  • 327
  • 2
  • 10

1 Answers1

1

Since it is your SQL that is coming up incorrect, double check that your models have all the correct associations in them. Make sure User has_many :microposts and make sure Micropost is similar to the following.

class Micropost < ActiveRecord::Base
  belongs_to :user

  has_reputation :votes, source: :user, aggregated_by: :sum
end

Also, double check that you have migrated your database and that it has all the correct columns you need for those associations.

rocket scientist
  • 2,427
  • 1
  • 19
  • 28
  • Yeah my User `has_many :microposts, dependent: :destroy`. Micropost is similar to above. I ran `rake db:migrate`, `rake db:migrate`, `rake db:migrate` but the problem is the same – Lindsayts Feb 27 '13 at 23:59
  • 1
    Hmmmm, and I'm assuming you are using Rails 3.2.6 or above since that is what was used in the Railscast and you ran the proper terminal commands `rails g reputation_system` and clearly you migrated :)...The seems like it should be in the associations somewhere since that is what ActiveRecord uses to create the SQL query. Unfortunately, Im not super familiar with the gem activerecord-reputation-system so this is my best guess based on your info. Good Luck! – rocket scientist Feb 28 '13 at 14:36
  • I meant to say I ran `rake db:drop db:create db:migrate db:populate db:test:prepare` above – Lindsayts Mar 01 '13 at 04:06
  • I was using Rails 3.2.12 but went to 3.2.6 to see if it made a difference (it didn't). I agree with your diagnosis, it seems like the associations. Thanks for your help. – Lindsayts Mar 01 '13 at 04:07