Eight事業部 エンジニアの坂田です。
私は、今年の4月に新卒として入社しました。学生時代はアルバイトでJavaを書いたりしていましたが、Eightで扱っているRailsについてはほとんど扱ったことがなく、未経験でした。
今回はそんな私が「Eightに配属されて最初のタスク」についてどのように向き合い、解決させていったのかについて書いていこうと思います。
状況について擦り合わせ
はじめに、自分の現状のスキルについての話や、配属されるチームで今やっている事などについて上長とMTGがありました。今の自分の状況や、やれる事、Eightが実際に課題として向き合っている事を擦り合わせていき、自分が向き合う課題を決めました。
「メール配信のデザインとトリガーの可視化」をやる事に
色々な事を考慮検討し、話し合いをしていった結果、最終的に「メール配信のデザインとトリガーの可視化」というタスクを任せてもらえる事になりました。その後、具体的なEightの現状や、課題等を共有してもらいました。
Eightのメール配信
現在Eightではユーザーに対し、状況に合わせた多様なメールを配信しています。システム的に特定の時間で送っているものや、ユーザーのアクションをトリガーにして即時送信しているものなど、約70に分類できます。また、これらのメールデザインやコンテンツは日々の機能追加や改善を通してアップデートされています。
Eightのメール管理の現状
しかし、上記の70種類ほどのメールがいつ配信されているのか、どんな内容なのかについて一元管理ができていませんでした。そのため、配信されたメールのコンテンツ等を確認したい場合には、ソースコードからトリガーを解析し、その手順に従って開発環境や、ステージング環境上で、メールを送信・確認するといったことをしていました。
抱えていた課題
この状態では、以下のような課題があります。
- 現状把握にかかるため新規施策や改善サイクルの速度が落ちる
- メールが適切なタイミングや内容やデザインで送信されているかを振り返りにくい
そしてこれを1ヶ月という期間で解決する事が最初の私のタスクでした。最初は漠然としていましたが、説明を受ける中で、「なんとかしなくてはいけない」という思いが湧き上がりました。
目指す状態
上記のことを解決するためにはどうすれば良いかを自分なりに整理し、以下の事が必要であると考えました。
- Eightで配信されているメールのテンプレートや配信を一元管理できる
- 最新のメールのコンテンツやデザインが確認できる
- エンジニア以外のメンバーも確認する事ができる
そしてここからはどのようにこれらを実現させたかについて書いていきます。
スプレッドシートでリストを作成
一元管理については、スプレッドシートでやる事にしました。スプレッドシートに、それぞれのメールのタイトル、トリガー、そして、実際に送られているメールのプレビューが載っているページを作り、そこへのURLを記載する事でこのシートを見れば、いつ、誰にどのような内容のメールが送られているのかを確認できるようになると考えました。
例えば上記のようなシートを作り、リンクをクリックすると
現在送信されているメールのプレビュー画面がすぐ見えるようになるイメージです。(こちらは実際にEightが配信しているメール) そのため、常に最新のソースコードの状態でメールのプレビューが表示されるページを実装する必要がありました。
Action Mailer Preview
これはAction Mailer PreviewというRailsの機能を使うことで実現できました。既に色々な記事で紹介されていますが、簡単にどう使うかについて説明します。
rails generate
で、mailerを作成すれば、同様にmailer_previewが作成されます。存在しない場合は、config.action_mailer_preview_path
に設定しているディレクトリ配下にActionMailer::Preview
を継承したプレビュークラスを作成すればOKです。
class HogeMailer < ActionMailer def foo(user) @user = user mail to: @user.email, subject: 'Hoge mail' end end
例えば、上記のようなHogeMailerがあるとすると...
class HogeMailerPreview < ActionMailer::Preview def foo user = User.new(name: 'sakata', email: 'test@example.com') HogeMailer.foo(user) end end
こうすれば、<Application Root>/rails/mailers/<mailer name>/<method name>
にアクセスすることで、プレビューを表示する事ができます。上記の例で言うとlocalhost:3000/rails/mailers/hoge/foo
でプレビューを表示できます。
そして、このリンクをスプレッドシートに載せる事で、メールのコンテンツやデザインを直ぐに確認できるようになると考えました。
developmentモードでしか機能しない
しかし、この機能はデフォルトではRailsのdevelopmentモードでしか動きません。今回は、エンジニアだけではなく、PO/PM/デザイナー/QAなどエンジニアではないメンバーが容易に確認できるようにすることが前提としているため、さすがに、これを見るためだけにエンジニアではない人用に、RailsやDBなどの環境をローカルに構築して、プレビューを見るたびにRails serverを立ち上げていては、本末転倒です。
ステージング環境で動くようにする
そこで、私は社内からアクセスできるステージング環境でプレビューできるようにしてはどうか、と考えました。 Eightでは本番環境とは別に、エンジニア以外のメンバが実際に機能等を確認してテストをする為の本番環境に近い構成のステージング環境を用意しています。 この環境でプレビュー機能を有効にできれば、セキュリティと利便性を担保できると考えました。 ActionMailer::Previewにはdevelopmentモード以外でも有効にする機能が提供されており、developmentモード以外でもActionMailer::Previewを有効にする場合は
config.action_mailer.show_previews = true
とすればよいのですが、ステージング環境のみで確認できるようにしたいので
config.action_mailer.show_previews = Rails.env.development? || staging?
例えば上記のように設定する事で、エンジニア以外の人が見るステージング環境でプレビューできるようになります。
ローカルとステージング環境のDBの内容の差異
プレビューが表示できる環境が整ったので、ここからは約70種類のメールのPreviewを実装していく作業をしていくことにしました。しかし、実装を進めていくにつれ、環境によって上手く動かないケースが多くありました。 例えば以下のようなMailerがあるとします。
class HogeMailer < ActionMailer def foo(user_id) @user = User.find(user_id) mail to: @user.email, subject: 'Hoge mail' end end
当然ですがこういう場合は、実際にDBに存在しているデータのidを渡してあげる必要があります。
class HogeMailerPreview < ActionMailer::Preview def foo HogeMailer.foo(User.first.id) end end
最初は上記のようにしていたのですが、ローカルでは問題なく動いていたのに、ステージング環境上では上手く動作しないことがありました。それほど単純じゃないですが、例で言うと、ローカルではUserというデータが1件以上存在していたが、ステージング環境ではそのデータが無い為、エラーになってしまうというような事象が起こっていました。
テストデータを作る
どこで動かすか(DBに値が存在するか)によって、動作しなくなってしまうと、エンジニア以外のメンバーも確認する事ができるという元々のやりたい事とぶれてしまいます。なので、ローカルだろうとステージング環境だろうと、シードデータが無くても動作できるように、毎度メールプレビュー用のデータを作成する事にしました。
class HogeMailerPreview < ActionMailer::Preview def foo mail = nil ApplicationRecord.transaction do user = User.create!(name: 'sakata', email: 'test@example.com') mail = HogeMailer.foo(user) raise ActiveRecord::Rollback, 'コミットしたくない' mail end end
しかし、閲覧時にデータを作成するようにしてしまうと、そのたびにプレビュー用のデータができてしまいます。そこで、不要なデータが残らないように、トランザクションの中でmailerで必要なデータを作成し、mailを作成した後にロールバックさせる事にしました。これで、ゴミデータを溜める事なく、また、シードデータを事前に作る必要もなくプレビューがみられるようになりました。
複雑なデータ作成フロー
ただ、この作業が物凄く大変でした。
これは特にEightだからと言うより、大規模なアプリケーションならではだと思いますが、何かメールに必要な仮データを作るとき、多くの関連するデータも作成しなければならなかったり、Aを作るためにはBを作っていなくてはいけなくて、Bを作るためにはCとDが必要で…と言った感じで、Eightの事をほとんど全然知らない、Railsの経験がない自分にはかなり時間がかかってしまいました。また、それらを70種類以上作っていくという作業を1ヶ月以内で終わらせなければいけない...という漠然とした焦りを感じてしまい、作業がかなり滞っていました。
それでも
自分が何かに詰まっていた時に、先輩方は物凄くフォローしてくれて、ランチに誘ってくれたり、オススメの技術書や、仕事をしていく上での考え方を話してくれたり、忙しい中でも自分の詰まっている事について一緒に調べて、時にはペアプログラミングをしてくれる事も。ここまで支えられて、成果が出せないのはあり得ないな。という事で、これまであまり知らなかったEightの機能を実際にアプリを使いながら調べてみたり、日々自分ができなかった事を振り返り、今日より早くするために何をすればいいか? 明日はどう改善しようか? と考えながら、日々取り組みました。
実際にどうだったか
結果として、何とか与えられた1ヶ月という期日までに当初予定していたタスクを終わらせる事ができました🎉 色々試行錯誤しながらでしたが、ちゃんと期日までにやりきれた事はとてもうれしく、自信にもなりました。
成果としても、以下のような形で残すことができました。
デザイン修正が必要なものが可視化された
「このメールとこのメール同じ事言ってるよね」だったり、「こんなデザインで送ってたんだ…」というのが色々可視化出来て、メール配信における課題に向き合う上での土台作りができたと思っています。
メールに関わるタスクの速度向上に繋がる
また、エンジニアが既存のメールに修正を加える時、POが新しいメール施策を考案する時、QAがテストをする時など、これまでメールのデザインやトリガーが可視化できていない事で発生した様々なコミュニケーションコストをかなり減らす事ができたと思っています。
必要のないコードの顕在化
さらに、当初は想定していませんでしたが、トリガー等の洗い出しでソースコードを追っていく中で、実際には配信されていないのに、ソースコードだけ残っているものも結構あって、それらを見つけて、コードを削除するという負債解消的な事にも貢献出来たのはすごく良かった事かなと思っています。
終えてみて
自分は学生時代にRuby, Railsをほとんど触った事がなく配属当初、Railsを大規模に扱っているEightの開発に携わる事に少し不安を覚えていました。それでも自分はちゃんと成果として残るタスクを求めていました。今回やった事はそれにマッチしていたと思っています。
- テストデータ作成の過程で、Eightのクラス設計の知見が得られた
- トリガーを洗う中で、大規模なRailsアプリのコードを読む時間が得られた
- 自分のプルリクエストをレビューしてもらう中で、Rubyらしい書き方を学べた
- 目前にある課題にきちんと向き合い解決していく経験ができた
この経験を活かし、これからエンジニアとして邁進していきたいと思っています💪
最後に
Eightには、まだまだ向き合う課題が多く、その上で各分野に精通したエンジニアがそれらの課題に日々向き合い解決し続けています。そんなEightが今インターンを募集しています。
各分野のエキスパートから技術を学びながら、大規模サービスのリアルな課題に向き合い解決させていく事ができるEightのインターン!! 間違いなく今後の成長につながると思いますので、是非!!