mara
mara

Reputation: 39

Sending parameters through button on rails form_tag with put method

I have two links ( could be buttons if needed ) that say accept and decline and I need to send true or false parameters to my controller action by clicking one of those links. I don't want my parameters to be visible in the url so I need to use put method. I have tried with the link_to with defined method:

<%= link_to 'accept', { action: 'accept_offer', accept: true }, method: :put %>
<%= link_to 'decline', { action: 'accept_offer', accept: false }, method: :put %>

but my params are still visible.

I've tried using button_to but then my parameters are not passed. What is the best way to determine which option has been chosen (accept or decline) without showing parameters in url?

my route has be defined like this:

put 'offers', to: 'offers#accept_offer'

Upvotes: 0

Views: 3574

Answers (2)

jithya
jithya

Reputation: 428

i'll recommend to make a form instead of link_to and pass params in name. Use a form and POST the information.This might require additional code in source pages, but should not require logic changes in the target pages.

<% form_for @offer, :url => {:action => 'accept_offer'} do |f|%>
  <%= submit_tag "", :value => "Accept", :name => "accept" %>
  <%= submit_tag "", :value => "Decline", :name => "decline"  %>
<% end %>

in your action you'll get params[:accept] or params[:decline] based on the link you clicked.

Edited to include commas and spaces with keyword arguments on submit tag.]

Upvotes: 0

max
max

Reputation: 102343

Start with just the conventional routes:

resources :offers

Then lets use button_to to create a discrete form:

<%= button_to 'accept', @offer, method: :patch, params: { "offer[accept]" =>  true } %>
<%= button_to 'decline', @offer, method: :patch, params: { "offer[accept]" => false } %>

The params option creates hidden inputs inside the form.

Then make sure you whitelist the correct attribute:

class OffersController < ApplicationController
  def update
    @offer = Offer.find(params[:id])

    if @offer.update(offer_params)
      redirect_to @offer, success: 'Offer updated'
    else
      render :new
    end
  end

  def offer_params
     params.require(:offer).permit(:accept, :foo, :bar)
  end
end

If you need to have separate logic from the regular update then create two additional verbs:

resources :offers do
  member do
    patch :accept
    patch :decline
  end
end

<%= button_to 'accept', accept_offer_path(@offer), method: :patch %>
<%= button_to 'decline', decline_offer_path(@offer), method: :patch %>

This keeps your API restful and decriptive.

Upvotes: 0

Related Questions