2014-08-29 27 views
2

在我的应用程序中,我有自动发送电子邮件提醒应用程序完成面试过程中的下一步。电子邮件有一个退出链接,点击后,该链接将触发控制器动作,触发状态机事件以将其状态更改为opted_out。该链接不工作,并从本地主机控制台,这似乎是因为链接仍然产生GET请求,没有路由(错误是ActionController::RoutingError (Not Found):)。Rails 3.2`link_to`(在电子邮件中)'method::put`仍然产生GET请求

这里是显示不想要的GET请求控制台:

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"} 

这里是链接:

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' 

这里是所有的worker命名空间的路线:

# 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 

以下是控制器操作:

# 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 

这里是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 
+0

'link_to'怎么可能是'PUT'? 'link_to'不能有字段/形式,所以将它作为'PUT'或'POST'是什么意思? – RAJ 2014-08-29 17:15:38

+0

我没有关注你,因为你问了两个似乎至少是半修辞的问题。你对我应该改变什么有什么建议吗? – sixty4bit 2014-08-29 17:18:10

+0

为什么你想link_to as PUT? – RAJ 2014-08-29 17:21:13

回答

3

这是因为这是在电子邮件的情况下的链接。这是documented behavior

方法:HTTP动词的象征 - 这个修改将动态创建一个 HTML表单,并立即提交表单使用指定的 HTTP动词处理。用于链接执行POST操作 以进行危险操作,如删除记录(搜索漫游器可在抓取您的网站时遵循 )。支持的动词是:post,:delete, :补丁和:put。请注意,如果用户禁用JavaScript,则 请求将回退到使用GET。如果使用href:'#'并且用户 禁用JavaScript,则单击该链接将不起作用。如果您的 依赖于POST行为,则应通过使用请求对象的方法进行发布?, 删除?,修补程序?或放?,在您的 控制器的操作中检查它。

存在安全原因,不允许在电子邮件中使用可执行JavaScript以及表单。因此,使用JS呈现表单并执行PUT请求是不可能的,所以这将回到上述引用中所述的GET

+0

谢谢。我非常确定自己“试图”做的事情是可能的,因为我在我的管理仪表板中有类似的链接来更改Worker状态,并且它们工作正常。无论如何,我担心情况会如此。处理这个问题的最好方法是什么?带人到另一个按钮,做同样的事情的网页? – sixty4bit 2014-08-29 17:48:44

+0

@ sixty4bit应该没问题。我在很多地方都看到了这一点。 – 2014-08-29 17:51:10

4

link_to上的方法选项适用,因为您的应用程序包含拦截点击链接的JavaScript。该javascript使用正确的方法创建窗体(为浏览器不支持的请求方法添加输入元素)并支持该方法。

这不适用于电子邮件:您的网站的JavaScript不存在,电子邮件客户端通常不会运行JavaScript。

包括一个实际的表单在某些情况下有效,但很少出现(或显示可怕的警告) - 例如参见this question。不幸的是,仅仅有一个简单的“get”链接没有多少选择(当然,你可以进入一个确认页面,在那里你有一个按钮/链接会触发一个post请求)。

+0

谢谢。我如何将工作人员的ID从电子邮件视图传递到确认页面?我可以强迫他们登录,但如果有另一种方式,我宁愿不必这样做。 – sixty4bit 2014-08-29 18:35:43

+0

你必须把这个或某种不透明的令牌标识出链接中的用户 – 2014-08-29 18:55:22

相关问题