リモートワークは一つの手段

 こんにちは、Misoca開発チームの @corocn です。自動車部品メーカ、SIerを経て、joinしました。最近はfactorioというゲームに嵌り、気づいたら連休が終わっていました。

Misocaのリモート事情

 Misocaでは、場所にとらわれない働き方を推進しており、フルリモートで開発しているメンバーが多数参加しています。

 同時期にjoinしたメンバーが4人ほどいるのですが、そのうち3人がフルリモートワーク、1人(私)がオフィスワークとなりました。2017年5月現在のメンバーの居住地を地図に表してみました。

f:id:corocn:20170510182023p:plain

 愛知は本社があるため人数多めですが、バリエーション豊かになってきました。色んな地域のメンバーが増えるといいなあと思っています。*1

フルリモート前提の組織づくり

 スムーズなコミュニケーションのために、Misocaでは以下のようなツールを使っています。

  • 社内チャット: Slack
  • ビデオ/音声通話: Google Hangouts, Slack Call, Zoom, Screenhero, Skype
  • 文章化: esa
  • タスク管理:Trello

 ミーティングはGoogle Hangoutsをメインで使用し、1on1のミーティングはSlack callを使ったり、ペアプロする時はScreenheroを使ったり等状況によって使い分けていたりします。普段の会話は、Slackでワイワイやってます。

f:id:corocn:20170414161022j:plain

 オフィスにいるメンバーは、常設してある巨大ディスプレイと会議用の広範囲集音マイクを使用して参加しています。マイク感度が高いので、リモートからの挨拶に対して、自分の席から挨拶を返すことができて、同じオフィスで働いているように感じさせてくれます。

働く場所は関係なかった

 普段オフィスで働いているメンバーも、都合に合わせてリモートワーク選択できます。私も毎日オフィスにいるのですが、実は先日初めてリモートを試しました。

「いつもと変わらず仕事ができている。なんだこれは。すごいぞ。」

と嬉しくなりました。場所を変えてもいつも通り働ける。 オフィスがあるとはいえ、前提がリモートだからこそできることだなあと思いました。今後も、雨の日などはリモートで働こうと思っています。

全員オフ会

 たまには、リモートの人も含めて全員で集まろうや!ということで こちらの記事でも触れているように、オフ会が開かれました。当日は全員がオフィスに集まって、写真を撮ったり、普段リモート経由でしかやり取りしていない相手とペアプロをしました。

「リアルでは初めまして!」

という会話が面白かったです。

目的はリモートにあらず

 リモートワークを導入したぜ!で終わっていませんか?

 目的は良いプロダクトを世の中に送り出すこと、そのために個人、チームが最大のパフォーマンスを発揮できることだと思っています。

 パフォーマンスを最大化できる環境は人それぞれで、家族のそばで働くこと、地元で働くこと、逆に、自分はオフィスにいたほうが良い。なんて人もいると思います。まつもとゆきひろ氏も語っているように、「ちょうどいい」は人それぞれなんです。

「仕事があった」のが最大の理由だけど、人口が大きすぎず、小さすぎず、(私にとって)ちょうどいい感じの都市だったのが20年住み続けた理由のような気がします。それぞれの人がじぶんの「ちょうどいい」を見つけられるといいな。 私が松江にUターンした理由 – Yukihiro Matsumoto – Medium

 その選択肢の1つとして、リモートワークが選べるのが良いのではないでしょうか。

採用

Misocaでは「ちょうどいい」を大切にするエンジニアを募集しています!

*1:愛知に本社、島根に松江オフィスがあります

再ジョインしてから10ヶ月間、Misoca内で起こった事

どうも、Misoca開発チームの @snowsunny です。

昨年の7月にMisocaに再ジョインした話を書かせて貰った者です。

tech.misoca.jp

自分の都合で、4月いっぱいでまたMisocaから旅立つ事になったので、今回は再ジョインのまとめとして、10ヶ月間でMisoca内起こった事、思った事を書いていきたいと思います。

人が増えた!!🎉

10ヶ月間で一番変わったなーと思う所であり、Misoca開発チームの文化に大きく影響を与えていると思います。

昨年の7月から今年の5月までで、開発者の人数が倍近く増えています!

自分が入った時点では、オフィスにある机や椅子、モニターにも空きがあったのですが、現在はそれでは足りなくなってきて新たな机、椅子、モニターが増えました。

オフィスにくる人だけでもその状態なのですが、リモートワークで働かれる方も増え、朝会等でGoogleハングアウトを開くと右下に多くの人のカメラ映像や、アイコンが映っていて「人増えたなー」と実感しています。

新しい人達がもたらす空気はとても新鮮で、それによって社内のコミュニケーションやプロセス、コードの見直し等、色々な事がドンドン改善・修正されていきました。

Misocaに入るまでは、同じ顔ぶれの少人数でずっと開発をする事が多かった自分としては、とても楽しい体験でした。

