這週上課的內容和作業的概念和實作內容都是以前沒碰過的,因此週末來整個重新做一次,邊查資料、留個筆記未來可以參照。
前置作業
需要注意 ruby runtime 的版本,可以對照一下 Heroku 支援了哪些版本 ,調整 Gemfile 裡面指定的 ruby 版本。
寄信
ActionMailer
ActionMailer Basics (官方)
Ruby on Rails 實戰聖經 - ActionMailer - E-mail 發送
寄信方式
- :test
: 寄信方式設成 :test
代表並不會實際寄信出去,而是存在 ActionMailer::Base.deliveries
陣列中方便做自動化測試。
- :sendmail
: 使用伺服器的 /usr/bin/sendmail
程式來寄信
- :smtp
: 最推薦的寄信方式
新增 Mailer
在 Rails 專案生成後,不會有 app/mailers/application_mailer.rb
這個檔案存在,當第一次執行 mailer 產生器的時候,才會一併建立出來。
rails g mailer OrderMailer
接著就會有以下 prompt ,告知有什麼檔案生成:
create app/mailers/order_mailer.rb
create app/mailers/application_mailer.rb
invoke erb
create app/views/order_mailer
create app/views/layouts/mailer.text.erb
create app/views/layouts/mailer.html.erb
invoke test_unit
create test/mailers/order_mailer_test.rb
create test/mailers/previews/order_mailer_preview.rb
樣板檔案
可以看到有生成兩個樣板檔: mailer.text.erb
和 mailer.html.erb
從檔名後綴可以看出來, .text 就是純文字的信件、 .html 就會是有包含 HTML 內容的信件。
當兩個樣板檔案都存在的時候,寄信時則會將兩者的內容都帶入信件中
設定預設寄件人
在 ActionMailer 裡面,使用 default :from
可以設定預設寄件人信箱:
class ApplicationMailer < ActionMailer::Base
default :from => "foobar@example.org"
layout "mailer"
end
新增寄信的 method
打開 app/mailers/order_mailer.rb
來新增要寄信的 method 準備資料以及完成寄信的動作。新增完 method 後,在新增對應的樣板檔案,來呈現信件的內容。
因此,這個階段會做:
- 在 order_mailer.rb 中新增
notify_order_placed(order)
method - 手動新增
app/views/order_mailer/notify_order_placed.html.erb
這個樣板檔案。
因為我們要寄送的信件含有 HTML ,因此我們使用了 .html 這個後綴。
觸發寄信
ActionMailer 有個 method: deliver!
,像是這樣即可:
OrderMailer.notify_order_placed(Order.last).deliver!
也可以在 rails c
的環境下執行這個指令也可以寄信
預覽信件外觀
加入這個 gem 就可以預覽寄出去的信件
加入 Gemfile 、 bundle install 過後,在環境設定檔裡面加入以下這行
config.action_mailer.delivery_method = :letter_opener
重啟 rails s 之後,在寄信時,就不會真的祭出,而是跳出信件的預覽圖
註冊 Mailgun
設定 production 環境
這次是要 deploy 到 heroku 上面,所以要用環境變數的方式設定這些參數
...
config.action_mailer.default_url_options = { host: 'yourdomain.com' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
port: 587,
address: "smtp.mailgun.org",
user_name: ENV["MAILGUN_USERNAME"],
password: ENV["MAILGUN_PASSWORD"],
domain: ENV["MAILGUN_DOMAIN"],
authentication: :plain,
}
end
在 Heroku 設定 mailgun 要用到的環境變數
Deploy 到 Heroku 的機器上去之後,記得要設定在上面有設定到的三個 ENV 變數。
在 Heroku 的 app 設定頁面,選定 "Settings 頁籤" ,在 "Config Variables" 的 section, 就可以設定變數,點擊右邊的 "Reveal Config Vars" 按鈕就可以展開環境變數的列表了。
接著只要填入 MAILGUN_USERNAME
, MAILGUN_PASSWORD
, MAILGUN_DOMAIN
這三組 key-value 即可。
這三個值分別是對應到 mailgun 上 Domian Information 頁面的 Default SMTP Login
, Default SMTP Password
和 Login 帳號 @ 後的那段 domain 就好。
把使用者上傳的圖片丟到 S3
恩 ... 因為 heroku 不能存使用者自己上傳的圖片,所以這時候就要接 S3 來負責放圖片了。
怎麼申請及設定 S3: Heroku Dev Center - Using AWS S3 to Store Static Assets and File Uploads
怎麼在 Rails app 使用 S3:
Heroku Dev Center - Direct to S3 Image Uploads in Rails
保存 S3 的密鑰
在新增一組 key 的時候,請 務必 把密鑰資料下載下來保留好,在生成之後,管理平台上就不會有地方可以看秘鑰。如果沒有保存好的話,就只能刪掉 Key 再重新設定。
裝 fog 來介接 S3
fog
可以說是一個通用的接口,可以幫忙簡單快速的設定好不同雲端服務,如 S3, GCS 等。
...
gem "fog"
...
裝完之後跑 bundle install 就可以了
新增 CarrierWave 設定檔
並透過 fog 來設定 S3:
先新增這一個檔案,來初始化設定 CarrierWave
CarrierWave.configure do |config|
if Rails.env.production?
config.fog_credentials = {
provider: "AWS",
aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
region: ENV["AWS_REGION"] # 設定成 bucket 所在的位置,每個人可能會不同
}
config.fog_directory = ENV["AWS_BUCKET"]
# 最後要把儲存位置指定成 :fog, carrierwave 才會去用 fog 的設定
config.storage :fog
else
config.storage :file
end
end
其中的環境變數當然也要在 Heroku 上面設定好。
區域代號
region
的參數也需要根據選擇的機器設定正確的代號,可以參考官方的文件 ,如果設定錯誤,則會跳出 SocketError
移除原先設定
接著,在原本有的 image uploader class 中的儲存設定刪掉即可:
class ImageUploader < CarrierWave::Uploader::Base
...
- storage :file
...
end