Follow US
facebook twitter
NO. 190
TECH BLOG
じげんのテック

はじめてのRailsアプリ開発での技術的なつまずきと教訓

09.15.2022

目次

自己紹介

はじめまして。22卒エンジニアの工藤です。
好きなものはサウナとhiphopです。
大学3回生の中頃からエンジニアの勉強を始めました。最初は2ヶ月くらいで終了するスクールに入りRuby on Railsを学び、それからじげんに入るまではホームページの作成(HTML・CSS・WordPress)を個人で行っていました。
エンジニアとして技術に触れながら、ビジネスサイドも経験できるという軸で就活を行いじげんに入社しました。

本記事で伝えたいこと

この記事では、初学者の私がエンジニア研修を通してつまづいた点を書いていきます。初学者の方が、同じ轍を踏まないために解決までの道のりや教訓をお伝えします。
参考にしていただけたらとても嬉しいです!

アプリの紹介

背景

じげんでは、エンジニアは全体研修とは別にエンジニア研修を受けます。今年のエンジニア研修では、組織課題を解決する社内ツールというお題のもと、今回ご紹介するアプリを3ヶ月で作成しました。
課題発見のため、「社内コミュニケーションの活性化」という軸で人事をはじめ、さまざまな部署の社員にヒアリングを行いました。その中で、「社内の他事業部の方との関わりが薄い」という課題が見えてきました。
この課題を解決するため、私は「シャッフルランチをもっと気軽にできるアプリ『シャッフルランチくん』」を作成しました。
シャッフルランチとは、ふだんの業務では接点がない他部署の社員同士でグループを組み、ランチ会を行うイベントです。
じげんでは3ヶ月に一度「Znow」という社内交流活性化を推進するメンバーが主催していましたが、このグループ分けの作業に大幅な工数がかかっており、なかなか頻繁に実施するのが難しい様子でした。

機能

開発したシャッフルランチくんは、シャッフルランチのグループ分けを自動化するアプリです。
こちらを使うと、3ヶ月に一度ではなく毎日開催することができ、グループ分けが自動で行えるようになります。
シャッフルランチくんの画面は以下のようになっています。

アプリの動きとしては

  1. ユーザーは日時を指定する。
  2. 原則、最大人数3人とし、グループ分けを行う。
  3. Slackのチャンネルに招待し、グループを発表

という流れになっています。
以下、Slackの通知イメージです。

使用技術は、Rails7・ MySQL8・ Cloud Scheduler・ Docker・ Cloud Run です。

アプリ開発のつまずきと教訓

ここから、本題のつまずきについて書いていきます。
タイトルは、【】内が教訓で、その後が具体的なつまずきになっています。
また、本文ではつまずいた状況・解決方法・教訓を織り交ぜてご紹介します。

【ドキュメントはちゃんと読む①】カスタムバリデーションが動かない?

バリデーションとは、不正なデータがデータベースに保存されないようにする仕組みです。
例えば、電話番号を入力する画面を作っているとき、英字を入力するとエラーで弾くといったものがあります。 今回のアプリではユーザー(主催者)がランチに参加したい日付と時間を選択するのですが、ランチ開始の20分前以降は登録できないようにするために、バリデーションを書く必要がありました。
Railsにはpresence:trueなどのデフォルトのバリデーションがありますが、それでは対応ができないため、カスタムバリデーションを実装することになりました。
そこで、Railsの公式ドキュメントを参考に下記のような形で実装したのですが、うまく機能しませんでした。

間違った例(Active Record バリデーション – Railsガイドを改変)

class Invoice < ApplicationRecord
  validates :expiration_date_cannot_be_in_the_past

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date < Date.today
      errors.add(:expiration_date, "過去の日付は使えません")
    end
  end
end

