作字クリエイターの方を支援するSNSを作ってみたい【個人開発/RoR/Docker/AWS/DaisyUI】

# HelloWorld!
はじめまして！突然ですが皆様**作字クリエイター**ってご存知でしょうか？恐らく多くの方は首を横に振られたと思います。試しに作字≒タイポグラフィでググってみると、

>タイポグラフィは、活字を用い、それを適切に配列することで、印刷物における文字の体裁を整える技芸である。(Wikipedia)

とのこと。要するに文字を使ったデザインに関わる創作をする方々のことですね。今回はそんな作字クリエイターの方を支援するようなプラットフォームを作りたいと考え、独学でプログラミングを学びながらこれまで作ってきたWebアプリをご紹介できればと思います。

:::note info
なお本アプリはまだまだ実装したい機能があり、これからも開発を続けていこうと考えているため、表題の語尾は"~みたい"としました。
:::

【アプリ名】
__Sakujiru__
【URL】
▷http://sakujiru.com/
【レポジトリ】
▷https://github.com/dlanx0607/sakujiru-app

### 製作者の人となり 
- 牛タン:poultry_leg:が美味しい県で物理を学ぶ大学生
- CS専攻でも情報系でもないがIT業界を志望
- 転職者向けプログラミングスクールのインターンシップで基礎を習得
- 知り合いに超かっちょええ作字クリエイターがいる


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [アプリの概要](#アプリの概要)
1. [開発において意識した事](#開発において意識した事)
1. [参加していたインターンシップについて](#参加していたインターンシップについて)
1. [最後に](#最後に)

# アプリについて
### アプリの概要
クリエイターの方が自身の作品を投稿し、それを見た顧客が実際に案件を依頼したいクリエイターを見つけて、直接交渉ができるようなプラットフォームです。

### 製作に至った動機
僕には知り合いに作字クリエイターの方がおり、よく自身のSNSをたまたま見て下さった方から仕事の依頼を頂くという話を聞いていました。その際に完成作品のイメージのすり合わせや、価格交渉で苦労しているといった悩みがあったため、顧客が自身のイメージと近い作品から仕事を依頼するクリエイターを探せるような、**作字とのマッチングサイト**を作ってその悩みを解決したいと考えました。


### アプリの特徴 
__(1)作品投稿機能__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/330ee1fa-b3cf-731f-47f4-958ca3c43c7b.png)
作字クリエイターが自身の作品を紹介するページです。

__(2)マッチング（いいね機能）__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/a08e37f5-4e68-1407-78a4-caa03cb52cbf.png)
某マッチングアプリの如く、１枚１枚作品に「いいね」を押していき、次々と作品を評価することができるページです。

__(3)いいねした作字一覧__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/4bc664d9-838e-8579-98e5-3e6bb25f64f4.png)
マッチングページでいいねした作品を一覧することができるページです。

__(4)DM機能__
![スクリーンショット 2022-04-06 9.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/62889529-c0cf-66d1-ef2d-ec97cab454a6.png)
ActionCableを用いて、リアルタイム同期チャットを作成致しました。

__(5)クレジットカード登録機能(Pay.jp)__ 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/0261fde0-2d22-71ab-2101-ff6470f50eed.png)
決済APIであるPay.jpを用いて、クレジットカードをトークン化して登録する機能を実装しました。今後は実際の支払い機能を実装できたらと考えています。

### 主な機能(使用したGem)
- ユーザー登録・ログイン・編集・退会(devise)
- 画像投稿機能（carrierwave)
- ページネーション(kaminari)
- 初期アバター設定(initials)
- いいね・コメント機能
- 検索機能(ransack)
- マッチング機能
- DM機能
- クレジットカード登録機能(Pay.jp)

### データベース設計
![スクリーンショット 2022-04-06 1.15.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/6e807452-0a51-49ea-3d5e-96b7d3b675f5.png)
| テーブル名 | 役割 | 
|:-----------|:------------:|
| User       | ユーザー関連の諸々         |
| Post     | 投稿関連の諸々       |
| Card       | トークン化されたクレジットカードを保存する        |
| Art         | 投稿に紐づいた画像を保存する           |
| Reaction       |　マッチングによりいいねされた投稿を保存する       |
| Comment    | 投稿に対するコメントの作成・保存      | 
| ChatMessage   | ユーザー間でのチャットメッセージの保存  |
| ChatRoomUser |  チャットルームに呼び込むユーザーの保存  |
| ChatRoom | 中間テーブル  |

### 使用技術と選定理由
__(1)フロントエンド__
- HTML,CSS,JS(jQuery)
- Tailwindcss(DaisyUI)
→DaisyUIはデザイン性が非常に高く、また１から実装するには少し煩わしいような部品がはじめからコンポーネントとして用意されていて、使い勝手が非常に良いと感じました。また予めカラーセットが数十種類用意されており、htmlタグに１行テーマを記載するだけで気軽に見映を変えられるのに感動しました。飽き性の方にはオススメです。
```ruby:application.html.erb
<html data-theme="aqua">
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/6b832980-11c0-709f-dc07-13f788da3497.png)
```ruby:application.html.erb
<html data-theme="valentine">
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2415490/b8e3d628-041d-7ea6-0742-fa817759652d.png)

__(2)バックエンド__
- Ruby 2.7.5
- Rails 6.0.4.6
→開発当初はRails7で製作していたのですが、Turboが悪さすることが多かったので途中で6に切り替えました。7はtailwindcssなどのCSSフレームワークの導入が簡単で、scaffoldを叩くと勝手にスタイルをあててくれるので優秀でした。
- PostgreSQL 14.2

