:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::: SOLVED :::
Was able to figure out counter_cache on the Vote model and use it in Topics. Updated question below. Once the Topic model had a votes_count, all I had to do was put that in the view and update my counting in the controllers. Turned out to be pretty simple. However finding information was not, so this should help others out, in all its confusing glory. Go way way down for the answer.
Cheers
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::EDIT:::
:::See below for history:::
This is an edit to the original post. I'm really close with what I have, before I try a gem solution. I used a comment_cache on the vote model but now I don't know how to increment the cache.
class Vote < ActiveRecord::Base
belongs_to :topic, :counter_cache => true
end
and called topic.votes.size in the view and it now shows the count without an Active Record enumerable.
<td><%= pluralize(topic.votes.size, "vote") %></td>
<td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td>
<td><%= button_to '-1', downvote_topic_path(topic), method: :post %></td>
index.html.erb
Listing Topics
Title
test 1 vote [+1] [-1] Delete
New Topic
But comment_cache doesn't allow negative numbers. I'm still using create/destroy on the records rather than adding and subtracting a number to the count. How to increment and decrement? Those methods say I'm missing values. Currently it makes sense @topic.votes.last.destroy fails in that there are no more votes to destroy thus the tally cannot be less than zero.
How to setup so that I'm incrementing/decrementing the comment_cache value such that negative numbers are possible? I tried @topic.votes.increment and @topic.votes.increment_counter but they ask for 2 params that I'm not sure what to use. Tried
@topic.increment_counter(:votes_count, params[:id])
but no luck.
NoMethodError in TopicsController#upvote
undefined method `increment_counter' for #<Topic:0x007f87d974a4b0>
Extracted source (around line #433):
431
432
433
434
435
436
else
match = match_attribute_method?(method.to_s)
match ? attribute_missing(match, *args, &block) : super
end
end
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::HISTORY BELOW THIS LINE:::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Revisiting Rails again and I'm trying to do a simple vote counter on topics. What I want to do is increment/decrement the tally (integer) column in the votes record.
Topic has_may :votes, and Vote belongs_to :topic
In the topics_controller.rb I've used
def upvote
@topic = Topic.find(params[:id])
@topic.votes.increment_counter(:tally, params[:id])
redirect_to(topics_path)
end
def downvote
@topic = Topic.find(params[:id])
@topic.votes.decrement_counter(:tally, params[:id])
redirect_to(topics_path)
end
But I get an interesting ActiveRecord key instead of a value in the view instead of the count of votes.
index.html.erb:
from the view
<td><%= pluralize(topic.votes(:tally), "vote") %></td>
<td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td>
<td><%= button_to '-1', downvote_topic_path(topic), method: :post %></td>
result of view
test #<Vote::ActiveRecord_Associations_CollectionProxy:0x007fbb16451f68> votes
Delete
From Rails Console though the increment doesn't show up:
2.1.5 :022 > Vote.first
Vote Load (0.5ms) SELECT "votes".* FROM "votes" ORDER BY "votes"."id" ASC LIMIT 1
=> nil
2.1.5 :023 > Vote
=> Vote(id: integer, topic_id: integer, created_at: datetime, updated_at: datetime, tally: integer)
I think I've setup the routes.rb ok but the double do I'm not sure about
Rails.application.routes.draw do
resources :topics do
member do
post 'upvote'
post 'downvote'
end
end
root 'topics#index'
end
Anyway I think it's either the wrong method to increment or something I'm missing. Any help appreciated. Cheers
::SOLVED::
I was able to fix the problem using counter_cache in the Vote model. Voting is now possible with both positive and negative values. Hooray!
Added a new column in topic.
class AddVotesCount < ActiveRecord::Migration
def change
add_column :topics, :votes_count, :integer, :default => 0
end
end
Update Vote model
class Vote < ActiveRecord::Base
belongs_to :topic, :counter_cache :true
end
Now in the topics controller I can increment the up/down methods with
@topic.votes_count += 1
.
.
.
@topic.votes_count -= 1
I can use @topic.update_attributes but I found it unreliable for some reason so I opted for @topic.save in each method.
The view now uses just topics.votes_count and works great.
<td><%= pluralize(topic.votes_count, "vote") %></td>
<td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td>
<td><%= button_to '-1', downvote_topic_path(topic), method: :post %></td>
This works without needing a User model and/or the acts_as_votable gem. Although I will probably use a gem in future it was good to figure out how to make this work without it.
Cheers