もう一度、公式ドキュメントをじっくり読んでみました。すると、カスタムバリデーションではvalidatesではなくvalidateと書くことに気づきました!デフォルトのバリデーションはvalidates :name, presence: trueなどと書くのに対し、カスタムバリデーションはvalidate :expiration_date_cannot_be_in_the_pastなどにする必要があります。デフォルトの方は複数形の[s]が必要でカスタムバリデーションに複数形の[s]はつけません!すごく簡単なミスだったのですが、そのミスに気付かず、時間を浪費してしまいました。
今回の事例の様に読み飛ばすのではなく、しっかりと公式ドキュメントを読む必要があることを痛感しました。

正しい例(Active Record バリデーション – Railsガイドより引用)

class Invoice < ApplicationRecord
  validate :expiration_date_cannot_be_in_the_past

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date & Date.today
      errors.add(:expiration_date, "過去の日付は使えません")
    end
  end
end

【バージョンの違いに気をつける】 エラーメッセージが表示されない!?

いくつかのバリデーションを実装したのですが、引っ掛かった際にエラーメッセージが出力されませんでした。
入社前に会社から勉強を勧められたRuby on Rails チュートリアルでは、Rails6を使用していました。Rails6の時は以下のようなコードで表示されました。しかし、こちらで実装してみたところ、うまく行きませんでした。

def create
  @product = Product.new(product_params)
  if @product.save
    redirect_to controller: :products, action: :index
  else
    render "new"
  end
end

そこで、もしかしたらRails7から仕様が変わったのではないかと思い、調べてみると案の定変わっていました…。
Rails7からエラーメッセージを表示させるには status: :unprocessable_entityが必要になりました!詳しくは下記の記事に書かれています!
Rails 7.0 + Ruby 3.1でゼロからアプリを作ってみたときにハマったところあれこれ – Qiita

def create
  @product = Product.new(product_params)
  if @product.save
    redirect_to controller: :products, action: :index
  else
    render "new", status: :unprocessable_entity
  end
end

Railsだけではなく、gemなどもバージョンが上がると、今までと仕様が変わることがあります。もし別のプロジェクトと同じ実装で急にうまく行かなくなった際は、バージョンによる違いが原因の可能性があります。そちらも調べてみると解決へ前進できるかもしれません!

【テストは別の人の視点を入れる】BootStrapのハンバーガーメニューがクリックに反応しない!?

今回作成したアプリでは、767px以下に対応するレスポンシブ時にナビゲーションをハンバーガーメニューにしたいと考えていました。しかし、発表1日前になってハンバーガーメニューがクリックに反応しませんでした。
レスポンシブとはPCやスマホ、タブレットのデバイスに関係なく同じURL、かつそれぞれのデバイスの幅に合わせて反応よくサイトを表示させるようにすることです。
ハンバーガーメニューは画像右上のものです(Ruby on Rails チュートリアルより)。

一通りテストは行っていたのですが、レスポンシブ時のテストケースが抜けていたためギリギリになるまで気づけませんでした。しっかりテストケースをいろんな視点から作って、一度メンター陣に見てもらうべきでした。
また、ハンバーガーメニューを動かす緊急対策として同期が書いたQiita記事がありそちらを参考にしました。
rails 7系でjqueryが読み込めない問題
しかし、記事にもあるようにこちらは緊急対策用で根本的には解決できていません。解決するには、Rails7のimpotmapをしっかり理解する必要があります。こちらは今後の宿題です。

【RailsだけでなくRubyも勉強する】Slack APIのJSONから必要な情報を取ってくるには?

APIとはソフトウェアやアプリケーションなどの一部を外部に向けて公開することにより、第三者が開発したソフトウェアと機能を共有できるようにするものです。
今回はSlackの機能を使いたいのでSlackのAPIを使います。

