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:
- is adapted from the Railscast and doesn't hide the voting options
- is apparently more efficient but produces the same problem
- proves the rest of the code works: ALL the links hide when this option runs
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?