__(3)インフラ__
【開発環境】
- Docker 20.10.11 /Docker-compose 1.29.2
→コンテナとしてRails用のwebとデータベース用のdbの２つを用意しました。

【本番環境】
- AWS(VPC,EC2,RDS,S3,Route53)
→途中まではherokuにデプロイをとってましたが、その後にEC2に変更しました。ストレージにはS3を用いており、投稿された画像を保存しています。

__(4)コード管理__
- Git,GitHub,GitLab

__(5)エディタ__

- VSCode

__(6)進捗・タスク管理__

- Slack,Trello,Gather
→Trelloは進捗が可視化され、作業がどこまで進んでいるかひと目で分かるので進捗管理に重宝しました。Gatherはメンターや他のメンバーとの交流で使用していましたが、オンラインゲームのような感覚で会話できるので面白かったです。小学生の時に流行していたアメーバピグを思い出して感慨深くなりました…（遠い目)。

# 開発において意識した事
### (1)工夫した点
__マッチング機能の実装__
作品を一つのカード中に納め、Tinderのように次々と評価するような機能を実装したいと考えました。カードの重ね合わせには,tailwindcssのstackプロパティを用いて表現しました。
```ruby:swipe.html.erb 
<div class="swipe--cards stack mt-5 mb-5">
```

__擬似的チーム開発__
各機能ごとにブランチを切って実装→コミットしてプルリクを出してマージ
というような流れを繰り返すことで、個人開発ながらチームでの開発を意識して作業を行いました。

__タイムマネジメント__
製作期間が卒業研究と丸被りしていたので、作業時間を確保するのが中々大変でした。そのため研究の合間の時間や休日の僅かな休息時間を作業に充てて、進捗予定スケジュールの通り進めるように調整していました。また大学ではプロキシに阻まれてターミナルからgitにアクセス出来ないため、作業場所も自宅やカフェ、フードコートなど適宜変えていました。

### (2)苦労した点
__環境構築__
ぶっちぎり一番大変だったのがインフラの整備でした。開発環境においてはDockerやDocker-composeの概念の理解、Dockerfileの書き方やデータベースの接続で何度も苦しめられました。適当に拾ってきた野良のコンテナファイルを使っても大体どこかでエラーを吐くので、最初から公式のレファレンスを読み込むべきでした。また本番環境ではAWSの各サービス間での連携や環境変数をどこに書くか、セキュリティグループのエラー等に悩みました。

__学習方法について__
世の中に混在している情報の中から何を抜き出して、どのように学習を進めていくかで非常に悩みました。その中で実装経験が無い機能をどうアプリに取り込んでいくか、どのようなロジックで動いているかを理解するためにはどうしたら良いかを常に考えながら最善の一手を探るのが重要だと感じました。Udemyなどで網羅的に学習した後に、公式のレファレンスをよく読み込んで仕組みを理解する必要がありました。

### (3)今後の課題
この後の展望としては
- 作品カテゴリの実装
- snsを用いたログイン機能
- フォロー機能
- ゲストログイン
- スキルセット表示機能
- 理解が足りていない実装や各種インフラの勉強
- 各種UIの充実

など、挙げれば本当にキリがありませんが、一旦開発からは距離を置いてインターネットの基礎知識習得に注力しようと思います。その後Ver2をリリースしたらまたQiitaに記事を書きたいと思います:fire:

# 参加していたインターンシップについて
今回作成したWebアプリは、某ヘルステックベンチャー企業のITエンジニアインターンシップの一環で制作に取り組みました。お世話になったメンターの方や同時期に参加した学生の方々、特にチームメンバーにはこの場を借りて感謝致します。ありがとうございました。ここでインターンシップの中での僕の役割や内容を軽くご紹介できればと思います。

### (1)チームリーダーとしての役割
主目的は個人開発でしたが、同時期に参加した学生同士でチームを組み、お互いを鼓舞することでモチベーションを維持していました。その際に僕は１つのチームのリーダーとなり、主に以下の仕事・役割を担っていました。
1. 隔週土曜日の早朝にZoomでの進捗報告会の主催
2. Gatherでのモクモク会
3. 日常的なSlackでの作業管理及び進捗報告、情報共有
4. 開発でフロントランナーを走る

結果としてメンバー同士でのモチベーションアップに繋がり、無事に最終報告会まで走り切ることができました。チームでの活動は独学で感じていた孤独感を払拭することができ、大変有意義でした。

### (2)口頭での発表
インターンシップの中間及び最終報告時において、全社向けに企画案/成果物紹介プレゼンを行いました。現役のエンジニアの方のみならず、会社代表や役員の方々といった普段お会いする機会が少ない方々にもフィードバッグを頂きました。

【__開発初期段階の企画案スライド__】
<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vTGeX2udFZBAlZCzUVQb5iRjHXJ6Yt-TJULPP5X0PDxD30sedt_c9a62el85pSBLypQpsA0H30BhEZx/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="749" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

【__最終発表時のスライド__】
<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vREyICPGxwcjOPuJq2MO7ThfT_3o6jLbNKpdwA7OjPoh6Y9NdbdKTU1wzu6Bq9BEg/embed?start=false&loop=false&delayms=3000" frameborder="0" width="2560" height="1469" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

# 最後に
アプリ中で使用させて頂いた作品を提供&テストユーザーをして下さった
[8×8さん](https://www.instagram.com/happa__64/)
に感謝申し上げます。ありがとうございました。