TES Blog

株式会社テクニカルエンジニアリングサポートに所属する社員が、自身が携わるテクノロジーやイベントに関する情報を発信しています。

RubyWorld Conference 2018に参加した感想

はじめに

2018年11月1日(木)、11月2日(金)にかけて開催された RubyWorld Conference 2018 に参加してきました。
少し間が空いてしまっていますが、印象に残ったセッションと、それに対する所感みたいなものをご紹介できればと思います。
(全部のセッションに感銘を受けましたが、すべては書ききれませんでした…😨)

続きを読む

【イベント】ボードゲーム大会を開催しました!

こんにちは!普段はインフラ業務を携わらせて頂いている もち太郎です。

今年は台風がすごかったですね!みなさん、影響なく無事過ごせましたか? そんな悪天候の中、弊社ではイベントを行いました。 今回は弊社で行いましたイベントをご紹介いたします。

f:id:manabkr:20181019102106p:plain 9/29(土)にボードゲーム大会を開催いたしました!

続きを読む

fish shell と anyenv で楽にマルチ開発環境を整えよう for Mac

こんにちは。
Web エンジニアの Hayato Yamashita です。

昨今、Docker が大きな盛り上がりを見せており、ネイティブな開発環境を整える機会が少なくなってきました。

少なくなってきましたが、まだあります。

そんな Docker を使わない/使えない場合に備えて、ネイティブでマルチな開発環境を楽に整えるため、fish shell と anyenv の導入方法について紹介します。

本記事のポイント

fish shell で anyenv を使うにあたって、公式サイトに書いてある導入方法は bash や zsh 向けになっています。

そのため、一部書き方が異なっていて詰まってしまう可能性があります。

本記事では、そうしたところで詰まらないよう動作確認した上でのコマンド、設定内容を記載していますので、参考にしてください。

続きを読む

ActiveModelSerializers をデフォルトのまま使い始めたら今さらページネーション情報を入れられなくなったあなたに贈る解決方法

はじめに

こんにちは。
Web エンジニアの Hayato Yamashita です。

普段の業務では PHP を使っていますが、弊社は Ruby 推し企業であることもあり、社内向けサービス開発や個人の趣味など、何かにつけて Ruby を触っています。

今回は Ruby on Rails で開発している時、ページネーションで困ったことを記事にしました。

この記事について

ページネーションとは、内容の多いページを複数に分割して表示する手法のことです。

Google 検索などにも用いられており、一度に読み込むデータ量を減らし、ページを早く表示できるメリットがあります。

このページネーション、非常に有用であり普遍的であるものなのですが、後から追加実装するのは大変です。

最初からページネーションを意識して開発していれば、そう難しいことではありません。
ページネーションは普遍的なものですし、サポートしてくれるプラグインもたくさんあります。

しかし、後から使う可能性があるのに、つい先延ばしにしてしまうことってありますよね。

本記事では、どのような経緯があって後からページネーションを追加しないといけなくなったのか。
そして、どのようにして後から追加したのか、詳しく記載していきます。

対象となる読者

  • Ruby on Rails を API として使っている
  • ActiveModelSerializers を導入している
  • 最初はページネーションしてなかったけど、新機能だけページネーションできるようにしたい

読んだら得られるもの

  • 後からでもページネーション機能を追加できるようになる
  • それがバッドノウハウであることを知れる(詳しくは後述)
続きを読む

弊社の夏期休暇制度が変わったお話

f:id:t-miyahara11:20180921142355p:plain

酷暑が終わったと思ったら急に天気が悪くなり、気温もグッと低下しましたね。体調を崩さないように注意したいと思います。

突然ですが、(そして9月も終わろうとしていますが…)皆さんは夏休みはしっかり取れましたか?
今回は、今年から変わった弊社の夏期休暇の制度についてお話します。

続きを読む

2018年8月 アプリケーション開発向けの学生インターンシップの内容と、実施結果について

はじめに

TESでは毎年学生インターンシップの受入れを行っています。
今回は2018年8月20日から8月31日にかけての10日間、アプリケーション開発者向けをテーマとしたインターンシップを行い、日本工学院八王子専門学校様から4名の生徒さんに参加していただきました。

今回の記事ではインターンシップの活動内容と、その結果について紹介します。

目次

取り組んでもらった課題

端的にまとめると、デタラメな作りをしたアプリケーションに対して、それぞれ改善案を出して実際に修正するとしました。
私の方で用意したアプリケーション(粗悪)を対象にしてグループで話し合いながら解決手段を模索する、といった内容です。

ソースコード自体はパブリックリポジトリにて公開しています。
(意図してデタラメに作っているので粗探しはご勘弁を…🙇) github.com

開発環境

  • OS
    • Windows 7
  • 仮想環境
    • Docker
  • プログラム言語
    • Ruby 2.4
  • 開発フレームワーク
    • Ruby on Rails 5.2
  • データベース
    • MySQL 5.7
  • バージョン管理
    • Git
  • 利用サービス
    • GitHub(ソースコード管理と課題管理)
    • Slack(チャットでの相談)

