我想向未完成結帳的客戶發送一封帶有魔術鏈接的電子郵件,該鏈接將在點擊update控制器中的操作之前讓他們登錄。
我在電子郵件正文中發送以下鏈接:
<%= link_to(
"Continue to checkout",
"#{checkout_url(host: @account.complete_url, id: @user.current_subscription_cart)}?msgver=#{@user.create_message_verifier}",
method: :patch,
subscription_cart: { item_id: @item_id },
) %>
我checkouts_controller有一個update動作:
def update
# update cart with item_id param and continue
end
我的routes樣子是這樣的:
resources :checkouts, only: [:create, :update]
它給出了以下update路線:
checkout_path PATCH /checkouts/:id(.:format) checkouts#update
電子郵件正文中的link_to生成帶有data-method="patch"屬性的鏈接
<a data-method="patch" href="https://demo.test.io/checkouts/67?msgver=TOKEN">Continue to checkout</a>
=> https://demo.test.io/checkouts/67?msgver=TOKEN
但是當我點擊它時,出現以下錯誤:
No route matches [GET] "/checkouts/67"
為什么它GET在我指定時嘗試請求method: :patch?
uj5u.com熱心網友回復:
正如@AbM 所指出的,您需要發送一個指向回應 GET 請求的路由的鏈接。電子郵件客戶端不太可能讓您運行 JS 或在電子郵件正文中包含表單 - 因此您不應該假設您可以發送除 GET 之外的任何內容。
如果你想要一個如何做到這一點的例子,你不必進一步查看Devise::Confirmable解決幾乎完全相同問題的模塊:
Prefix Verb Method URI Pattern Description
new_user_confirmation GET /users/confirmation/new Form for resending the confirmation email
user_confirmation GET /users/confirmation The link thats mailed out with a token added - actually confirms the user
POST /users/confirmation Resends the confirmation email
這種設計的美妙之處在于,即使不存在單獨的模型,用戶確認也被建模為 RESTful 資源。
在您的情況下,實作可能類似于:
resources :checkouts do
resource :confirmation, only: [:new, :create, :show]
end
# Handles email confirmations of checkouts
class ConfirmationsController < ApplicationController
before_action :set_checkout
# GET /checkouts/1/confirmation/new
# Form for resending the confirmation email
def new
end
# POST /checkouts/1/confirmation
# Resends the confirmation email - because shit happens.
def create
@todo generate new token and resend the confirmation email
end
# GET /checkouts/1/confirmation&token=jdW0rSaYXWI7Ck_rOeSL-A
# Confirms the checkout by verifying that a valid token is passed
def show
if @checkout.valid_token?(params[:token])
@checkout.confirm!
redirect_to '/whatever_the_next_step_is'
else
flash.now('Invalid token')
render :new, status: :unauthorized
end
end
private
def set_checkout
@checkout = Checkout.find(params[:checkout_id])
end
end
在這里,我們對 GET 請求應該始終是冪等的規則稍作改動,因為單擊鏈接實際上會更新結帳。這是一個公平的權衡,因為它需要用戶少點擊一次。
如果你想保持冪等性,你可以發送一個鏈接到edit包含update確認表單的操作。Devise::Invitable 就是這樣做的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/534554.html
下一篇:計算總價(商品數量*商品價格)
