In my app I have automated e-mails reminding applications to complete the next step in the interview process. The e-mail has an opt out link which, when clicked, should hit a controller action that fires a state machine event to change their state to opted_out
. The link is not working, and from the localhost console it seems to be because the link is still producing a GET request, for which there is no route (the error is ActionController::RoutingError (Not Found):
).
Here is the console displaying the undesired GET request:
Started GET "/worker/application/opt_out.1" for 10.0.2.2 at 2014-08-29 17:08:06 +0000
Processing by LandingController#show as
Parameters: {"category"=>"worker/application", "location"=>"opt_out"}
Here is the link:
link_to 'stop getting these reminders', opt_out_worker_application_url(@worker), method: :put, style: 'background-color: #fff; color: #56A0D3; display: inline-block; margin-bottom: 5px; margin: 0px; padding: 0px; text-decoration: none'
Here are all the routes for the worker
namespace:
# routes.rb
namespace :worker do
resource :application, only: [:create, :new, :show] do
member do
put 'opt_out' => 'application#opt_out'
end
end
resources :jobs do
member do
post 'compete' => 'jobs#compete'
delete 'compete' => 'jobs#withdraw'
end
resources :comments, only: [:create]
resources :timesheets, only: [:create, :new, :show]
end
resources :banks, only: [:create, :new, :destroy]
scope 'money' do
root to: 'money#index', as: 'money'
post 'withdraw' => 'money#withdraw', as: 'money_withdraw'
end
get 'profile' => 'profiles#show'
root to: 'jobs#index'
end
Here is the controller action:
# applications_controller.rb
def opt_out
@worker = Worker.find(params[:id])
if @worker.interview_requested? or @worker.onboarding_requested?
if @worker.fire_state_event(:opt_out)
AdminsMailer.sweeper_opted_out(@worker.id)
redirect_to root_url, notice: "You have successfully opted out of the application process. We're sorry to see you go, and hope you'll consider returning in the future!"
else
redirect_to root_url, alert: "There was a problem. Please contact Support if you need further assistance."
end
else
redirect_to root_url, alert: "There was a problem. Please contact Support if you need further assistance."
end
end
Here is rake routes
:
opt_out_worker_application PUT /worker/application/opt_out(.:format) worker/application#opt_out
worker_application POST /worker/application(.:format) worker/applications#create
new_worker_application GET /worker/application/new(.:format) worker/applications#new
GET /worker/application(.:format) worker/applications#show
It's because this is a link in context of an email. It's documented behavior:
method: symbol of HTTP verb - This modifier will dynamically create an HTML form and immediately submit the form for processing using the HTTP verb specified. Useful for having links perform a POST operation in dangerous actions like deleting a record (which search bots can follow while spidering your site). Supported verbs are :post, :delete, :patch, and :put. Note that if the user has JavaScript disabled, the request will fall back to using GET. If href: '#' is used and the user has JavaScript disabled clicking the link will have no effect. If you are relying on the POST behavior, you should check for it in your controller's action by using the request object's methods for post?, delete?, patch?, or put?.
There are security reasons to disallow executable JavaScript in emails, as well as forms. Therefore, it's impossible to render a form with JS and execute a PUT
request, so this falls back to GET
as stated in citation above.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句