Button_to uses POST Link_to uses GET, why? ROR - ruby-on-rails

I've ran into a ror problem using the link_to. Why does my link to use the GET method and my button_to use the POST method, after I specified my "method"=>"post" within the link_to parameters?
View:
<%= button_to "pdf", :action => 'getquote' %>
<%= link_to 'pdf', {:controller => 'inventories', :action => 'getquote', :method => :post } %>
Controller Method:
def getquote
#cart = find_cart
respond_to do |format|
format.pdf
end
end
Terminal Output (Button/Link, respectively):
Processing InventoriesController#getquote (for 127.0.0.1 at 2010-01-30 01:38:02) [POST]
Parameters: {"action"=>"getquote", "authenticity_token"=>"D2cwnHyTHgomdUM3wXBBXlOe4NQLmv1Srn0paLbExpQ=", "controller"=>"inventories"}
Processing InventoriesController#show (for 127.0.0.1 at 2010-01-30 01:39:07) [GET]
Parameters: {"method"=>"post", "action"=>"show", "id"=>"getquote", "controller"=>"inventories"}

I think your html options have to be in a separate hash from your url options:
<%= link_to 'pdf', {:controller => 'inventories', :action => 'getquote'}, {:method => :post } %>
I looked all over for a proper example, with no luck. For my code, I've mostly given up and just use the new style:
<%= link_to 'Delete', custom_event, :confirm => 'Are you sure?', :method => :delete %>

Might be useful for someone who is visiting :)
By default, button_to performs POST action only.
to do make a GET the syntax is as follows:
<%= button_to 'pdf', { :action => 'getquote'}, :method => :get %>

One possibility is that you have Javascript disabled, in which case it will fall back to a GET.

Related

Wrong controller action in rails form with link

I have a form...
= simple_form_for #form, :url => update_path, :method => :put do |form|
= form.input_field :name
= link_to image_tag asset_path("icon.png"),
{:controller => 'controller/name', :action => 'delete', :id => some.id}
= form.submit
As in above form I have a link/image/icon, which on click should fire delete action controller, but for some reason it goes to index controller action. Can someone point what's wrong here please?
When you define a resources routes, the delete action will be defined as the same url as the update action (which is accessed using PUT or PATCH HTTP verbs),
but it is accessed using the DELETE HTTP verb
All you need to do is set the link to the update path of your object and use the DELETE verb instead:
= link_to image_tag("icon.png"), update_path(id: some.id), method: :delete
Also, no need for #asset_path, I think
Try doing:
= link_to image_tag asset_path("icon.png"),
{:controller => 'controller_name', :action => 'delete_method_name', :id => some.id},
{:confirm => 'Are you sure?', :method => :delete}
Issue is that, you need to pass :method as :delete, :action should be the method name of your controller not the HTTP method.

How can I generate post link in rails 4?

