0

I am currently getting an undefined method for adding <% if current_user.vote_up?(@micropost) == true %>, I am unsure what is causing the error because I defined it here in the micropost controller. Any suggestions?

Micropost Controller

 def vote_up
    @micropost = Micropost.find(params[:id])
    current_user.vote_exclusively_for(@micropost)
    current_user.vote_up(@micropost)
    respond_to do |format|
      format.html { redirect_to :back }
      format.js
      end
  end

   def unvote
    @micropost = Micropost.find(params[:id])
    current_user.vote_exclusively_against(@micropost)
    current_user.unvote(@thred)
    respond_to do |format|
      format.html { redirect_to :back }
      format.js
      end
  end

Micropost HTML

<% if current_user.vote_up?(@micropost) == true %>
<div class='<%=micropost.id %>'>
<a href="/microposts/<%=micropost.id %>/vote_up" data-remote='true' class='CounterButton b2'>
<span id="CounterIcon" class="<%=micropost.id%>"></span>
</a>
</div>
<% else %>
<div class='<%=micropost.id %>'>
<a href="/microposts/<%=micropost.id %>/unvote" data-remote='true' class='CounterButton b2'>
<span id="CounterIcon" class="<%=micropost.id%>"></span>
</a>
</div>
<% end %>
Kellogs
  • 471
  • 1
  • 4
  • 17

1 Answers1

2

Controller methods can't be called directly like you intend to from the view.

Furthermore, there seems to be a bit of confusion on how the MVC separation works in Rails.

Your current_user variable (in the view) corresponds to the "Model" layer, and as such, vote_up? should be a method of whichever class current_user is an instance of. This would be defined in models/User.rb or something like that, and there should be a vote_up? method that just queries the user's instance and returns a boolean value.

This has nothing to do with the controller's vote_up action. This will not return a value per se: I understand it to actually vote up a "micropost". A method in the controller will be fired in response to a user's request, do some stuff to objects from the database (model layer), possibly put some of these model objects in variables, and invoke a view to show information to the user (possibly taken from these objects). But methods in the controllers aren't meant to be "called" from the view.

Incidentally, doing == true as you do in the Micropost HTML is redundant as by convention, methods ending in ? return a boolean value. You can just:

<% if current_user.vote_up?(@micropost) %>
Roadmaster
  • 5,297
  • 1
  • 23
  • 21
  • Thank you for explaining this, clears up a lot of misconceptions I have :) – Kellogs Feb 24 '12 at 20:58
  • @raodmaster I am kind of confused with this here, I think it should be along these lines but it won't work, can you help me out? I added `def vote_up? votes.find_by_voter_id(voteable) end` in the user model hmm unsure – Kellogs Feb 24 '12 at 21:11
  • Does the User model have a votes method or attribute? Note that if your associations are built correctly, you sould be able to do self.votes to get the user's votes. This depends on your specific project, so I suggest you read through the code, check the project's documentation, and if stuff is still unclear, refer to the excellent documentation at guides.rubyonrails.org, or even a book such as Agile Web Development with Rails. – Roadmaster Feb 25 '12 at 00:53