Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make button change value on click in Ruby on Rails

I'm having a lot of problems getting this to work, I don't quite understand how the view sends info to controller, so it can be manipulated.

I have a button, which when clicked should change its value. Values changes between Yes / No. When the button is clicked it needs to change the corresponding value in the database, then in the view I already have the logic that decides button value.

Here's some code, how I imagine it working... show.html.erb view

<% status = @problem.status? 'No' : 'Yes' %>
<%= link_to status, @problem, :class => 'btn btn-success' %>

In my ProblemsController

def show
  @problem = Problem.find(params[:id])

  @problem.status ? @problem.status : (@problem.status == 'false')
end

def solve
end

I'm not sure if I should change the database value in show method or create another one. The problem is that I don't know how to communicate from the view to the controller. How can I do this?

I was considering adding :data { solve: @problem.status } to link_to tag, not sure if that would help though. So far I'm unable to enter solve method (I tried adding :action => 'solve' or :action => '/problems/solve' ), which didn't help. The following is something I just tried, but it doesn't work (doesn't go to solve action in ProblemsController).

<%= link_to status, @problem, :controller => 'problems', :action => 'solve', :class => 'btn' %>

I would definitely appreciate some help! Any ideas?

Edit: Added code for params in controller, which I had. Sorry I should've included it.

like image 574
Chemist Avatar asked Mar 22 '23 04:03

Chemist


1 Answers

An http "GET" request sends its data to the controller via the query parameters (the part of the URL that looks like ?someAttribute=foo&someOtherAttribute=bar).

The link_to helper can accept additional parameters which will be included in the generated URL as query parameters like I described above. The URL path helpers (such as problem_path for example), can do the same. For example: problem_path(@problem, :additionalParam=>"someValue"), which will generate something like problem/1?additionalParam=someValue.

You were on the right track with your last link_to example, you simply needed to add the additional parameters in a similar manner as described above. However, that method is unnecessarily verbose, when you can use url helpers instead.

If your requirement is to simply flop the boolean status field, the show action wouldn't be the appropriate place. I don't know if the solve action is intended to handle this flopping, but for clarity, we'll handle this activity in an action called flop, from which you can simply redirect_to the show action.

In your routes.rb, set up the flop action.

resources :problems do
    member do
        get :flop
    end
end

If you do a rake routes, you'll see you will have another URL helper that looks like:

flop_problem GET /problems/:id/flop(.:format) problem#flop

So you can write your button link_to like so:

link_to (@problem.status ? "Yes" : "No"), flop_problem_path(@problem)

Which leads to the flop action in the ProblemController:

def flop
    problem = Problem.find(params[:id])
    problem.status = !problem.status # flop the status
    problem.save

    redirect_to problem_path(problem)
end

The show action shouldn't need anything beyond loading up the problem object.

By the way, if you want to clean up the link_to code a little, add a method in the Problem model class:

class Problem < ActiveRecord::Base
    # other code ...
    def status_name
        status ? "Yes" : "No"
    end
end

Which can be used like so:

link_to @problem.status_name, flop_problem_path(@problem)
like image 70
Paul Richter Avatar answered Apr 26 '23 03:04

Paul Richter