Rails路由无法触发unsubscribe控制器动作问题求助
问题分析与解决方案
这个问题的核心原因很明确:邮件客户端不会加载Rails的JavaScript(rails-ujs),所以无法处理data-method="put"这个属性。
你在页面里用method: :put生成的链接,本质是靠Rails的JS把点击事件转换成一个带_method=put参数的POST请求,但邮件是独立的HTML内容,打开时不会加载你的应用的JS文件,所以用户点击链接时,浏览器会直接发送一个GET请求到那个URL——而你的路由只配置了PUT方法,自然就出现「No route matches [GET]」的错误了。
解决步骤:
修改路由,支持GET请求
因为邮件里的链接只能是GET请求(没办法触发JS转换),所以需要把你的取消订阅路由改成支持GET,或者同时支持GET和PUT:# 方案1:同时支持PUT和GET(兼容页面内的链接和邮件链接) match 'newsletter_subscriptions/unsubscribe/:unsubscribe_hash' => 'newsletter_subscriptions#unsubscribe', :as => 'unsubscribe', via: [:get, :put] # 方案2:直接改成GET(更适合邮件场景) get 'newsletter_subscriptions/unsubscribe/:unsubscribe_hash' => 'newsletter_subscriptions#unsubscribe', :as => 'unsubscribe'调整链接生成代码(可选)
如果改成纯GET路由,生成链接时可以去掉method: :put参数,避免不必要的data-method属性:<%= link_to 'Unsubscribe', unsubscribe_url(@unsubscribe_hash) %>确认控制器方法的幂等性
你的unsubscribe方法是把active设为false,这个操作是幂等的——就算用户多次点击取消链接,也不会产生副作用,所以用GET请求是安全的(虽然REST规范里GET不应该修改资源,但取消订阅这类操作是例外,因为它是用户明确的、无副作用的操作)。
这样修改后,邮件里的链接就能正常触发控制器的unsubscribe动作了。
内容的提问来源于stack exchange,提问作者Ernest Mistiaen
相关产品推荐
相关产品推荐