Slackチャンネルに招待するときや、メンション(送り先の指定)をつけてグループ分けを発表する際に、対象者のメンバーIDが必要です。そこでSlackのusers.lookupByEmailメソッドを使用しました。
このメソッドは、Slackに登録されたメールアドレスからメンバーIDを取得するものです。
このメソッドのレスポンスデータを取得したかったのですが、JSON形式のデータの取り出し方を理解できていなかったので、時間を浪費してしまいました。
users.lookupByEmailメソッドのレスポンスは以下のようになっています。
users.lookupByEmail method | Slackより引用)

{
    "ok": true,
    "user": {
        "id": "W012A3CDE",
        "team_id": "T012AB3C4",
        "name": "spengler",
        "deleted": false,
        "color": "9f69e7",
        "real_name": "Egon Spengler",
        "tz": "America/Los_Angeles",
        "tz_label": "Pacific Daylight Time",
        "tz_offset": -25200,
# ...
    }
}

4行目のidを取りたい場合、どうするべきかがわからなかったのですが、以下の記事を読んで解決しました。
【Ruby on Rails 備忘録】JSON形式のデータから情報を取得する方法
user["user"]["id"]の形で指定すると取り出せます。

こちらはRailsというよりもRubyの話です。
初心者によくあるパターンとして、Railsの勉強ばかりしていてRubyを勉強していないパターン(私もです)があると思います。しかし、実際開発するとなるとRubyの知識は必須なので勉強した方が良いです!実際、Rubyを勉強し始めて読めるコードの幅がかなり増えたと感じています!

【ドキュメントはちゃんと読む②】Slackでメンションを付ける方法

グループ分けを行う際にメンションをつけたかったのですが、うまくいきませんでした。
普段Slackでは文字を入力する箇所に「@」をつけるとメンションできるのですが、送信するテキストに「@」をつけてみたところメンションにはならず、ただの文字列として表示されてしまいました…。
そこでメンションの付け方を調べてみたところ、ある記事に@usernameでメンションをつけられると書いてありました。行ってみると、まさかのただの文字列として出力されてしまいました。Slackの公式ドキュメントを見てみると、現在はメンションは<@user_id>に変更されたようです(user_idは前節で出てきたメンバーID)。
ネットにある情報は、すでに古くなっている場合があるので読むべきは公式ドキュメントだと再認識しました。
繰り返しになりますが、分からないことがあれば公式ドキュメントを読みましょう!

最後に

読んでいただきありがとうございました。
じげんに入社する前は、エンジニアの人はあまり話さなくて、気難しそうというイメージを持っていました。じげんでは全くそのようなことはなく、みなさんフレンドリーで、自分なりに考えた上で分からない時は、理解するまで教えてもらえます。
エンジニアで技術に触れながらビジネスの知見を得たい人には最高の環境だと思います!

現在じげんでは新卒エンジニアを募集しております。
もし、今回の記事を読んでみて、じげんについて気になった方はぜひOVERSの他の記事も読んでみてください。


SHARE
  • facebook
  • twitter