I am trying to generate a link that will use post method
<%= link_to "guess", :action => "submit_guess", :method => "post" %>
But when I click on that link I am getting
No route matches [GET] "/guess/submit_guess"
<%= button_to 'guess', action: 'submit_guess' %>
Or, if you have JS enabled:
<%= link_to 'guess', action: 'submit_guess', method: :post %>
# note the symbol
(It's better to use button_to and then style it with css if necessary)
<%= link_to "guess", {:action => "submit_guess"}, :method => "post" %>

render partial on click

I would like to call partials on some standard operations. I am using this method for calling the partial:
%li= link_to 'Delete Event', 'javascript:void(0);', :class => 'alert tiny button', :data => {'reveal-id' => :RevealDelete}
= render 'layouts/reveal_delete', :item => event_display(#event.event), :resource => #event
Then in my partial,
#RevealDelete.reveal-modal
%a.close-reveal-modal ×
%h3= "Delete #{item}"
%p Are you sure you want to delete this?
=link_to "Delete #{item}", resource, :method => :delete, :remote => :true, :confirm => resource, :class => 'button close-reveal-modal'
%a.button.alert.close-reveal-modal Cancel
How can I have this has as something like:
link_to 'Delete', '#', :partial => 'layouts/delete', :remote => :true?
so that I only render that partial when clicked and not when the page loads?
You can do that with javascript like:
<%= link_to "Delete", delete_content_path, :remote => true %>
The action in your corresponding controller then will be this:
My Controller:
def delete_content
respond_to do |format|
format.js
end
end
Then you can create the delete_content.js.erb inside your correct directory of the link and there you put the following code:
delete_content.js.erb
$('#div_id').html("<%= render :partial => 'my_partial' %>");
Then in your view:
delete_content.html.erb
<div id = "div_id">
#this div is html div that will render your partial
</div>
Don't forget to put your partial _my_partial.html.erb in the same folder.
To add to the accepted answer, I only got it to work after changing the js portion to the following:
$('#div_id').html("<%= escape_javascript(render :partial => 'my_partial') %>");
Without the escape_javascript it was just rendering the partial in the background and not updating the view.
on the view do this:
link_to "Delete #{item}", '/model/confirm_deletion', :method => :delete, :remote => true #add the class and extra attributes if neeeded
on your controller
def confirm_deletion
end
and add a view to the confirm_deletion action in js
#RevealDelete.reveal-modal
%a.close-reveal-modal ×
%h3= "Delete #{item}"
%p Are you sure you want to delete this?
=link_to "Delete #{item}", resource, :method => :delete, :remote => :true, :confirm => resource, :class => 'button close-reveal-modal'
%a.button.alert.close-reveal-modal Cancel
:javascript
$(body).append($('#RevealDelete'));
that would make an ajax request to load that custom confirmation dialog, maybe you want to add some wrapper to insert the dialog instead of using body.append

Destroy method does not work, instead show method implements (Rails)

I need to make a button to destroy object.
Instead of destroy it shows fields
inex.html.erb
<%= link_to image_tag("/images/glossy_green_button.png"), device , { :html => { :method => :delete}, :controller => :devices, :action => 'destroy',:id => device.id, :onclick => 'return confirm(\'Are you sure?\');' }, :method => :turnon %>
devices_controller.rb
def destroy
#device = Device.find(params[:id])
#device.destroy
respond_to do |format|
format.html { render action: "destroy" }
format.json { head :no_content }
end
end
routes.rb
device GET /devices/:id(.:format) devices#show
PUT /devices/:id(.:format) devices#update
DELETE /devices/:id(.:format) devices#destroy
Appreciate any ideas what I got wrong.
Thank you
D
UPDATED:
<%= button_to "Delete", device , :method => :delete %>
this works fine
Which version of Rails are you using? Why your link_to method calling is so complex? It can be simply re-written. Try the following one:
<%= link_to image_tag("/images/glossy_green_button.png"), device , :method => :delete, :confirm => "Are you sure?"
Destructive actions should be performed as a form submission - http://www.w3.org/2001/tag/doc/whenToUseGet.html#checklist
use button_to (passing a :method of :delete) instead and style the button appropriately.
or Try this <%= button_to "delete", your_object, :method=>:delete, :class=>:destroy %>

Share a partial among different resources

I have the following bit of code in my views:
- if admin?
.meta
Administrator options:
= link_to 'Edit This Post', edit_post_path(#post)
|
= link_to 'Delete This Post', #post, :method => 'delete', :confirm => 'Are you sure?'
I find that I use this same basic snippet a lot, but sometimes with different resources, and sometimes with more than one resource on a page. I'd like to extract this into a partial to DRY it up, but I need to write is so it could work with local or instance variables for any model. For instance, I need it to work with:
#post, post, #page, page
How do you do that?
You can cleanly write your partial to be independent of the given object:
- if admin?
.meta
Administrator options:
= link_to 'Edit', [:edit, object]
|
= link_to 'Delete', object, :method => 'delete', :confirm => 'Are you sure?'
And then you could do something like
render :partial => 'shared/admin_link', :locals => { :object => #post }
You can commit a variable to a partial using the :object or the :collection options in the render method. The :object option passes a single object to the partial that can contain anything. The :collection option is used to pass an Array of Objects that must be from the same Class.
For example you have your #post and pass it to the partial like this
<%= render :partial => 'layouts/my_partial', :object => #post, :as => :my_local_var %>
Then you can access the object by calling my_local_var in the partial. Using :collection is slightly different but you can read it on your own here: http://guides.rubyonrails.org/layouts_and_rendering.html
A Problem will be the usage of one partial in different Classes because of the routes names. Then you cant use the edit_modelname_path(#instance_var) you must use the routes Hash { :controller => params[:controller], :action => 'edit' } in the link_to method!
// For Link creation wihout params[:controller] :
Its just an Idea I didnt do this before but you can try this for example:
You render the partial and use :object => #instancevar, :as => :my_local_var you can use the following line for dynamic link creation:
<%= link_to "link text", { :controller => my_local_var.class.to_s.pluralize.downcase, :action => 'edit', :id => my_local_var.id } %>
Then you dont depend on the params[:controller] but are able to link to the vars edit link.

Resources