Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Railsで海外9ヵ国にサービス展開している話 / Rails i18n
Search
rince
February 26, 2021
Programming
3
1.7k
Railsで海外9ヵ国にサービス展開している話 / Rails i18n
2021/2/26 @銀座Rails#30
Railsでのi18nの進め方と少人数で海外展開する上での設計・実装・テスト・デプロイの工夫についてお話ししました。
rince
February 26, 2021
Tweet
Share
More Decks by rince
See All by rince
あらゆる商品を扱う商品データベースを再設計した話 / product db re-architecture
rince
12
6k
Elasticsearch入門 〜前編〜
rince
0
260
ActiveSupport::Concern で学ぶRuby
rince
1
300
Railsを6年間やってきたぼくが最近Railsでハマったこと
rince
3
560
プロジェクトをまたいだIssue管理
rince
0
2.2k
そうだ Rack 作ろう。
rince
2
92
Lean Startup
rince
0
180
Yahoo!主催のOpenHackDayJapanに参加してJAXA賞をいただきました
rince
1
130
Other Decks in Programming
See All in Programming
短期間での新規プロダクト開発における「コスパの良い」Goのテスト戦略」 / kamakura.go
n3xem
2
170
rails stats で紐解く ANDPAD のイマを支える技術たち
andpad
1
300
「とりあえず動く」コードはよい、「読みやすい」コードはもっとよい / Code that 'just works' is good, but code that is 'readable' is even better.
mkmk884
3
630
Scalaから始めるOpenFeature入門 / Scalaわいわい勉強会 #4
arthur1
1
340
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
890
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
260
「Chatwork」Android版アプリを 支える単体テストの現在
okuzawats
0
180
暇に任せてProxmoxコンソール 作ってみました
karugamo
2
720
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
110
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
560
ChatGPT とつくる PHP で OS 実装
memory1994
PRO
2
120
SymfonyCon Vienna 2025: Twig, still relevant in 2025?
fabpot
3
1.2k
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
229
18k
How STYLIGHT went responsive
nonsquared
96
5.2k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Statistics for Hackers
jakevdp
796
220k
Code Review Best Practice
trishagee
65
17k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
17
2.3k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Agile that works and the tools we love
rasmusluckow
328
21k
Designing for Performance
lara
604
68k
Transcript
Railsで海外9ヵ国に サービス展開している話 2021/2/26 @銀座Rails rince (@kazumax1218)
rince (@kazumax1218) • 2011- カカクコム(食べログ→キナリノ) • 2018- メルカリ(ソウゾウ→メルペイ) • 2020-
mybest 旅とキャンプとサウナが好き。 自己紹介 0. はじめに
• Railsのi18nの基本をお伝えして、海外展開の開発面でのハードル がそこまで高くないことを知っていただく • 少人数での海外展開の工夫をお伝えして、少人数でも海外展開でき るということを知っていただく • 日本から海外にチャレンジするプロダクトが増えたらいいな😊 本発表のゴール 0.
はじめに
本日のアジェンダ 1. Railsのi18nの基本 2. どんなサービスを海外展開してるのか 3. 少人数で開発/運用するための工夫 ◦ 設計・実装 ◦
テスト・デプロイ 4. まとめ 0. はじめに
1. Railsのi18nの基本
i18n = internationalization • 国際化・多言語化 • 先頭のiと末尾のnとの間に18文字あるのでこのように略される i18nとは? 1. Railsのi18nの基本
国際化 • 使われるすべての文言やロケール固有の要素 (日付や通貨フォー マットなど) の抽象化 ローカライズ • 具体的な翻訳方法を提供したり、そのためのフォーマットを提供し たりすること
国際化とローカライズ 1. Railsのi18nの基本
1. ロケールの設定 2. コード中の文言を抽象化する 3. 訳文を与えて翻訳する 4. 日時や金額をローカライズする i18nの進め方 1.
Railsのi18nの基本
• デフォルトのロケールを変更する場合 config/application.rb • パラメータやドメインに応じてロケールを変更する場合 application_controller.rb 1. ロケールの設定 config.i18n.default_locale =
:en around_action :switch_locale def switch_locale(&action) locale = extract_locale || I18n.default_locale # paramsやドメインからlocaleを抜き出す I18n.with_locale(locale, &action) end ※ I18n.locale= を使うと同じスレッドで処理される以後のリクエストも影響を受けてしまう 1. Railsのi18nの基本
I18n.t (translate) メソッドでコード中の文言を置き換える • 各訳文の意味を適切に表すキーを与える 2. コード中の文言を抽象化する <p>Hello!</p> <p>Hello, itadori!</p>
<p><%= t :hello %></p> <p><%= t :greeting, name: 'itadori' %></p> 1. Railsのi18nの基本 動的な値は引数で渡す
各国の辞書ファイルに訳文を追加する 3. 訳文を与えて翻訳する 1. Railsのi18nの基本 # config/locales/en.yml en: hello: 'Hello!'
greeting: 'Hello, %{name}!' # config/locales/pt-BR.yml pt-BR: hello: 'Olá!' greeting: 'Olá, %{name}!' %{} で変数を式展開できる
I18n.l (localize) メソッドやヘルパーメソッドで日時や金額を現地の フォーマットに変換する 4. 日時や金額をローカライズする 1. Railsのi18nの基本 ※ https://github.com/svenfuchs/rails-i18n
にほとんどの言語の翻訳ファイルがある <h3><%= locale %></h3> <p><%= l Date.today %></p> <p><%= number_to_currency 1000 %></p>
簡単😊
Viewに大量の文章が含まれている場合は言語別にテンプレートを分ける ことも可能 • ex) プライバシーポリシー, 利用規約など • ビューファイルの拡張子の前にロケールを付ける 補足1: ローカライズ済みビューテンプレート
1. Railsのi18nの基本 app/views/pages ├── privacy_policy.en.html.slim ├── privacy_policy.pt-BR.html.slim ├── ... └── privacy_policy.vi.html.slim
Viewファイルのパスに沿った階層で訳文を定義すると、対応するView 内で「. +キー名」で訳文を参照できる • 同じキー名がいろんなページで使われる場合に便利 補足2: 訳文の遅延探索 1. Railsのi18nの基本 en:
users: index: title: 'Title A' show: title: 'Title B' app/views/users/index.html.erb <%= t '.title' %> <%# => "Title A" %> <%= t '.title' %> <%# => "Title B" %> app/views/users/show.html.erb config/locales/en.yml
2. どんなサービスを海外展開してるのか
徹底した自社検証と専門家の声をもとに 本当に良いモノを紹介して、 あなたの”選ぶ”をお手伝いする おすすめ情報サービス サービス内容 https://my-best.com 3,300万人 月間訪問者数(MAU)
商品を自社で実際に購入し、 比較・検証してデータベース化 各々に最適な商品をランキングで紹介 ①比較コンテンツ 専門家やインフルエンサーが 自身の愛用品の中からおすすめ ②アイテムリスト
世界11ヵ国にサービス展開 アメリカ ブラジル イギリス 中国 日本 タイ ベトナム インドネシア 台湾
展開国数 11 ヵ国 インド フィリピン 2. どんなサービスを海外展開してるのか ブラジル・インドネシア・タイ・台湾では既に月間数百万PVのアクセス
各国に合わせたコンテンツを作成 2. どんなサービスを海外展開してるのか Brazil (https://mybest-brazil.com.br) Thailand (https://my-best.in.th) 各国の編集者・ライターがいて、各国に合わせたコンテンツを作成している
3. 少人数で開発/運用するための工夫
• フルタイムのエンジニアが4人しかおらず、国内でのPMFが最優先の ため、海外に割けるリソースは1名以下 (We are hiring!) • 国内版は機能開発が頻繁に行われるため、国内版とはコードを分ける • 中国は各種SaaSが使えないため、中国以外の海外9ヵ国に対応する
(中国はWordPressで運用) • 機能は国によらず同じだが、コンテンツは各国で異なる • 今後まだまだ展開国は増える可能性がある 前提 3. 少人数で開発/運用するための工夫
• できるだけ開発/運用コストを抑える ◦ 1名のリソースで開発/運用が回るか? • 今後展開国が増えても破綻しない仕組みにする ◦ 20ヵ国になっても開発/運用が回るか? 基本方針 3.
少人数で開発/運用するための工夫
3-1 設計・実装 👈 3-2 テスト・デプロイ
• 開発メンバーが少なく、できるだけ運用コストを減らすため • 現状では国ごとの機能のローカライズはそこまで必要ないため 1リポジトリ複数DBで運用 選択肢 説明 向くケース 複数リポジトリ 複数DB
国ごとにコードもDBも分ける ・開発リソースがある / 展開国が少ない ・各国で機能のローカライズが必要 1リポジトリ 複数DB 各国コードは共通で、国ごとに DBを分ける ・開発リソースがない / 展開国が多い ・各国で機能のローカライズが少ない 1リポジトリ 1DB 各国コードもDBも共通で、カラ ムやテーブルでデータを分ける ・データは同じで言語が異なる ・翻訳サイト 3. 少人数で開発/運用するための工夫(設計・実装)
• 開発メンバーが少なく、できるだけ運用コストを減らすため • 現状では国ごとの機能のローカライズはそこまで必要ないため 1リポジトリ複数DBで運用 選択肢 説明 向くケース 複数リポジトリ 複数DB
国ごとにコードもDBも分ける ・開発リソースがある / 展開国が少ない ・各国で機能のローカライズが必要 1リポジトリ 複数DB 各国コードは共通で、国ごとに DBを分ける ・開発リソースがない / 展開国が多い ・各国で機能のローカライズが少ない 1リポジトリ 1DB 各国コードもDBも共通で、カラ ムやテーブルでデータを分ける ・データは同じで言語が異なる ・翻訳サイト 3. 少人数で開発/運用するための工夫(設計・実装) どの国かを環境変数で持ち、database.ymlのdatabaseやhostの値を切り替える 👈
保守性・可読性を高めるためになるべく国ごとの分岐を入れない • ex) タイムゾーン, 機能のON/OFF, GAのトラッキングIDなどの各種設定 コード内に国ごとの分岐を入れない 3. 少人数で開発/運用するための工夫(設計・実装) config.time_zone
= case ENV['OVS_CODE'] when 'br' 'Brasilia' when 'id' 'Jakarta' ... when 'vn' 'Hanoi' end
https://github.com/rubyconfig/config を使って定数を出し分ける コード内に国ごとの分岐を入れない 3. 少人数で開発/運用するための工夫(設計・実装) # config/settings/br/settings.yml time_zone: 'Brasilia' #
config/settings/id/settings.yml time_zone: 'Jakarta' # config/application.rb Settings.add_source!("#{Rails.root}/config/settings/#{ENV['OVS_CODE']}/settings.yml") Settings.add_source!("#{Rails.root}/config/settings/#{ENV['OVS_CODE']}/#{Rails.env}.yml") Settings.reload! config.time_zone = Settings.time_zone
管理画面のアカウント管理のコストを削減するためにAWSのCognitoを用い てアカウントを一元管理し、グループでアクセス権限を分ける Cognitoでアカウントを一元管理 3. 少人数で開発/運用するための工夫(設計・実装)
3-1 設計・実装 3-2 テスト・デプロイ 👈
GitHub Actionsのstrategy.matrixを用いて各国でRSpecを並列実行 各国並列でテストを行う jobs: rspec: ... strategy: fail-fast: false matrix:
ovs_code: ['br', 'id', 'in', 'ph', 'th', 'tw', 'uk', 'us', 'vn'] env: ... OVS_CODE: ${{ matrix.ovs_code }} 3. 少人数で開発/運用するための工夫(テスト・デプロイ)
運用コストを最小限にするためのインフラ 3. 少人数で開発/運用するための工夫(テスト・デプロイ) ・・・ Indonesia (ap-southeast-1) Brazil (sa-east-1) AWSのFargateを用いて、トラフィックや展開国が増えてもスケールする 仕組みを構築
Slackから全世界に一括デプロイできるようにして、デプロイの手間を削減 ChatOpsで全世界に一括デプロイ 3. 少人数で開発/運用するための工夫(テスト・デプロイ)
国とPR番号を指定して、レビュー環境にデプロイ • 本番相当のデータで各国の動作確認が可能 • 各国の開発用データの準備の手間を削減 リリース前の各国での動作確認 3. 少人数で開発/運用するための工夫(テスト・デプロイ)
大きな問題もなく、 海外9ヵ国に展開できています😊 (小さな問題はいろいろとあったので、その話もまたどこかでw)
4. まとめ
• Railsのi18nのサポートのおかげで、開発面においては海外展開の ハードルはそこまで高くない • 少人数のリソースでも開発/運用を工夫することで、複数ヵ国に海外 展開可能 • 日本から海外にチャレンジするプロダクトを増やしていきましょう 💪 まとめ
4. まとめ
ご清聴ありがとうございました!