1

I'm using the thumbs_up gem in my application and I'm trying to figure out the best way to save votes in my controller while iterating.

Here is my model:

class Vendor < ActiveRecord::Base
    has_many    :inventory_items
    has_many    :items, through: :inventory_items
    has_many    :shopping_lists, through: :inventory_items

    acts_as_voteable
end

my current controller:

def vote_for_vendor
    # not sure what to put in here
end

def vote_against_vendor
    # not sure what to put in here
end

my current view:

<% provide(:title, 'Stores') %>

<table class="table table-condensed table-hover">

<tr>
    <th>Name</th>
    <th>Address</th>
    <th>Favorite?</th>
</tr>

    <% @vendors.each do |v| %>
<tr>

    <td><%= v.name %></td>
    <td><%= v.address %></td>
    <td>
        <% if current_user.voted_for(v) %>
            <%= link_to 'unlike', vote_against_vendor_vendors_path(vendor_id: v.id), :remote => true %>
        <% else %>
            <%= link_to 'like', vote_for_vendor_vendors_path(vendor_id: v.id), :remote => true %>
        <% end %>
    </td>
</tr>

</table>

Most of the examples I've seen have used params([]) to pass the relevant information to the controller. I don't really have params because this is just my index page that shows all vendors. How can I save votes using this gem while iterating? Thanks in advance!

Updated Controller w/ help from MrYoshi

class VendorsController < ApplicationController

    def index
        @vendors = Vendor.all
    end

    def vote_for_vendor
        vendor = Vendor.find(params[:vendor_id])
        current_user.vote_for(vendor)

        respond_to do |format|
            format.js
        end
    end

    def vote_against_vendor
        vendor = Vendor.find(params[:vendor_id])
        current_user.vote_against(vendor)

        respond_to do |format|
            format.js
        end
    end
end

my routes:

resources :vendors do
    collection { post :vote_for_vendor }
    collection { post :vote_agaist_vendor }
  end

Current Server Error

Started GET "/vendors/vote_for_vendor?vendor_id=4" for 127.0.0.1 at 2013-09-06 10:07:29 -0700

AbstractController::ActionNotFound (The action 'show' could not be found for VendorsController):

...........

Rendered /Users/#Myname/.rvm/gems/ruby-2.0.0-p195/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb within rescues/layout (0.5ms)

settheline
  • 3,333
  • 8
  • 33
  • 65

2 Answers2

1

I give you the start of what you want, and you will be able to do the rest by yourself I think:

View:

<% if current_user.voted_for(v) %>
  <%= link_to 'unlike', vote_against_vendor_vendors_path(vendor_id: v.id), :remote => true %>
<% else %>
  <%= link_to 'like', vote_for_vendor_vendors_path(vendor_id: v.id), :remote => true %>
<% end %>

Controller:

def vote_for_vendor
  vendor = Vendor.find(params[:vendor_id])
  current_user.vote_for(vendor)

  render :nothing => true
end

And the vote_against is pretty simple to guess now that you have this one above ;)

MrYoshiji
  • 54,334
  • 13
  • 124
  • 117
  • Ah cool I see how that works. Nice. I'm getting the page rendered now, but my votes aren't submitting. I've updated my controller to reflect the changes. I had to add collections for these routes to get them working. I added those as well, because I'm not sure they're set up correctly. Also, I added the format block for js and ajax. Not sure why my votes aren't submitting, thoughts? – settheline Sep 05 '13 at 21:42
  • What is the error raised @settheline? 404 Not found? No route matches [url]? Nothing at all? – MrYoshiji Sep 06 '13 at 13:14
  • Is the request sent? Does your server receive the request? What happens when it does receive the request? – MrYoshiji Sep 06 '13 at 16:03
  • Checked it out and the request is getting sent to the server. I've updated the question with server error. – settheline Sep 06 '13 at 17:08
  • You need to add `render :nothing => true` at the end of your actions in order to stop the server from redirecting/rendering any other action. – MrYoshiji Sep 06 '13 at 17:11
  • I reconfigured my `link_to` to a `button_to` and reconfigured my controller methods as well. I'm not getting votes submitted correctly. I'm not worrying about callback or anything fancy until I get the `unlike` function working. Started a new question to tackle that. If you have a moment, give it a peek please! Your answer here helped me figure out the iteration aspect of it, so thank you! http://stackoverflow.com/questions/18666945/thumbs-up-gem-rails-how-to-take-back-a-vote – settheline Sep 06 '13 at 21:36
0

For your 'current server error' (AbstractController::ActionNotFound (The action 'show' could not be found for VendorsController):), you need to add a member route to your config/routes.rb file, like this:

resources :vendors do
  member do
    post 'vote_for_vendor'
    post 'vote_against_vendor'
  end
end

You are currently using collection routes which are for resources that don't need a particular ID to work. I highly recommend reading the Rails Guide on routes:

Rails Guide Documentation on Routes

Peter H. Boling
  • 512
  • 5
  • 14