プロジェクトの概念の導入

これが導入されるまで、Misocaでは開発チーム全体での朝会や、ふりかえり、タスクの相談等を毎朝行っていたのですが、全てを一括で行っていた為、冗長に感じる事があり開発チームの中で大分負担になってきていました…。

そこで大きな目標に合わせて細分化された、プロジェクトと言う概念が導入されました!

プロジェクト毎に朝会やふりかえり、相談を行う事で、冗長に感じる時間を無くし、ミーティングの時間を大幅に縮小する事ができました。

前述の人が増えた事によって出来る事が増え、現在Misocaでは開発だけで4つのプロジェクトが同時進行しています。

この概念はずっと生き続けていて、現在のMisocaの開発には必要不可欠な物になっています!

詳しくは下記の記事をご覧下さい。

tech.misoca.jp

スクラム開発の実践

プロジェクトに分かれた事で、開発プロセスとして新たな試みを行いやすくなり、受発注プロジェクトで試験的に始まったのがスクラム開発でした。

前職でスクラム開発を行っていた人が居て、その人を中心にやり方が整備されて皆で実践していった感じです。

具体的には全員でプランニングポーカーでストーリーポイントを見積もって、スプリントのベロシティーを計測してバーンダウン&アップチャートを作って進捗確認をしたり、スプリントレビューで成果を振り返ったりしています。

最初は受発注プロジェクトだけで使われていた手法だったのですが、受発注でのノウハウが開発チームに共有され、現在は他のプロジェクトでもそのプロジェクトに合った方法に変えながらスクラム開発が行われる様になってきました。

こう言う新しい実験的な試みをドンドンやらせて貰えるMisocaの開発環境は本当に素晴らしいなーと思います!

自分としては「スクラム開発」って言う名前だけは知っていたのですが、実際に使ってみた事は無くとても新しい体験でした。 特にプランニングポーカーでの見積もりで全員の認識の齟齬を無くしたり、バーンダウン&アップチャートを作って進捗確認するのはとても分かり易く良いやり方だと思うので、Misocaを出た後の仕事でも是非活かしていきたいな思っています!

その他

  • Ruby会議のスポンサー参加
  • Ruby biz大賞受賞
  • 一つの終わりと新たな始まり
  • 弥生からの友
  • Misocaボードゲーム
  • 受付水漏れ騒動
  • 自動ドア粉砕事件
  • 初めてのゴルフ場 雨のち晴れ

等々、他にも色々あったですが、それはまた別の機会に。

まとめ

再ジョインして10ヶ月経ちましたが、その10ヶ月間で、Misocaの開発プロセスや環境は大きく変わっています。 もう最初にどんな感じで開発を進めていたのかハッキリ思い出せないくらいです…w

そしてその変化は良くなる為の物であり、Misocaは現在進行系で変化し続けています。 1年後くらいのMisocaの開発環境は、また大きく違うより良いものになっているんだろうなーと確信しています。

こう言う変化を続けるMisocaで働けたのは、開発者としてとても楽しく、とても良い経験になりました。

5月からMisocaを離れるのですが、Misocaで得られた経験を活かして違う仕事に邁進していこうと思います!💪

Misocaの皆様へ

再ジョインしてからの10ヶ月間、ご迷惑をおかけする事も多かったと思うですが、色々な経験をさせて頂いて感謝の念でいっぱいです。

またどこかでお会いする機会があったら仲良くしてやって下さい。

本当にありがとうございましたー! 👋 😊

村上春樹のうなぎ説を応用して、Misocaうなぎ説でチームづくりに取り組む

ユーザー、プロダクト、チーム

こんにちは、こくぼ @ です。 プロダクトをつくることと、つくりかたをデザインすることが好きです。

早速ですが、プロダクトをつくる流れをごくごく簡単にまとめてみました。 f:id:yusuke-k:20170424144635p:plain

細かいことを言うと、他にもプロダクトのリリースに至るまでのプロジェクトについての話があったり、リリース後のユーザーサポートやメトリクスの話があったりしますが割愛します。

今日はチームづくりの話をします

f:id:yusuke-k:20170426133251p:plain

よいプロダクトはよいチームによってつくられます。 よいチームをつくるためにはよいマネジメントが必要です。

ボトムアップの行動と文化は勝手には育ちません。 会社としてトップダウンで環境をつくり、指針をつくることで文化が育まれる、というのがぼくの考えです。

今日はぼくがMisocaで行っているチームづくりについてお話しします。 チーム内のコミュニケーションを活性化するために、Misocaではうなぎミーティングというものをやっています。

普段交わらない人とのコミュニケーション

数十人を超える規模の会社になると、名前も知らなければ顔もよくわからない人が出てきますよね。 そういう人とのコミュニケーションどうしてますか?

