2017/11/29
Ruby - 使用 Devise confirmable
markdown
## Devise confirmable
當你想要認證註冊者的信箱時可以使用 confirmable
安裝方式請參考:[https://github.com/plataformatec/devise/wiki/How-To:-Add-:confirmable-to-Users](https://github.com/plataformatec/devise/wiki/How-To:-Add-:confirmable-to-Users)
以下說明一些實務上的可能會遇到的細節調整方式。
## 什麼時候會寄出信?
### 建立 user 時
在建立 user 時,會在呼叫 user.save 後寄信給 user。
```
user = User.create
user.save
```
### user email 更新時
在編輯 user 時,若 email 有修改,會在呼叫 user.save 後寄信給 user。
```
user = User.find(params[:id])
user.email = 'QQ@QQ'
user.save
```
此時寫入的 email 會被保存到 unconfirmed_email,而原先的 email 欄位在 user 完成認證之前不會改變。
## 開發時測試寄信的方法
在開發時可能會希望不要真的寄出信件,此時可以使用 letter_opener,他會在需要寄信時,只將信件內容印在 console log 上。
設定方法是在 `config/environments/development.rb` 加入以下程式碼:
```
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```
## confirmable 自動測試
加入了 confirmable 之後可能會導致 test fail,因為 devise 嘗試 send mail 但是 test 環境下可能無法正確寄信。
#### 避免寄出信件的方法
如果你希望在測試時不要寄信,如果你使用 FactoryBot 這個套件來生成 user,以下是跳過 email 驗證的方法:
```
FactoryBot.define do
factory :user do
after(:build) { |u| u.skip_confirmation! }
end
end
```
在不使用 FactoryBot 的情況下,跳過 email 驗證的方法:
```
user = User.new
user.skip_confirmation!
user.save
```
#### 成功寄出信件的方法
如果你希望寄信,但是你沒有設定 host 值,那麼你會看見這個:
```
ActionView::Template::Error: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
```
此時你需要加入以下內容至 `config/environments/test.rb`:
```
config.action_mailer.delivery_method = :test
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```
### 測試寄件內容
使用 ActionMailer::Base.deliveries.last 可以取得最後一次寄出的信件內容:
```
user = User.new
user.save
mail = ActionMailer::Base.deliveries.last
mail.from
mail.to
mail.subject
mail.body.to_s
```
因此可以對信件內容做測試。
### 模擬使用者完成認證
用 code 完成認證的方法
```
user = User.find(params[:id])
user.confirm
```
## 同一個認證連結被點擊第二次會發生什麼事?
當 user 點擊第二次認證信連結時,預設是會顯示「 Email was already confirmed, please try signing in. 」字樣。可以透過自訂 controller 去修改預設行為
## 怎麼修改認證信內容?
改 template
改 template 路徑
## 自定義寄信路徑
```
class DeviseMailer < Devise::Mailer
helper :application # gives access to all helpers defined within `application_helper`.
include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`
def headers_for(action, opts)
super.merge!({template_path: '/users/mailer'}) # this moves the Devise template path from /views/devise/mailer to /views/users/mailer
end
# def confirmation_instructions(record, token, opts={})
# headers["Custom-header"] = "Bar"
# opts[:from] = 'my_custom_from@domain.com'
# opts[:reply_to] = 'my_custom_from@domain.com'
# super
# end
end
```
## 參考資料:
測試寄信的方法
[http://guides.rubyonrails.org/testing.html#testing-your-mailers](http://guides.rubyonrails.org/testing.html#testing-your-mailers)
阻止修改mail時的認證:[https://coderwall.com/p/7_yh8q/skip-devise-email-confirmation-on-update](https://coderwall.com/p/7_yh8q/skip-devise-email-confirmation-on-update)
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言