0

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

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

The count doesn't get the sum of all of the 1's together right? Its just counting the how many one's there are correct, not adding them together?
well in this case, it would be the same as its all 1's. Never mind. Thanks Alex I am marking this answer as correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.