Windowsをホストとして、Docker上で動作するRailsアプリケーションを構築した状態で配布しました。
今までのインターンシップではネイティブ環境上に構築することが多く、参加者の方への負担が増えて結果的に作業時間が無くなることが多々あったので、今回はDocker環境の配布を選択しました。結果的に環境構築に手間取ることがなかったため、この選択は正解だったかと思います。

スケジュール

スケジュールは以下のとおりに行いました。

  • Day 1:会社説明・案内、課題説明、開発環境構築
  • Day 2:改善案の洗い出し、GitHubのissue作成
  • Day 3〜Day 9:修正作業
  • Day 6:振り返り(KPT)実施
  • Day 10:成果発表

日々の日課として朝会(スタンディングミーティング)を開き、前日の成果と当日の作業予定の報告を行ってもらいました。
また、こちらはカリキュラムではありませんが、学生が学校に向けて提出する日報の作成を帰宅前に行っています。

Day 1

初日は会社で作業するにあたっての注意事項等について、管理本部から説明を行い、その後は会社の設備案内を行いました。
以降は私の方からインターンシップで行う活動内容の説明と、各自で開発環境の構築を行ってもらいました。

Day 2

無事開発環境が整ったところで、各自でサイトとソースコードの状態を確認して、問題点とそれに対する改善案を出してもらいました。
また、挙がったアイデアをGitHubのissueに登録して、それぞれ担当割り振りを行うように指示しました。
GitHubを利用したことのない方も居たため、issueの使い方に悩んでいましたが、一つのissueに対して一つの改善案を作成するようにアドバイスをし、整理した内容を登録してもらいました。

改善のアイデア自体については、こちらからは制限することなく自由に行ってもらったため、私ではなかなか思いつかない学生ならではのアイデアが出てきたのが非常に面白かったです。

Day 3〜Day 9

この期間はソースコードの修正作業を行ってもらいました。
皆さん本格的にRuby・Railsに触れた経験がないため、苦戦しながらの作業となり少し高いハードルだったかなと思いましたが、
担当するissueを見直し、自分の力量に見合った課題について対応を行っていました。
自主的にペアプロを行い効率化を図りながら作業をしていたり、バックエンドの実装が苦手ならフロントエンドの実装を行うなど、役割分担の工夫が印象的でした。

このフェーズでは質問を受け、開発中に発生した問題に対して「私ならこう修正する」というニュアンスのアドバイスを行いました。
現役プログラマーとしてなるべく恥ずかしくないコードを見せたつもりですが、大変不安です...😰

余談ですが、事前に埋め込んだバグに対して意図通りに引っかかってくれたので、してやったり感はありました。勿論、アドバイス時には意地悪せずに回答しています🐧

Day 6

5日間経過した段階で振り返り会を行いました。
今回はKPT法を用いて各自に Keep(赤色)Problem(黄色)Try(青色) の各付箋にそれぞれ考えていることを記載してもらいました。
厳密なKPTではなく、良かったこと・改善する必要があること・これから頑張りたいこと、といったニュアンスで考えてもらいました。

Keepと Problem

f:id:t-miyahara11:20180831165343p:plain

Try

f:id:t-miyahara11:20180831165026p:plain

前週まではグループとして課題に取り組むための会話量が少なく、なかなかコミュニケーションが図れてない場面が多かったのですが、
今回のKPTを通してお互いが何を考えているのか、どんな問題を抱えているのか話せる場ができたことで、この日以降グループとしてのまとまりが出来てきたかと思います。

Day 10

最終日はこれまでの成果についての報告会を開きました。
弊社社員の前で実際にアプリケーションの動作を見せながら、各自追加・修正した機能の説明をしてもらいました。
直前の修正でマージミスが発覚したため開始直前までドタバタしていましたが、なんとか10日間の成果を発表できていました。
報告会の終盤に質疑応答の場を設け、弊社社員からの質問に答えてもらう際、それぞれ出来たこと・工夫したことを話してもらいました。

おわりに

インターンシップに参加して良かったと思ってもらえるように準備してきましたが、最後に作成してもらった日報の中で「来ていなかったら後悔していた」とコメントがあったので、適切な応対ができたかなと思います。

今回のインターンシップの目的は、技術的なことについて主眼に置かず、グループワークや課題解決の手法について考えを巡らせる意図で企画した内容となっています。
その中で苦戦しながらもグループ開発を行い、それぞれが成長できたことが実感できて嬉しく思います。

少しでも弊社のインターンシップに興味が湧いた方がいれば幸いです。

Capistranoデプロイ実行時に、Microsoft TeamsのIncoming Webhookコネクタに向けて(Gemを拡張しつつ)通知を送る

はじめに

弊社では社内コミュニケーションツールとしてMicrosoft Teamsを利用しています。
日々アップデートしている様子もあり、リリース当初からするとSlackとの差をあまり感じなくなってきました(遊び心はSlackに軍配が上がりますね👌)

本記事ではCapistranoによるデプロイ実行時に、Teamsのチャネルに向けて作業開始の通知を送る方法についてまとめてみました。

開発環境

開発環境は以下のとおりです。

  • Ruby 2.4.2
  • Ruby on Rails 5.2
  • Capistrano 3.11.0

