0

In the view, suppose I have a button. If I click on it, it should trigger the file download.

In my view I have:

<%= link_to 'Download File', download_file_home_path %>

In routes.rb

resources :homes, only: [:update] do
  member do
    get 'download_file'
  end
end

In homes_controller.rb

def download_file
  send_file "path/to/file.pdf"
end

When I click on the link, everything works perfectly and it triggers download. But I need a button instead of link. When I use the button_to method, it fails and I get following error:

ActionController::RoutingError (No route matches [POST] "/source_machines/4/download_report"):
  actionpack (4.2.5) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  railties (4.2.5) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.2.5) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.2.5) lib/rails/rack/logger.rb:20:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  actionpack (4.2.5) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  rack (1.6.4) lib/rack/runtime.rb:18:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  activesupport (4.2.5) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  rack-rewrite (1.5.1) lib/rack/rewrite.rb:24:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  rack (1.6.4) lib/rack/lock.rb:17:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  railties (4.2.5) lib/rails/engine.rb:518:in `call'
  railties (4.2.5) lib/rails/application.rb:165:in `call'
  railties (4.2.5) lib/rails/railtie.rb:194:in `public_send'
  railties (4.2.5) lib/rails/railtie.rb:194:in `method_missing'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  rack (1.6.4) lib/rack/deflater.rb:35:in `call'
  newrelic_rpm (3.16.1.320) lib/new_relic/agent/instrumentation/middleware_tracing.rb:96:in `call'
  rack (1.6.4) lib/rack/content_length.rb:15:in `call'
  puma (3.6.0) lib/puma/configuration.rb:225:in `call'
  puma (3.6.0) lib/puma/server.rb:578:in `handle_request'
  puma (3.6.0) lib/puma/server.rb:415:in `process_client'
  puma (3.6.0) lib/puma/server.rb:275:in `block in run'
  puma (3.6.0) lib/puma/thread_pool.rb:116:in `call'
  puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'
  logging (2.1.0) lib/logging/diagnostic_context.rb:450:in `call'
  logging (2.1.0) lib/logging/diagnostic_context.rb:450:in `block in create_with_logging_context'

My question is why does it works with link_to and does not work with button_to method, and what can I do to make it work with button_to

dhrubo_moy
  • 1,144
  • 13
  • 31
  • 1
    This is because your route for the action is created for GET request and your link is sending GET request so it working.But button_to is sending request as POST request which is not matching to any route. – prashant Aug 31 '16 at 16:27
  • Great. Added `method: "get"` and boom, it worked. Thank you so much. – dhrubo_moy Aug 31 '16 at 16:34
  • 1
    if you want to use button_to for get request. Use it like this: `<%= link_to 'Download File', download_file_home_path, method: :get %>` and it will work. – prashant Aug 31 '16 at 16:36
  • Yup. Did that. And it worked. Thanks for your comment. :) – dhrubo_moy Aug 31 '16 at 16:37

2 Answers2

1

Ok, try it:

<%= button_to 'your_button_name', your_path, method: 'get' %>
0

Following @prashant 's comment,

This is because your route for the action is created for GET request and your link is sending GET request so it working.But button_to is sending request as POST request which is not matching to any route.

So adding method: 'get' fixed the problem.

The view should look like following:

<%= button_to 'Download Report', download_file_home_path, method: 'get' %>
dhrubo_moy
  • 1,144
  • 13
  • 31