Misocaでは現在20数人のメンバーがいて、名前と顔はわかるけど、それでも日常的にかかわる人、というのは限られてきます。 何かのプロジェクトをやることになったとき、全く話したことがない人とゼロから関係をつくっていくのは大変ですよね。

ましてや、どうやって自己紹介して、どうのように相手のことを知るのか、心理的にも負担が大きいです。 そこで第三者として「うなぎ」を持ち込みます。

村上春樹のうなぎ説

f:id:yusuke-k:20170425144056p:plain

うなぎ説とは、村上春樹さんという毎年ボジョレーヌーボーの季節になるとノーベル賞を逃すことで有名な作家さんが提唱した概念です。

うなぎの話―カウンセリングの三人目のお客さん|神戸・芦屋

村上:僕はいつも、小説というのは三者協議じゃなくちゃいけないと言うんですよ。

 

柴田:三者協議?

 

村上:三者協議。僕は「うなぎ説」というのを持っているんです。僕という書き手がいて、読者がいますね。でもその二人だけじゃ、小説というのは成立しないんですよ。そこにうなぎが必要なんですよ。うなぎなるもの。

 

(略)

 

村上:いや、べつにうなぎじゃなくてもいいんだけどね(笑)。たまたま僕の場合、うなぎなんです。何でもいいんだけど、うなぎが好きだから。

 

(略)

 

柴田:それはあれですか、自分のことを書くのは大変だから、コロッケについて思うことを書きなさいっていうことですか

 

村上:同じです。コロッケでも、うなぎでも、牡蠣フライでも、何でもいいんですけど(笑)。コロッケも牡蠣フライも好きだし

 

(略)

 

村上:たとえば、柴田さんがここにあるコロッケについて原稿用紙10枚書くとする。柴田さんはただコロッケについて書いているわけであって、柴田さん自身について語っているわけじゃないんだけども、そのコロッケについての文章を読めば、柴田さんの人柄というか、世界を見る視点みたいなものが、僕にもある程度わかるわけじゃないですか

 

柴田:ええ、願わくば

 

村上:でも柴田さんが僕に向かって直接、柴田元幸とは何か、いかなる人間存在か、というような説明をはじめると、逆に柴田元幸を理解することは難しくなるかもしれない。むしろコロッケについて語ってくれた方が、僕としてはうまく柴田元幸を理解できるかもしれない。それが僕の言う物語の有効性なんですよね。

 

村上:コロッケをあいだに引き込むことによって、コロッケに何かを託すことによって、一つの立体的な風景を共有することになる。言葉ではなく、風景を共有するということが一番大事なんです。

人と人との間に「うなぎなるもの」(途中でコロッケに変わってるけど)を介在させることにより、その人の人柄がわかり、言葉だけじゃない立体的な風景を共有できる、という説です。 この話は「ナイン・インタビューズ 柴田元幸と9人の作家たち」という本での対談なのですが、これを読んだ時、村上春樹って本当に頭の良い人なんだなあ、と感心しました。 *1

Misocaうなぎ説

うなぎなるもの=プロダクト

Misocaにうなぎを持ち込むにあたり、「うなぎなるもの」を何にするのか考えました。 そして、自分たちが日々の仕事で携わっている「プロダクト」について話すのがよいのでは、という考えに至りました。 *2

f:id:yusuke-k:20170424172350p:plain

Misoca版にアレンジ

Misocaチームは小説を書くのとは違って、チーム内で多 vs 多のコミュニケーションを取るので、Misoca版にアレンジして、多人数の中で、うなぎなるものを語りあう、という形式にしました。

これは『問題解決に効く「行為のデザイン」思考法』という本で紹介されている、役職や立場を超えた部署横断で行われるワークショップから着想を得ています。

うなぎミーティング発足

目的

Misoca社内で「うなぎミーティング」を始めるにあたり、以下のように位置づけました。

f:id:yusuke-k:20170424163333p:plain

簡単に言うと

  • みんなで共通の話題でワイワイ話そうぜ!
  • 話をしたり聴いたりすることでみんなの個性を引き出そう
  • ワイワイやってコミュニケーションを活性化していこう

となります。

