Mahmoud Moustafa Mahmoud Moustafa - 3 months ago 22
Ruby Question

rails buttons click counter

This is another I'm-totally-new-to-Ruby-please-have-mercy situation.

So i'm trying to figure out how to make a database of all my buttons to save the click count each time they're clicked. I started a

new rails
to try it out and generated a
model Button
and a
controller buttons index


route.rbs

Rails.application.routes.draw do
resources :buttons
root 'buttons#index'
end


migration

class CreateButtons < ActiveRecord::Migration[5.0]
def change
create_table :buttons do |t|
t.integer :clicks
t.timestamps
end
end
end


buttons_controller

class ButtonsController < ApplicationController
def index
@button = Button.find(1)
end

def doit
@button = Button.find(1)
@newcount = @button.clicks + 1
Button.find(1).update_attributes(:clicks => @newcount)
end
end


Now.. i need to trigger the doit method.. is it possible to trigger a non CRUD operation ?
i tried this but it doesn't seem to work
index.html.erb

<h1>Hello, This is button and my click are :</h1>
<h1><%= @button.clicks %></h1>
<%= link_to 'click me', method: :doit %>


I know there's something I'm not getting here...
Ruby have been doing so much magic that I can't do a simple ruby method.. it have been really hard for me getting the part were methods are taking place without calling them by name..
Specially when I trigger a delete method and the destroy method is triggered by that.. I really need to get used to this too-much-magic coding

Answer

Several things to improve, I think. Please get back to me if something is not working (I did not run the code)

Make your index action list all the buttons

Controller:

def index
  @buttons = Button.all
end

View:

<h1>These are all my buttons</h1>
<% @buttons.each do |button| %>
  <%= link_to("Button #{button.id}", button_votes_path(button), method: :post) %>
<% end %>

It's common to have index show a list of resources.

Only create the routes you need, make increment a separate action

I'd chose to call it "vote". You could also call it "clicks" or "presses" or whatever.

resources :buttons, only: [:index] do
  resources :votes, only: [:create]
end

Add the votes controller

class VotesController < ApplicationController
  def create
    button = Button.find(params[:id])
    button.clicks += 1
    button.save
    redirect_to buttons_path
  end
end

No error handling here. So this is just to get you started. For the next steps I suggest you follow a tutorial or start with simpler stuff.

Comments