Incoming Webhookコネクタの導入

まずはTeamsのチャネルに対してコネクタの追加を行い、Incoming Webhookの通知先リソース名を取得します。

  • チャネル名右側の [...] から「コネクタ」を選択します。

    f:id:t-miyahara11:20180725082429p:plain

  • Incoming Webhook項目の「構成」を選択します。

    f:id:t-miyahara11:20180725082615p:plain

  • 名前(あとでTeams上で表示されます)を入力し、「作成」を選択します。

    f:id:t-miyahara11:20180725082741p:plain

  • リソース名をクリップボードにコピーします。

    f:id:t-miyahara11:20180725083058p:plain

上記手順によって取得したリソースが通知先になります。

通知用のGem

今回Incoming Webhookへ向けて通知を送る際に、こちらのGemを利用させて頂きました。

github.com

Capistranoのデプロイタスクに通知処理が組み込まれる、大変便利なGemです(ありがとうございます🙏)。
configに記載する内容はそれほど多くないため、容易に導入できると思います。

しかしそのままでは…

今回導入するIncoming Webhookコネクタに対してメッセージを送る場合は、少しだけ手を加える必要があります。
通常Incoming WebhookへメッセージをPOSTする際は、 payload をキーとしてデータを送信する必要がありますが、
Incoming Webhookコネクタに対してメッセージをPOSTする場合、payload キーを指定せずに直接JSON形式のデータを送信する必要があります。
詳しくは下記をご覧ください。

docs.microsoft.com

Gemの拡張手段

方法としては以下の手段が考えられます。

  1. 公開されているリポジトリから、ディレクトリ・ファイル構造をそのまま移植してコード修正
  2. Rubyのクラス拡張によるコード修正
  3. RubyのRefinementを使用したクラス拡張によるコード修正

1は流石に気が咎めるので却下ですね。
2でそのままモンキーパッチをする勇気はないので、3を選択しました。

追加したコード

lib/capistrano/tasks/webhook.rake

まずは lib/capistrano/tasks/webhook.rake ファイルを作成します。

# Capistrano::Hook::Webのパッチモジュール
module CapistranoHookWebRefine
  refine Capistrano::Hook::Web do
    def post(params)
      http.start do
        req                 = Net::HTTP::Post.new(uri.path)
        req['Content-Type'] = 'application/json'
        req.body            = params.to_json
        res                 = http.request(req)
        res
      end
    end
  end
end

上記コードの追加により、該当クラスのメソッドを再定義しています。
今回は post メソッドの内容を書き換えて、パラメータのHashデータをJSONに変換してbodyに渡すように修正しました。
payload キーの存在は、ここで忘れてしまいましょう。

# 独自に定義したタスクを優先させるため、gem側のcapistranoタスクを削除
Rake::Task['webhook:post:starting'].clear

namespace :webhook do
  namespace :post do
    using CapistranoHookWebRefine

    # gemのwebhookのままだと、usingで呼び出したモジュールが優先されず、
    # 拡張していない Capistrano::Hook::Web が使用されるので、別名で定義
    def web_hook(url, payload)
      return if url.nil? || payload.nil? || payload.empty?
      info "POST #{url} payload='#{payload}'"
      result = Capistrano::Hook::Web.client(url).post(payload)
      message = "HTTP #{result.code} #{result.message} body='#{result.body}'; "
      if result.is_a?(Net::HTTPSuccess)
        info message
      else
        error message
      end
    end

    desc 'Post a starting message if :webhook_url and :webhook_starting_payload are present'
    task :starting do
      run_locally do
        url     = fetch(:webhook_url)
        payload = fetch(:webhook_starting_payload)
        web_hook(url, payload)
      end
    end

    before 'deploy:starting', 'webhook:post:starting'
  end
end

上記はGemで提供されているrake taskの定義を改変したものです。
もしかすると、web_hook を定義せずにもう少しスマートにできるのかもしれませんが…。

config/deploy/production.rb
# TeamsのIncoming Webhookコネクタへの通知設定
base_paylod_params = {
  '@context' => 'http://schema.org/extensions',
  '@type' => 'MessageCard',
  themeColor: '0072c6',
  title: 'Release Production',
}

set :webhook_url, {取得したIncoming Webhookの通知先リソース}
set :webhook_starting_payload, base_paylod_params.merge(text: 'Now, deploying...')

Incoming Webhookへ渡すパラメータの指定は以下を参考にしつつ、:webhook_url には取得した通知先リソースを指定します。
Part 2: Working With Office 365 Groups And Connectors – Microsoft MVP Award Program Blog

デプロイの実行結果

普段どおり、bundle exec cap production deployを実行すると…。

f:id:t-miyahara11:20180818153224p:plain

無事メッセージが通知されました👌

課題

目標は達成できたものの、経緯を把握していない人がコードを見た時に負債だと感じる面が否めません。
Gemの構造が難しいものではないため、コードを参考にしつつ自前のGemを作成して組み込む、というのが個人的には最適解だと思いました。
いずれ時間ができた時にトライしてみようと思います。