現在募集中の関連求人はこちら

  • Jobs 【新卒】2023年度採用

    summary
    • 募集概要

      2023年度新卒採用について、詳細は下記ページでご確認ください。

      【2023年度】じげんの新卒採用について

      <募集コース>
      ▼ビジネスコース
      事業家(=専門性と広い知識を有しビジネスをリードする人材)として事業開発に必要なスキルを多角的に身に着け、3-5年後には事業責任者として経営をリードする人材を目指していただきます。
      入社後以下いずれかの職種に配属を予定しています。
      【事業企画/マーケティング】
      多岐にわたる事業領域・プロダクトのマーケティング戦略を策定し、様々なマーケティング戦術の実行まで一気通貫で行います。主にデジタルマーケティングを用いてプロダクトのグロースを担っていただきます。
      【メディアプロデューサー】
      ディレクターとしてマーケター・エンジニア・セールス等と協働して企画立案を行い、分析、要件定義、スケジュール・リソース管理、品質管理、効果測定を担っていただきます。
      【コンサルティングセールス】
      事業家に必要な基本の力であるコンサルティング力や課題発見・解決能力を磨き、事業の成長を担っていただきます。

      ▼エンジニアコース
      自社開発メディアのフロントエンド~バックエンドまで幅広く経験し、エンジニアリング力だけでなく事業開発能力を持つエンジニアを目指していただきます。

      ▼経営戦略コース
      代表直下でM&A・管理会計に携わり、早期から専門性高く高度なコーポレートアクションにチャレンジしていただきます。

      ▼会計コース
      じげんやグループ会社の財務経理を担う部門で、専門性を高め、攻めの姿勢で事業全体をサポートしていただきます。

    • 応募条件

      2023年4月・10月に入社可能な方
      (2023年3月以降に卒業予定の方は、エントリー時にお知らせください)

    • 求める人材

      下記に強みがある方
      ・圧倒的当事者意識
      ・課題発見
      ・解決力
      ・巻き込み力
      ・やりきる力
      ・経営目線

    • 雇用形態

      正社員
      ※転勤:場合によって有
      ※グループ会社への出向の可能性がございます

    • 試用期間

      3カ月
      ※試用期間中の待遇などに変更はありません。

    • 勤務地

      勤務地はご希望を考慮の上、配属部署・職種によって決定します。

      ※東京(本社)をはじめ、名古屋・大阪・福岡・大分・沖縄各オフィス、グループ会社拠点などに配属の可能性があります。

    • 勤務時間

      フレックスタイム制(コアタイムあり)

    • 休日・休暇

      完全週休2日制(土日祝)、夏季休暇、年末年始休暇
      年次有給休暇(時間単位での取得も可能)

    • 給与

      初年度想定年収3,240,000円以上(大卒・大学院卒)
      ※月45時間の固定残業手当を含む

      ・給与改定年4回
      ・賞与:業績連動賞与制度あり(全社業績・個人の実績により支給の可能性有)
      ・残業過少者奨励金:時間外労働が月間45時間以下であった場合、残業時間過少者奨励金を支給する(10,000円)

    • 待遇

      【保険】
      各種社会保険完備(雇用・労災・健康・厚生年金)

       

      【交通費】
      全額支給

       

      【受動喫煙防止のための取組み】
      屋内原則禁煙(喫煙室あり)

       

      【福利厚生】
      ・関東ITソフトウェア健康保険組合
      ・ベネフィットステーション
      ・慶弔金
      ・委員会制度(全従業員が何らかの委員会に所属し社内制度運営や企画を担当)
      ・わくらぶ(社内クラブ活動支援)
      ・じげハン(社員紹介採用決定でインセンティブ支給)
      ・社内通貨”GAT”(一人毎月1000円分を受け取り、特にお世話になった人へ感謝の言葉と共に贈る制度)
      ・誕生日お祝い(誕生月に1万円分のアマゾンギフトカードを支給)
      ・N-minutes(1日20分間昼寝ができる制度)
      ・Fitness Hour(月2回までランチ時間を1時間延長し運動時間にあてることができる制度)
      ・社内コミュニケーション支援(年4回の全社飲み会、部署キックオフ費用負担)
      ・シャッフルランチ制度
      ・書籍購入補助/勉強会出席支援
      ・資格補助制度
      他多数
      上記以外にも、従業員からの希望や社内公募実施を通じて新制度の構築にも積極的に動いています。 

    • 選考の流れ

      応募コースやご参加いただくイベントによりご案内するステップが変更となる場合がございます。

      エントリー

      本選考イベント参加

      WEBテスト

      面接・面談(3~5回)
      +適性検査

      内定

      ※面接・面談は基本的にオンラインで実施いたします
      ※ご応募いただいてから1週間以内(※年末年始、GWを除く)にメールでご連絡いたしますので、ご確認をお願いいたします

    • よくあるご質問

      こちらをご覧くださいFAQ

Top