ARTLoe
ARTLoe

Reputation: 1799

Unsure how to Implement GEM 'Thumbs_up' [rails 4]

Hi i'm very new to rails and any help will much appreciated. I am trying to implement the thumbs_up GEM. I have read the documentation but still find it challenging to implement it fully.

  1. what i would like is the display of an increasing figure when a user clicks on the thumbs_up image and vice-versa when a user clicks on thumbs_down image

by figure i mean: if a user clicks the image thumbs_up you see a figure of 1, if another user clicks the image thumbs_up the figure increases to 2 [displaying 2 users have liked the event giving it a thumbs_up]

Any advise along side with an explanation will be helpful - below is the stage i have reached

i have a.) run g thumbs_up & b.) rake db:migrate

Models:

#Event.rb
class Event < ActiveRecord::Base
  belongs_to :user
  acts_as_voteable
end

#User.rb
class User < ActiveRecord::Base
  has_many :events, dependent: :destroy
  acts_as_voter
end

Controller

class EventsController < ApplicationController
  before_action :set_event, only: [:show, :edit, :update, :destroy]
  before_filter :authenticate_user!

  def index
    @events = Event.order(:date)
  end

  def show
    @commentable = @event
    @comments = @commentable.comments
    @comment = Comment.new
  end

  def new
    @event = Event.new
  end

  def edit
  end

  def create
    @event = Event.new(event_params)
    @event.user = current_user

    respond_to do |format|
      if @event.save
        format.html { redirect_to @event, notice: 'Event was successfully created.' }
        format.json { render :show, status: :created, location: @event }
      else
        format.html { render :new }
        format.json { render json: @event.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @event.update(event_params)
        format.html { redirect_to @event, notice: 'Event was successfully updated.' }
        format.json { render :show, status: :ok, location: @event }
      else
        format.html { render :edit }
        format.json { render json: @event.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @event.destroy
    respond_to do |format|
      format.html { redirect_to events_url, notice: 'Event was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def vote_for
      @event = Event.find(params[:id])
      current_user.vote_for(@event)
      respond_to do |format|
        format.js
      end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_event
      @event = Event.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def event_params
      params.require(:event).permit(:name, :description, :date, :time, :city, :price, :user_id)
    end
end

Views: app/views/events/show.html.erb

<p>
  <strong>Name:</strong>
  <%= @event.name %>
</p>

<p>
  <strong>Description:</strong>
  <%= @event.description %>
</p>

<p>
  <%=link_to image_tag('thumbs_up', :border => 0), vote_for_event_path(@event), :remote => true %>
  <%=link_to image_tag('thumbs_down', :border => 0), vote_against_event_path(@event), :remote => true %>
</p>

Routes:

Rails.application.routes.draw do

  devise_for :users

  resources :events do 
    resources :comments, only: [:create, :destroy]
    member do
      post :vote_for, :vote_against
    end
  end
end

Upvotes: 2

Views: 124

Answers (1)

joelparkerhenderson
joelparkerhenderson

Reputation: 35483

To show the votes in your view, use the votes_for method and votes_against method.

For example in your view add these lines:

<p>
  <strong>Votes For:</strong>
  <%= @event.votes_for %>
</p>

<p>
  <strong>Votes Against:</strong>
  <%= @event.votes_against %>
</p>

Because you are learning Rails, I suggest you try using basic HTML links instead of AJAX links:

<%=link_to image_tag('thumbs_up', :border => 0), vote_for_event_path(@event) %>
<%=link_to image_tag('thumbs_down', :border => 0), vote_against_event_path(@event) %>

A basic link can help you see what's happening, and your controller will reload the entire page.

When you get the basic links working, then read about AJAX, and how to use the Rails link_to with remote: true to update an HTML div.

There are various ways to accomplish this: you can read about using Rails responders, or using coffescript, or using jQuery to attach a link handler.

There are also various user interface solutions, such as updating the vote immediately because you know the original vote and you can increment the vote immediately on the client side.

Here's a related StackOverflow question that has a bunch of good answers and discussion about remote_to and replacing a div: rails link_to :remote

Upvotes: 2

Related Questions