Reputation: 605
I am getting a undefined method for 'value' when running my rspec test. I am trying to get the value column in the Votes table for the respective post instance variable being ran in the rspec test. Am I calling the value wrong?
Up_votes function description:
The function is supposed to add to the array if the value of the vote is 1 and doesn't add it, if it is -1. Once that loop is completed, then it is supposed to sum the total number of votes(up votes) in that array.
Rspec error:
Failures:
1) Post vote methods #up_votes counts the number of votes with value = 1
Failure/Error: expect(@post.up_votes ).to eq(3)
NoMethodError:
undefined method `value' for #<Vote::ActiveRecord_Associations_CollectionProxy:0x007ff2e1621728>
# ./app/models/post.rb:29:in `up_votes'
# ./spec/models/post_spec.rb:14:in `block (4 levels) in <top (required)>'
Rspec test:
require 'rails_helper'
describe Post do
describe "vote methods" do
before do
@post = Post.create(title: 'Post title', body: 'Post bodies must be pretty long.')
3.times { @post.votes.create(value: 1)}
2.times { @post.votes.create(value: -1)}
end
describe '#up_votes' do
it "counts the number of votes with value = 1" do
expect(@post.up_votes ).to eq(3)
end
end
describe '#down_votes' do
it "counts the number of votes with values = -1" do
expect(@post.down_votes ).to eq(2)
end
end
describe '#points' do
it "returns the sum of all down and up votes" do
expect(@post.points ).to eq(1) # 3 - 2
end
end
end
end
Post.rb:
class Post < ActiveRecord::Base
has_many :comments, dependent: :destroy
has_many :votes
has_one :summary
belongs_to :user #means the post table has the user table's primary key in it
belongs_to :topic
mount_uploader :avatar, AvatarUploader
default_scope {order('created_at DESC')}
validates :title, length: {minimum: 5}, presence: true
validates :body, length: {minimum: 20}, presence: true
#validates :topic, presence: true
#validates :user, presence: true
def markdown_title
(render_as_markdown).render(self.title).html_safe
end
def markdown_body
(render_as_markdown).render(self.body).html_safe
end
def up_votes
vote_array = []
sum = 0
vote_array << @post.votes.value.each do |vote| unless @post.votes.value == -1
vote_catch = vote_array
end
end
vote_catch.each do |vote|
sum += vote
end
sum
end
end
Vote.rb file:
class Vote < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
Vote schema
create_table "votes", force: :cascade do |t|
t.integer "value"
t.integer "post_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Upvotes: 0
Views: 567
Reputation: 386
You're calling .value
on a collection of votes, as opposed to on a vote itself. Something like @post.votes
will return a collection.
Could you do something like this?
def up_votes
votes.where(value: 1).count
end
That should grab all of the votes for the instance of Post w/ a value of 1 and return the count.
Upvotes: 1