iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
Software Development

Rails Active Model系列 第 18

D-18 Active Model errors - 2

  • 分享至 

  • xImage
  •  

接續前一篇,我們來聊聊 errors 的 I18n 翻譯規則。

這可以分兩個部分,因應 errors.add 可以傳入兩個 argument ,第一個是 attribute,第二個是 message。
今天先講第一部分,attribute,或者 method。

首先在完全沒有規劃 I18n 檔案的情況下,除了 EN 的其他語言應該都會顯示 translation missing: ... 在你的翻譯結果裡面。
所以我們還是先從 EN 英文開始比較單純。

一樣,我們先做出一個範例 class:

class MyCls
  include ActiveModel::Model
  attr_accessor :name
  attr_accessor :target_id
  validates_presence_of :name
  validates_presence_of :target_id
end

在完全沒有規劃翻譯檔的情況下,我們新建一個物件,並且觀察他的 error message:

obj = MyCls.new
obj.validate
obj.errors.to_a
 => ["Name can't be blank", "Target can't be blank"]

從第一個我們可以觀察到,attribute 翻譯的部分,就只是把該欄位第一個字母轉大寫而已,

但看到第二個的時候,不對呀!我的欄位明明叫做 target_id 為什麼他只顯示 Target 呢?

這是因為,翻譯欄位的時候,他事實上會去使用 self.class.human_attribute_name 以進行翻譯。而當我們沒有規劃翻譯檔的時候,這個 method 最後會直接把 attribute 先 .to_s 再接 .humanize 以順利翻出人類易讀的樣子。

然而,string.humanize 這個方法他背後其實會很雞婆的幫你去掉結尾的 _id,再把第一個字母大寫。
於是,就變成上面看到的樣子了...。

那應該如何規劃翻譯檔呢?
在您的 conig/locales/ 資料夾裡加上 en.yml 並且寫入:

en:
  activemodel:
    attributes:
      my_cls:
        name: Name
        target_id: Target ID

然後上面的在跑一次:

obj = MyCls.new
obj.validate
obj.errors.to_a
 => ["Name can't be blank", "Target ID can't be blank"]

你看,就完整翻譯出 Target ID 惹~。

注意!上面翻譯檔裡面的 activemodel 其實是根據您的 class method i18n_scope 來決定的,預設長這樣

    def i18n_scope
      :activemodel
    end

所以如果你想要,你完全可以覆寫掉這個 i18n_scope 的 method,像是:

def i18n_scope
  :my_scope
end

然後你的翻譯檔就要配合規劃,像這樣:

en:
  my_scope:
    attributes:
      my_cls:
        name: Name
        target_id: Target ID

今天大致介紹過了 attribute 的翻譯規則,下一篇再來介紹 message 的。


上一篇
D-17 Active Model errors - 1
下一篇
D-19 Active Model errors - 3
系列文
Rails Active Model28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言