ミーティングの定義(フレーミング

最初にこのミーティングについて定義をしました。 話をすることを主眼においているので、それ以上の意思決定などはこの場では行いません。

普段の仕事とは違って、話すことが目的なんだよ、結果を求める場ではないだよ、というフレーミングをしました。

f:id:yusuke-k:20170424164705p:plain

手順

MisocaではTrelloを常用しているので、各自が話したいことをカードにして、みんなの前でピッチする、というやり方をしています。 そこでみんなの共感を得られたものを投票によって決めて、掘り下げて話をする、という流れになっています。

時間があるときは、投票によって選ばれたアイデアと、適当に選ばれた人が個人の主観で選んだアイデア*3の2つについて話をしています。

f:id:yusuke-k:20170424164729p:plain

やらないこと

個人の目線でフラットに話すことが大事なので、会社としてどうするか、話す内容についての優劣など、順位を付けることはやりません。 ただ、時間は限られているため、みんながみんな話したいことを話せるとは限りません。 そこは時間と効果のバランスを見てコントロールする必要があります。

Misocaでは話す内容についてはTrelloのvote機能を使って決めています。

f:id:yusuke-k:20170424164748p:plain

ポイント

「話をする」ことが大事

  • NOT 決める場
  • 少なくとも一回につき全参加者が一度は発言してもらう
  • 喋りがちの人には気もち自重してもらう

参加者がポジティブな気持ちになれることが大事

  • NOT ネガティブ
  • 一部の人が盛り上がるだけでは意味がない
  • 辛い気もちになったらワイワイできない

うなぎについて話した結果

うなぎミーティングを毎週15分ほど時間を取って、12回実施しました。 普段はTrelloを活用していますが、一度オフラインで模造紙に付箋を貼ってやってみる、ということも試しました。

(プロダクトについて話す以上、社外秘になってしまうのであんまりお見せできないのが残念です)

Trelloでやっている様子

f:id:yusuke-k:20170424173114p:plain

f:id:yusuke-k:20170427160327p:plain

f:id:yusuke-k:20170425142243p:plain

オフラインで紙に書いている様子

普段一緒に仕事しない人とグループになってワイワイ話す。 f:id:yusuke-k:20170424173500p:plain

グループで話したことをみんなの前でワイワイ話す。 f:id:yusuke-k:20170424173633p:plain

f:id:yusuke-k:20170424174831p:plain

参加者の声

始めた当初はうまくいくか不安だったのですが、思ったよりみんな積極的に話をしてくれて毎回盛り上がりました。 以下は、社内esaや日報に寄せられたコメントです。

f:id:yusuke-k:20170425113536p:plain

f:id:yusuke-k:20170425114039p:plain

f:id:yusuke-k:20170425113608p:plain

f:id:yusuke-k:20170425113645p:plain

f:id:yusuke-k:20170425113707p:plain

f:id:yusuke-k:20170425113720p:plain

f:id:yusuke-k:20170425113833p:plain

f:id:yusuke-k:20170425113437p:plain

f:id:yusuke-k:20170425113524p:plain

プロダクション

少しずつプロダクトへの反映もされるようになってきた。 具体的な成果はこれからユーザーの皆様の目にも見える形になっていくと思います。

まとめ

よかったこと

一人一人に話をしてもらうことで、その人がどういうバックグラウンドの持ち主で、どういう目線でプロダクトを見ているのかがわかるようになりました。

また、やりたいこと、できたらよいことをみんなで語ることで、その場にポジティブな空気が生まれました。 やる気やモチベーションをあげることにも効果があるんだとよい意味での発見でした。

この取組はすぐに結果が見えるものではないので、長い目で続けていければと思ってます。

これからの課題

毎回同じ話題だとダレる?

今のところ話題は尽きませんが、同じような話題が続くと食傷気味になり、ダレてきてしまうかもしれません。

そうなったときは話題を変えて、別の「うなぎなるもの」を見つけてくる必要があるかもしれません。

話したことを行動につなげていく

現状は、第一弾として話し合うことにフォーカスしました。 今後はよりアクティブな結果につなげていける話もできたらよいかな、と思ってます。

うなぎの輪を広げていく

Misocaが弥生株式会社のグループ会社になってから関係者が飛躍的に増えました。 形態や文化の異なる会社とのコミュニケーションにも有効に使えるのではないかと期待しています。

集大成

f:id:yusuke-k:20170425140516p:plain f:id:yusuke-k:20170425140316p:plain

ということで、Misocaでの集大成が無事に着地しました。 3年半の間いろんなことに取り組ませてもらったMisocaには感謝の気もちでいっぱいです。

それでは皆さん、こくぼの次回作にご期待ください。

余談

村上春樹のこういう話をたくさん読みたい人は「村上春樹河合隼雄に会いにいく」やその他のインタビュー集を読んでみるとよいでしょう。 村上春樹の小説をまだ読んだことがない人には分量的にちょうどいい「スプートニクの恋人」をオススメします。

個人的には村上春樹翻訳のティム・オブライエンがすごく好きですが、人におすすめするにはレイモンド・カーヴァーにしています。

*1:村上春樹は小説を書くよりも翻訳とかこういう対談の方が頭の良さが際立っている気がします

*2:より正確に言うと、プロダクトについて話す場をつくりたい、という課題と、チーム内のコミュニケーションを活性化したい、という課題が重なりました

*3:21世紀枠と社内では呼んでいます

設定きりわけ大作戦

Misoca開発チームの黒曜(@kokuyouwind)です。

先日秋葉原UDXで行われた技術書典2にサークル参加して情報ガールを頒布してきました。*1

本気で原稿を落としそうになりましたが、なんとか入稿できてよかったです。

f:id:kokuyouwind:20170419175003j:plain

「原稿は早めに書こう」という教訓を得た結果、この開発ブログはそこそこ早めに書き始めています。*2

🔧 環境設定について

今回は設定ファイルの話をします。

MisocaではSettingsLogicを使い、RAILS_ENVに応じて設定を切り替えられるようにしています。*3

しかしアプリケーションの成長に伴い設定ファイルが肥大化し、以下のような設定ファイルができあがっていました。

default: &default
  application: &default_application
    host_with_port: "localhost:3000"
    protocol: http
  service_a:
    host: "<%= ENV['SERVICE_A_HOST']%>"
    token: "<%= ENV['SERVICE_A_TOKEN']%>"
    user_path: /api/v1/user
    issue_path: /api/v2/issue
  # こんな感じで設定が100行くらい続く

development:
  <<: *defaults
  service_b:
    host: dev.example.com
    application_id: misoca_dev
    secret: secret_dev_b
  service_c:
    type: mock

production:
  <<: *defaults
  application: <<: *defaults_application
    host_with_port: "<%= ENV['APPLICATION_HOST_WITH_PORT']%>"
    protocol: https
  service_b:
    host: prod.example.com
    application_id: misoca
    secret: secret_prod_b
  service_c:
    type: api
    application_id: misoca
    secret: secret_prod_c
  # こんな感じで設定が50行くらい続く

こうなると、設定を追加するのも確認するのも大変になってきます。

特にしんどいのは外部サービスの設定で、

  • RAILS_ENVに関わらず、環境変数で設定を変える(service_a)
  • RAILS_ENVで切り替える(service_b)
  • 開発環境ではモックする(service_c)

など設定方法がそれぞれで変わってしまい、設定の見通しを更に悪くしています。

🔪 設定の分割

設定ファイルの肥大化を解決するため、外部サービスの設定は別ファイルに切り出していくことにしました。

service_bの設定であれば、以下のように専用の設定ファイルを読み込むコードを書いておきます。

class ServiceBSettings < Settingslogic
  source "#{Rails.root}/config/service_b.yml"
  namespace Rails.env
end

こうすると、service_b.ymlは下記のようにとてもシンプルになります。

development:
  host: dev.example.com
  application_id: misoca_dev
  secret: secret_dev_b
production:
  host: prod.example.com
  application_id: misoca
  secret: secret_prod_b

同様に、service_cの設定は以下のようになります。

development:
  type: mock
production:
  type: api
  application_id: misoca
  secret: secret_prod_c

元の設定と比べて、環境ごとの設定がわかりやすくなりましたね。

🚩 設定切り替え条件の変更

ステージングサーバと本番サーバで外部サービスの向き先を変えたい場合は、service_aのように環境変数でサーバを切り替えることになります。*4

このような設定は、SettingsLogicのnamespaceを利用して、1つの環境変数で設定項目をまとめて切り替えるようにしました。

class ServiceASettings < Settingslogic
  source "#{Rails.root}/config/service_a.yml"
  namespace ENV['SERVICE_A_ENV'] || 'development'
end

設定ファイルであるservice_a.ymlは以下のようになります。

default: &default
  user_path: /api/v1/user
  issue_path: /api/v2/issue
development:
  <<: *defaults
  host: dev.servicea.example.com
  token: token_dev
production:
  <<: *defaults
  host: servicea.example.com
  token: token_prod

こうすることで環境変数の設定が簡潔になり、各環境での設定内容をきちんと設定ファイルに記述できるようになりました。

🏗 URLの構築

上述の設定ファイルのようにホスト名とパスをそれぞれ定義した場合、URLを使う箇所で"https://#{ServiceASettings.host}#{ServiceASettings.user_path}"のようにURLを組み立てる必要が出てきます。

これは使いづらかったので、以下のように設定クラスを拡張し、*_urlに対応する設定が見つからない場合には*_pathからURLを生成して返すようにしました。

class ServiceASettings < Settingslogic
  source "#{Rails.root}/config/service_a.yml"
  namespace ENV['SERVICE_A_ENV'] || 'development'

  # *_urlが見つからず、対応する*_pathがある場合はhostを含めたフルURLを生成して返す
  def method_missing(name)
    if name =~ /_url\Z/ && host
      path_key = name.to_s.gsub(/_url\Z/, '_path').to_sym
      url = URI.join("https://#{host}/", send(path_key)).to_s
      create_accessor_for(name, url)
      url
    else
      super
    end
  end
end

これで、ServiceASettings.user_urlのようにアクセスすることができるようになります。

設定ファイルを切り分けることで、こういった各設定ごとのヘルパーも生やすことができるようになり、なかなか便利です。*5

📢 宣伝

Misocaでは設定ファイルを綺麗にしたいエンジニアを募集しています。

*1:リンク先はおためし版になってます。全文PDFはいろいろ手直しがあり、現在頒布準備中です…

*2:結局、あまり余裕のない時間に書き上がりました

*3:類似のGemにconfigなどがあります。最近だとこちらのほうが主流かもしれません。

*4:RAILS_ENVとしてstaging環境を追加する方法もありますが、環境を増やすとそれだけ複雑になるためMisocaでは行っていません。

*5:設定クラスでやるのは邪道かもしれませんが、このためだけに別のラッパークラスを作るのもなぁ… と迷った末、今回はこうしました。

❄️frozen_string_literal

こんにちは、mzpです。最近はBuckleScriptで、OCamlJavaScriptに変換して遊んでいます。

先日、Misoca開発チームでfrozen_string_literal を有効にするようにしたので、そのときの話を紹介したいと思います。

🔥有効にする前に起きたこと

Ruby 3.0からfrozen_string_literalが標準で有効になるという話もあって、一部のコードに # frozen_string_literal: true が登場するようになりました。

次第に、 # frozen_string_literal: true を書いてないと、レビューで指摘が入るようになりました。

f:id:mzp:20170411172750p:plain

f:id:mzp:20170411173000p:plain

🚓 Rubocopの設定変更

機械的にチェックできる項目をレビューで指摘するのは好きではないので、RubocopのStyle/FrozenStringLiteralCommenteを有効にし、自動でチェック・修正できるようにしました。

f:id:mzp:20170411173235p:plain

その際、既存のコードにはすべて ruboocp:disable をいれて、このルールに検知されないようにしました。

# 既存コードは frozen_string_literal: true を書いてなくても許す
%w(app lib spec config).each do |name|
  Dir["#{name}/**/*.rb"].each do |path|
    content = File.read(path, encoding: 'utf-8')
    if content !~ /\A# frozen_string_literal: true/
      File.write(path, "# rubocop:disable Style/FrozenStringLiteralComment\n" + content)
    end
  end
end

🔪Ripperによる自動書き換え

大半のファイルに rubocop:disable が書いてあるのは微妙かなと思ったので、安全に書き換えれるファイルでは frozen_string_literal を有効にするようにしました。

具体的にはRipperで全ファイルを走査して、文字列リテラルを使っていないファイルではfrozen_string_literal を有効にするようにしました。

f:id:mzp:20170411174755p:plain

require 'ripper'

class FindStringLiteral < Ripper::Filter
  def on_tstring_beg(_, data)
    data = true
  end

  def on_tstring_content(_, data)
    data = true
  end

  def heredoc_beg(_, data)
    data = true
  end
end

def string_literal?(path)
  content = File.read(path)
  FindStringLiteral.new(content).parse(false)
end

%w(app lib spec config).each do |name|
  Dir["#{name}/**/*.rb"].each do |path|
    unless string_literal?(path)
      content = File.read(path, encoding: 'utf-8')
      if content =~ %r{\A# rubocop:disable
Style/FrozenStringLiteralComment}
        File.write(path, content.gsub(/\A.*/, "# frozen_string_literal:
true"))
      end
    end
  end
end

🚀今後の予定

残ったファイルは自動では修正できないので、別の修正するたびにちょっとづつ書き直しています。ボーイスカウトルールです。

f:id:mzp:20170411175109p:plain

🔉宣伝

Misocaではコードを綺麗にしていくエンジニアを募集しています。

Controllerのリファクタリング ~または私は如何にして肥大化していくControllerをやめてDHHによるControllerの書き方を愛するようになったか~

こんにちは!
Misoca開発チームのめろたん(@renyamizuno_)です!

最近LEGOランドが開園したので行きたいのですが、地味に遠いため行けてないマンです。

最近あった面白いことは、 スマホでスクショとか撮れないなぁと思って色々確認したら、

アプリとかキャッシュとかがスマホのストレージ容量をありえないくらい超越してたことです。

はい。

今回は最近ありえないほど大きくなってしまったControllerをいかにリファクタリングしたか*1というのをざっと書きたいと思います。

おおきくなるController

どうしても大きくなっちゃいますよね。

なにも考えないと大きくなっちゃうのは知ってたので*2、 Controllerのアクションをmoduleとして切り出して、Controllerにincludeするようにしていました。

# app/controllers/hoge_contoller.rb
class HogeController < ApplicationController
  include HogeController::FugaActions

  def show
  end
    
  # ...
end

# app/controllers/hoge_contoller/fuga_actions.rb
class HogeController
  module FugaActions
    def fuga
      # ...
    end
  end
end

最初の頃は、「これめっちゃええやん。最高かよ。」と喜んでいました。

ですが、これで思考を停止してしまい機能を増やすたびにHogeActionsを増やすという愚行をやっていました。 思考を停止しているのでなーんにも気にせず追加していたのですが、ある時メンバーから 「これは…ひどいよ…。」 という声が上がってハッとして見直したら

class HogeController < ApplicationController
  include HogeController::FugaActions
  include HogeController::FugaFugaActions
  include HogeController::FugaFugaFugaActions
  include HogeController::FugaFugaFugaFugaActions
  # ...

  before_action :hoge
  before_action :hogehoge, only: :add_hoge
  # ...

  def show
  end
    
  # ...
end

実際のコードを乗っけるのは流石にアレなのでざっくりとしかかけないのですが、 実際はもっとひどくてなんか大変でした…。

さあリファクタリング

現状がやっべぇのは認識できたのでそこからどう直すか考え方針をまとめて、
メンバーにレビューしてもらい方針を固めました。

大きく3ステップで進めようとなりました。

1. たりとらんテストを足せ

そもそもなんでテスト足りてないんだよ…という話なのですが、申し訳。

Misocaではビジネスロジックをクラスに切り出して「ユースケースオブジェクト」と呼んでいます。 Controllerはユースケースオブジェクトを呼び出して、ビジネスロジック処理の結果を受け取るという風にしています。 でそのユースケースオブジェクトのユニットテストが明らかに足りていないものが多くありました…。

リファクタリングをして動作が壊れてもテストがないとわからないので、まずそのへんのテストをちゃんと一通り書こうとなりました。

2.責務を切り離せ

ユースケースオブジェクトに「『これ』をやって『これ』をする。」のような感じの物がありました。 具体的には「権限を確認」して、問題なければ「なにかを作る」のような感じでした。

これは複数の事を一つのクラスでおこなっているため良くないね。というような感じになりました。 なので責務を切り分けて、別のクラスに切り出しました。もちろんテストもちゃんとかきました。

3.HogeActionsをHogeControllerに

最後にHogeActionsとなっているのをHogeControllerに変更します。

方針としては、下の記事を参考にしてやりました。

postd.cc

これはとても一般的なパターンですよね。私も以前はもっとこのパターンを使っていました。 しかし今は「いやいや違う」と思うようになりました。indexという単一のメソッドのみを持つInboxes::PendingsControllerという、新しいコントローラを持つのです。

基本的に彼が言っているのは、コントローラはデフォルトのCRUDアクションindex、show、new、edit、create、update、destroyのみを使うべきだということです。その他のアクションはどれも専用の(それ自体はデフォルトのCRUDアクションしか持たない)コントローラの作成につながるのです。

現状のコードを見ると、

class HogeController
  module FugaActions
    def fuga
    end
  end
end

となっている。

のでこれを上の記事に従ってControllerに書き換えます。

module Hoge
  class FugaController
    def create
    end
  end
end

このfugaアクションはFugaを作るものだったので、DHHの教えに従ってcreateにリネームしました。

あとはroutes.rbを修正するのみです。

resources :hoge, only: [:show] do    
  member do
    post :fuga
  end
end

というのを

resources :hoge, only: [:show] do    
  member do
    resources :fuga, only: :create, module: 'hoge'
  end
end

のように修正して完成です!!!

まとめ

まだリファクタリング途中なのでアレですが…

before

class HogeController < ApplicationController
  include HogeController::FugaActions
  include HogeController::FugaFugaActions
  include HogeController::FugaFugaFugaActions
  include HogeController::FugaFugaFugaFugaActions
  # ...

  before_action :hoge
  before_action :hogehoge, only: :add_hoge
  # ...

  def show
  end
    
  # ...
end

after

# app/controllers/hoge_contoller.rb
class HogeController < ApplicationController
  def show
    # ...
  end
end


# app/controllers/hoge/fuga_contoller.rb
module Hoge
  class FugaController < ApplicationController
    # アクセスできるできるユーザか確認
    before :authenticate

    def create
      # ...
    end

    private

    def authenticate
      # ...
    end
  end
end

別のクラスになるのでどこまで影響があるのかわかりやすくなりましたね。 たとえばbefore_actionが、 別ファイルにあるアクションに影響が〜とかがなくなったので良いですね。 またCRUDアクションだけになるので、なにをするのかがControllerの名前だけみればわかるようになったのも良かったです。

あとDHHがこれやってるっていうのがめっちゃ安心感があってよかったです。

さいよう

Misocaではキューブリック作品が好きな人を募集しています!

*1:実際は現在進行系

*2:われわれはかしこいので

スナバからのリモート勤務

前記事の@mugi_uno と同様、3月からMisocaにリモートワーカーとしてjoinした @lulu-ulul です。

自己紹介とjoin した経緯、名古屋でのオンボーディングの後にMisocaでフルタイムのリモート勤務を1週間やってみた所感を書いていきます。

前記事で触れられてる事は私も感じていますが、繰り返しになるので省きます。

tech.misoca.jp

about me

鳥取県鳥取市在住

rubyistにはおなじみの島根と同じ山陰地方にあります。 中国地方の北側にある山陰地方、その右側担当です。 f:id:lulu-ulul:20170330102109j:plain

Misocaには松江オフィスがあるので直線距離では手前ですが、 名古屋への飛行機は無いためオフィスへのアクセスの悪さでは上かもしれないです。

鳥取の中でも東側なので関西圏へのアクセスの方が良かったりします。 大学は関西に出てましたが、Uターンで地元に戻ってきました。

鳥取

f:id:lulu-ulul:20170330101650j:plain ©鳥取県

有名な所だと砂丘・松葉ガニ・梨・山陰海岸ジオパーク辺りでしょうか。 ここ数年のネット界隈ですとスナバコーヒーやポケモンGOのスポット等が記憶に残っているかもしれません。

都市部みたいな遊びには向いてませんが、のんびり暮らして行く上では住みよい町なんじゃないかなーって思ってます。

山・海・スノースポーツ・ツーリング・温泉めぐりと一通りできるのでアウトドア派には良い土地でもあります。

今はAmazonを始め通販が充実してきているのでインドア派の自分も生活する分には特に不満はありません。

略歴

地元のシステム開発会社で研究開発やRubyを中心とした受託開発をやっていました。

県外のクライアント相手の機能追加案件が多かったため、gitベースの納品やリモートでのやり取り等に慣れる事ができました。この経験は、Misocaで生かされていると感じています。

一度退職して家族の介護をしていましたが状況が落ち着いたので就職活動を行いました。

最初は東京に出る予定で、転職先も決まりました。

しかし祖母を置いて行くのはなあという思いが強くなり、フルタイムのリモート勤務(以下フルリモート)ができる企業を探しました。

Misocaを選んだ理由

以下の理由から総合的に決めました。

  • 鳥取からフルリモートで働ける
    • くわしくは後述します(※1)
  • 自社サービスを行っている
    • 運用等も含めて全体に関わって行きたいという気持ち
    • 一つのサービスを育てていくという過程を経験してみたい
  • 地元に間接的にでも貢献できそう
    • 鳥取は中小企業の割合が高いため
  • リモート勤務が一部の人のものではなく全員の選択肢になっている
    • くわしくは後述します(※2)
  • 選考の中で社員の方やオフィスの雰囲気が掴めた
    • 選考の中で一日名古屋オフィスで作業しました!

鳥取からフルリモートで働ける(※1)

これが一番大きい理由です。

居住地を選ばない働き方ができるのは私の理想でした。

リモート勤務が一部の人のものではなく全員の選択肢になっている(※2)

名古屋在住の人も当たり前の様に利用しているので、自分だけリモートで特別扱いされている、という感覚はありません。

ミーティングの参加者全員リモート参加という日もありました!

また、フルフレックス制ではなくコアタイムを合わせて名古屋オフィスに皆が繋ぐ形態です。 オフィスを拡張した様なイメージを感じています。

リモート勤務をしてみて

良かった事

適宜家族の様子を窺う事ができる

  • 小休憩する時等についでに様子を見れるので安心できます
  • いざという時にすぐ対応できるという安心感も!

通勤時間が無い

  • 朝や夕方に家族との時間を取れる
  • 朝昼晩一緒に御飯を食べられる!

ちょっとしたタスクをこなせる

不定期に5分くらい家族の世話をしないといけない時があるのですが、すぐに対応できます。 (もちろん採用時にちゃんと伝えてあります!)

これはオフィス勤務だとまずできない事なので大変助かってます。

お魚がおいしい

鳥取は田舎ですが海産物のコスパに関してだけは都会には負けません!

白イカ!ノドグロ!もさえび!蟹!etc…

お刺身おいしい。 f:id:lulu-ulul:20170330164001j:plain

困った事

ビデオ会議の負荷が高い

MisocaではGoogle hangoutsを勤務中繋ぎっぱなしにするのですが、人数が多くなると2016年モデルのMBPでも負荷が気になるレベルでした。

→これは後日ハングアウト専用のノートPCを支給してもらえたので解決しました!

タスクに直接関係無いコミュニケーション

雑談とかの頻度はやっぱり対面でやるより減ってしまいますね。

Misocaでは最初に名古屋で14営業日程のオンボーディングがあって、人となりが大体掴めたので大分助かってます。

またSlackの個人用チャンネルが整備されていたり、日報のコメント欄でのやり取りといった文字ベースのコミュニケーションもあります。

これについては私も何か良い案があればフィードバックしていきたいなと思ってます。

他に感じた事

改善サイクルが早い

提案に対してのアクション、フィードバックが早いと感じています。

例えば全体の振り返りミーティングでは、私が入ってからでもフォーマットが2回変わりました。

単に不要な情報を削るだけではなくて、情報の出す順序を変える事で質も上がっています!

まとめ

フルリモート勤務をするにあたって、私が期待していた以上の環境がありました。

後は私がキャッチアップして期待に応えていくだけだと思っていますので頑張っていきます!


株式会社Misocaでは、家族と一緒に暮らしながら地方で頑張るエンジニアも募集しています!