1. はじめに
シンプルを追求したブックマークサービス「5Keeps」(ファイブキープス)を作りました。
2020年11月に未経験からプログラミングの学習を開始して、あっという間に1年が過ぎ去り、ようやく自作アプリのリリースにこぎつけました。この記事では、前半に開発したサービスについて解説し、後半に1年間の学習の過程をまとめています。
-
5Keepsへのリンク
https://five-keeps.herokuapp.com/
2. サービスについて
2-1. サービス概要
解決したい課題
プログラミング学習の環境は、時間や場所によって様々です。私の場合、家やカフェではMacbook、学校ではWindows、電車ではスマホを使ってます。最初はブラウザのブックマーク機能を活用してましたが、以下の課題を感じました。
- ブックマークが増えすぎて、今必要な情報にすぐアクセスできない。
- ブックマークの整理が大変。
そこで、これらの課題を解決するブックマークサービスを、自作アプリの題材に選びました。
解決方法
以下のように機能を制限し、「今」必要な情報だけを、「分かりやすく」保存できる仕様にすることで、課題を解決しています。
- グループを5つまで作成できる。
- リンクをグループ毎に5つまで作成できる。
- リンクには必ずタイトルをつける。
2-2. 使い方(お試し用)
1. 言語を選択し、「まずはお試し」ボタンからゲストページに移動
2. グループを作成
3. グループを選択し、リンクを作成
2-3. 機能一覧
ユーザー関係
・ユーザーの作成、編集、削除
・ユーザー認証(ログインの保持を選択可)
・メールを使用したアカウント有効化
・メールを使用したパスワード再設定
・ゲストログイン機能(詳細は後述)
グループ関係
・グループの作成、表示、編集、削除(非同期通信)
リンク関係
・リンクの作成、表示、編集、削除(非同期通信)
・URLから、リンク先WebサイトのOGP情報を取得・表示(RubyのNokogiri gemを使用)
・検索機能
その他
・お問い合わせ機能(Gmailを使用)
・言語切り替え機能(日本語/ 英語)
2-4. ゲストログイン機能について
様々な実装方法があると思いますので、別途詳細をまとめました。
1. usersテーブルにboolean型の「guest属性」を追加
class AddGuestToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :guest, :boolean, default: false
end
end
2. ゲストページ用のルーティングを追加
post '/guest', to:'users#create_guest'
get '/guest', to:'static_pages#guest'
3. usersコントローラーにcreate_guestアクションを作成
# POST /guest
# 現在のユーザーがゲスト => ゲストページにリダイレクト
# 現在のユーザーがいない => 新たにゲストを作成 (emailのアカウント名/passwordはランダムな英数字)
def create_guest
if current_user && current_user.guest?
redirect_to guest_path
else
user = User.create(name: "Guest User",
email: SecureRandom.alphanumeric(15) + "@guest.com",
password: SecureRandom.alphanumeric(10),
guest: 1)
log_in user
flash[:success] = t('.flash.success')
redirect_to guest_path
end
end
4. static_pagesコントローラーにguestアクションを作成
# GET /guest
# 現在のユーザーが「nilである」または「guestではない」=> ルートにリダイレクト
def guest
redirect_to root_url if !current_user || !current_user.guest?
end
5. ゲストユーザーを定期的に削除
Herokuのschedulerアドオンを利用し、以下のrakeタスクを1日1回、日本時間1時AMに実行してます。
desc "This task is called by the Heroku scheduler add-on"
task :delete_all_guests => :environment do
puts "Updating guests..."
# 1日より前に作成されたゲストユーザーを全て削除
User.where(guest: :true).where("created_at < ?", 1.day.ago).destroy_all
puts "done."
end
参考:http://railscasts.com/episodes/393-guest-user-record?view=asciicast
2-5. 使用技術一覧
バックエンド
・Ruby 2.6.3
・Ruby on Rails 6.1.4
フロントエンド
・Sass
・Vanilla JS
データベース
・MySQL 8.0
インフラ
・Heroku
テスト
・Minitest
2-6. ER図
2-7. 今後やりたいこと
機能面
・スマホ画面でのUI・UXを改善する。
・非同期通信時の処理速度をあげる。
・ソーシャルログイン機能を実装する。
・レスポンシブ対応を細分化する。(現状だとPC/ Mobileの2パターン)
技術面
・RSpecでテストを書き換える。
・開発環境でDockerを導入する。
・インフラをHerokuからAWSに変更する。
・APIモードでシステムを作り変えてみる。
3. アプリ完成までの道のり
3-1. 学習開始(2020年11月〜2021年1月)
Progateとドットインストールを用いて、HTML、CSS、JavaScript、Ruby、SQL、UNIXコマンド、Git、Railsの基礎を学びました。JavaScriptのforEach()
が中々理解できず苦戦したことや、始めてターミナル上でUNIXコマンドを叩いた時、想像していたプログラマー像を彷彿とさせる作業に興奮したことを、覚えています。
3-2. 苦しみつつ継続(2021年2月〜5月)
Railsチュートリアルに突入しましたが、第1章から大きくつまづきました。どうやってもHerokuにデプロイできず、泣きそうになりながらググりまくり、何とか解決しました。今思えば良い経験になったと思います。その後は、難しすぎて離脱→別途学習→復帰を繰り返しながら、少しずつ進め、6月に職業訓練校に入学するまでに、10章まで完了させました。(理解度は6割程度だったと思います。)
3-3. オブジェクト指向への理解が深まる(2021年6月〜8月)
学校では、Java→ HTML/CSS→ JavaScript→ Servlet/JSP→ SQL→ Linux→ Gitの順で授業が進みました。放課後や週末の学習では、Progate、ドットインストールも活用し、一旦Javaに集中しました。
JavaはRubyと違い、様々なことを明示的に指定します。例えばメソッドを作る時、 戻り値はある?引数はある?それぞれ型は何なの? などを明確にします。そんなJavaを使って、授業の中で何度も、クラスやインターフェース、メソッドを作ったおかげで、引数とは?戻り値とは?インスタンス変数とは?コンストラクタとは?アクセッサとは?継承とは?などを身体で理解し、プログラミング全体やオブジェクト指向への理解が深まりました。
Javaの学習がある程度落ち着いてから、Railsチュートリアルを再開し、全14章を完走しました。そしてついに、人生初の自作アプリ「5Keeps」の実装を始めました。
3-4. CRUD処理やデータベースへの理解が深まる(2021年9月)
学校では9月末の1回目の発表会に向けて、制作期間に入りました。授業は午前中のみで、午後は制作の時間です。この期間は、「5Keeps」の開発を、2つの方法で進めました。学校ではServlet/JSP、放課後や週末はRailsです。
Servletとは、JavaでWeb開発をするための、基本的なプログラムです。Servlet単体ではMVCのControllerを担当し、Viewを担当するJSP(Rubyで言うERBのようなもの)と連携して、Webページを動的に生成します。
Java Servlet(ジャバ サーブレット)とは、サーバ上でウェブページなどを動的に生成したりデータ処理を行うために、Javaで作成されたプログラム及びその仕様である。
引用:Wikipedia ( https://ja.wikipedia.org/wiki/Java_Servlet )
JavaServer Pages (JSP) は、HTML内にJavaのコードを埋め込んでおき、Webサーバで動的にWebページを生成してクライアントに返す技術のこと。
引用:Wikipedia ( https://ja.wikipedia.org/wiki/JavaServer_Pages )
Servlet/ JSPはフレームワークではないので、RubyのフレームワークであるRailsやJavaのフレームワークであるSpring Bootと比べると、手動でやらなければならないことが多いです。大変ですがその分学びが多く、特に以下の2点はその後の開発に大きく役立っています。
CRUD処理の流れが身体に染み付く
Servletは、リクエストの種類に応じて、呼び出すメソッドが変わります。GETリクエストでdoGet()
が呼び出され、POSTリクエストでdoPost()
が呼び出されます。Servlet/ JSPで開発を進める中で、リクエストの種類によって処理を使い分ける作業を、何度も繰り返しました。そのおかげで、CRUD処理の流れが身体に染み付きました。典型的な例は以下の通りです。
・ doGet()
:URLパラメータの値を取得/ データベースから値を取得→JSPで表示
・ doPost()
:フォームに入力された値を取得→データベースを更新→doGet()
にリダイレクト
データベースを強く意識
Railsチュートリアル一周目では、ORマッパーである Active Recordを何となく使い、データベースのことをあまり意識できてなかったです。Servletを使った開発では、データベースとの接続を手動でおこない、生のSQLを沢山書き、データを追加するたびに「MySQL Workbench」で確認する作業を繰り返しました。そのおかげで、Railsを使ったアプリ開発においても、データベースを強く意識できるようになりました。
3-5. ググりながら実装(2021年10月)
Servlet/ JSP版「5Keeps」の発表が無事に終わり、学校では最後の大きなトピックとして、Javaのフレームワーク「Spring Boot」を学習しました。Railsと比較しながら学ぶことで、フレームワークとは?O/Rマッパーとは?パッケージ管理とは?などの理解が深まりました。
一方Rails版「5Keeps」は、ユーザー認証等、ベースとなる機能の実装が完了し、グループ・リンク関係機能の実装に突入しました。ここからは、Railsチュートリアルの枠を越えた未知の領域です。最初は不安でしたが、日本語記事はもちろん、時には英語で調べながら、1つ1つ機能を実装していきました。ググりながら実装していく中で、自力で問題を解決していく力が身についたと思います。
大変だったこと【非同期通信】
グループとリンクの作成・表示・編集・削除を全て非同期通信で行うことで、UXの向上を図ってますが、新たに追加した要素にイベントを追加するなど、RailsとJavaScriptの連携に苦労しました。
こだわったこと【OGP情報の取得】
アプリの機能がシンプルな分、デザイン面での寂しさがありました。それを改善するため、RubyのNokogiri gemを利用して、URLからリンク先WebサイトのOGP情報を取得しています。Webスクレイピングは未知の技術でしたが、いくつかの記事を参考にし、始めてOGP画像を取得できた時は、とてもテンションが上がりました。
参考:https://zenn.dev/arao99/articles/40cde7168279f899d0f5
3-6. ついにリリース!(2021年11月5日)
リリース直前まで、iOS特有の問題(ボタンの色や形が変わる等)を解決したり、学校の講師から「何のアプリなのかわかりずらい」と指摘を受けて、トップページに「使い方」を追加したりバタバタしましたが、11/5にTwitter上でリリースを発表することができました。
3-7. 職業訓練校という選択肢(余談)
プログラミングの学習を始めた当初は、会社員として働きながら、出勤前後や週末を使って学習をしていましたが、仕事との両立が難しく、思うように進みませんでした。一旦会社を辞めるべきか悩んでいる時に、職業訓練校のことを知り、応募することにしました。無事合格し、実際に受講してますが、入学して本当によかったと思ってます。理由は以下の通りです。
- 訓練校の期間中は失業手当を受給できるので、勉強に集中できる。
- 講師に質問や相談ができるので、挫折することなく学習を進められる。
- 「学校」という場所があることで、モチベーションを維持しやすい。
独学に限界を感じているが、金銭的にスクールに通うのが厳しいという初学者の方には、職業訓練校という選択肢もありだと思います。
4. さいごに
未経験から1年間プログラミングを学びましたが、正直最初は甘くみていました。プログラミングは難しいです。ひとつ壁を乗り越えたと思ったら、更に巨大な壁が現れます。とはいえ、コツコツ学習を続ける中で、少しずつできることが増え、その分楽しさが増していきました。
「5Keeps」をいったんリリースできましたが、完成ではないです。今後も改善を続けて、どんどん良いサービスにしていきます。
まだまだ学びたいことが沢山あるので、まずはエンジニア就職を成功させ、経験を重ねつつ、今後も技術を磨いていきたいと思います。日々の学びをTwitterで発信してるので、もしよければ覗いてみてください。(https://twitter.com/hayasakadaichi)