基本會員註冊登入沒問題後,剛開始大家可能會想先處理的,就是註冊的一些欄位新增與資料要寫入資料庫會碰到問題,以及個別通知訊息及標籤的 i18n 中文化等等,所以本篇會介紹關於 i18n 這個套件搭配 Devise 的用法
套件有指令可以幫忙生出對應的 controller,如果前面建立的 model 是 User 且也是放在 devise 之下,用以下的指令並且 [scope] 改為 users,可以產生對應的 controller,每個 controller 內容有許多註解為提示這些 controller 是對應那些功能相關
rails g devise:controllers [scope]
rails generate devise:controllers [scope] -c=[controller's name]
注意有提示訊息提醒要確認在 routes.rb 中設定正確路徑
# 如果同上用 rails g devise:controllers user
# 想要用上其中的 sessions controller
devise_for :users, controllers: { sessions: "users/sessions" }
Devise 提供許多好用的 helper 方法,可以讓你套用在專案中。
在 controller 內可以設定 before_action 加入預設認證使用者的方法,會讓該頁面跳轉到登入頁,且需要登入後才可以進入。
before_action :authenticate_user!
判斷使用者是否已經登入?
user_signed_in?
當使用者登入後,指出目前使用者,這個指令應該會是大家用這個套件的一個主要亮點,你可以透過關聯來連結到其他的 model,去進行資料的撈取。
current_user
可以在登入對應的 scope 中使用的 session
user_session
當使用者登入時,devise 確認帳戶或更新密碼後,會去找 scope 的路徑。登入之後再把使用者導向設定好的地方。
如果自訂路徑使用 :user 的 resources,就會去 user_root_path,如果沒有設定這條路徑,就使用 root_path 為預設值,如同上一篇提到的。
如同我們手刻的時候需要將資料透過強參數清洗,避免使用者在填入資料時,強制將一大包 params 惡意送入資料庫,需要經過 controller 的允許(permit)。
devise 預設註冊只有 email 和 password 可以通過,但我們通常會客製自己的欄位,例如使用者名稱、匿稱、生日、地址等等。
Devise 中有三個 action 可以允許設定的欄位通過傳到 model,
分別是:
使用者註冊表單再額外多加其他欄位 如 username、birthday、address,必須在 ApplicationController 設定 before_action,並定義預設方法configure_permitted_parameters
來執行,並且設定 before action 當用到 devise 的 controller 就會觸發。
以下為懶人的單行寫法:
ApplicationController.rb
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :birthday, :address])
# ()內依序為 (action, 清洗的欄位1, 清洗的欄位2 ....)
# 注意欄位要用symbol
end
end
答案是可以,我一開始也覺得很奇怪,通常不該寫到最上層的地方,嘗試改動移到下面 registrations_controller 裡面,一直沒能成功,後來發現要使用到套件產生的 controller,或是其他你自己想用的 controller,需要先在路徑中指出你是用哪個 controller 來管理資料 (同前產生 controller 提示訊息提到),需要在 devise_for :users
後面加上你要使用的 controller
devise_for :users, controllers: { registrations: 'users/registrations' }
再把相關的清洗設定移到裡面
app/controller/users/registrations_controller.rb
module Users
class RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
before_action :configure_account_update_params, only: [:update]
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :birthday, :address])
end
def configure_account_update_params
devise_parameter_sanitizer.permit(:account_update, keys: [:username, :birthday, :address])
end
end
end
在 Gemfile 加上 gem "rails-i18n",然後執行 bundle
修改 config/application.rb 的預設語系:
預設應該是 en,就是英文語系,要使用中文可以改為 zh-TW
config.i18n.default_locale = "zh-TW"
i18n 使用檔案 zh-TW.yml
devise 或 i18n-devise github 上已經有許多善心人士提供對應的翻譯檔案。
在 config/locale 中找到原本的 en 檔案,如果要中文翻譯,上面設定預設語系後加入zh-TW.yml
檔案就可以。
config.password_length = 6..128 # 可以自己調整
調整後包含前面註冊時預設的顯示都會變更,可以回去看一下 view 的檔案預設產生提示字樣的寫法,自行決定是否也要跟著顯示
devise :database_authenticatable, :validatable, password_length: 10..128
似乎是這個套件存在的問題,主要是沒有/users 這個路徑。
目前根據找到的一些解法,是針對路徑修正,強制將路徑導回註冊或登入頁面
路徑 config/routes.rb
devise_scope :user do
get '/users', to: 'devise/registrations#new'
get '/users/password', to: 'devise/passwords#new'
end
參考資料: