Ruby on RailsとReactでBlogアプリを作りました。

## <div id="top">使用技術一覧</div>

<!-- シールド一覧 -->
<p style="display: inline">
  <!-- フロントエンドのフレームワーク一覧 -->
  <img src="https://img.shields.io/badge/-Node.js-000000.svg?logo=node.js&style=for-the-badge">
  <img src="https://img.shields.io/badge/-React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB">
  <!-- バックエンドのフレームワーク一覧 -->
 <img src="https://img.shields.io/badge/-Rails-CC0000.svg?logo=rails&style=for-the-badge">

  <!-- バックエンドの言語一覧 -->
<img src="https://img.shields.io/badge/-Ruby-CC342D.svg?logo=ruby&style=for-the-badge">
  <!-- ミドルウェア一覧 -->
<img src="https://img.shields.io/badge/-MySQL-4479A1.svg?logo=mysql&style=for-the-badge&logoColor=white">
<img src="https://img.shields.io/badge/-Bootstrap-563D7C.svg?logo=bootstrap&style=for-the-badge">

  <!-- インフラ一覧 -->
  <img src="https://img.shields.io/badge/-Docker-1488C6.svg?logo=docker&style=for-the-badge">
<img src="https://img.shields.io/badge/-Heroku-430098.svg?logo=heroku&style=for-the-badge">
  <img src="https://img.shields.io/badge/-Amazon%20aws-232F3E.svg?logo=amazon-aws&style=for-the-badge">
</p>

## 目次

1. [アプリ名](#Isostagram)
2. [環境](#環境)
3. [ER図](#ER図)
4. [使用技術詳細](#使用技術詳細)
5. [アプリ機能](#アプリ機能)
6. [実装について](#実装について)


<br />

## Isostagram


[![Image from Gyazo](https://i.gyazo.com/73b0c6a1d0c8131b9fb3a075ba122083.png)](https://gyazo.com/73b0c6a1d0c8131b9fb3a075ba122083)

 **Github** : https://github.com/morishitakouki/Isostagram/tree/main
**url** : https://rails-react-frontend-blog-e49b147a0c56.herokuapp.com/

## アプリの概要
バックエンドにrailsとフロントエンドにreactを使ったblogアプリを作りました。


## 環境

<!-- 言語、フレームワーク、ミドルウェア、インフラの一覧とバージョンを記載 -->

| 言語・フレームワーク  | バージョン |
| --------------------- | ---------- |
| Ruby                  | 3.3.0    　|
| Ruby on Rails         |  7.0.8.1   |
| MySQL                 | 8.0        |
| Node.js               | 20.11.1   　|
| React                 | 18.2.0     |









## ER図

[![Image from Gyazo](https://i.gyazo.com/0691c96afefeba035575610fbe239859.png)](https://gyazo.com/0691c96afefeba035575610fbe239859)

<p align="right">(<a href="#Isostagram">トップへ</a>)</p>

## 使用技術詳細

### Backend

- ``devise / devise_token_auth``を使用したトークン認証機能
- ``carrierwave``を用い``Amazon S3``に画像を保存する投稿機能

### Frontend

- **コード解析**: ESLint
- **CSSフレームワーク**: react-bootstrap 
- **主要パッケージ**: Axios / react-router-dom / @mui/material / styled-components / react-hook-form /  react-bootstrap, bootstrap 

### Infrastructure, Development Environment

- **開発プラットフォーム** : Docker 
- **インフラ** :  AWS( S3) / Heroku *デプロイ
<br />


## アプリ機能


#### トップページ / ログイン

railsAPIから返されたトークン認証情報をローカルストレージに保存しています。
React hooksのuseContextを使いどのページでもログインしてるか否かを判別しログインしていなければ新規登録とログイン画面以外にアクセスできないようにしています。

<a href="https://gyazo.com/7dce9e2267ec7c32065eb5440aebcd09"><img src="https://i.gyazo.com/7dce9e2267ec7c32065eb5440aebcd09.gif" alt="Image from Gyazo" width="1000"/></a>

<a href="https://gyazo.com/8f4671d44f1944bf3e28232081034e0d"><img src="https://i.gyazo.com/8f4671d44f1944bf3e28232081034e0d.gif" alt="Image from Gyazo" width="1000"/></a>
<br />

### 新規登録
react-hook-formを使いバリデーションを実装しました。

<a href="https://gyazo.com/a3048fe6796962387460213ce594abb1"><img src="https://i.gyazo.com/a3048fe6796962387460213ce594abb1.gif" alt="Image from Gyazo" width="1000"/></a>
<br />

### ブログ投稿

<a href="https://gyazo.com/792a19d68cf8460265fa7aad3edee6b5"><img src="https://i.gyazo.com/792a19d68cf8460265fa7aad3edee6b5.gif" alt="Image from Gyazo" width="1000"/></a>

<br />

### ブックマーク機能

<a href="https://gyazo.com/792a19d68cf8460265fa7aad3edee6b5"><img src="https://i.gyazo.com/792a19d68cf8460265fa7aad3edee6b5.gif" alt="Image from Gyazo" width="1000"/></a>

### 編集機能

<a href="https://gyazo.com/f365e520ab6c1f8166ebf8e6b4a972e0"><img src="https://i.gyazo.com/f365e520ab6c1f8166ebf8e6b4a972e0.gif" alt="Image from Gyazo" width="1000"/></a>
<br /> 

### 削除機能

<a href="https://gyazo.com/7baa34d4d51b440bf3c8c2f7f0e1e3cc"><img src="https://i.gyazo.com/7baa34d4d51b440bf3c8c2f7f0e1e3cc.gif" alt="Image from Gyazo" width="1000"/></a>
<br /> 

### ログアウト

<a href="https://gyazo.com/11bfce8c34ff425ee8c2497c3153da62"><img src="https://i.gyazo.com/11bfce8c34ff425ee8c2497c3153da62.gif" alt="Image from Gyazo" width="1000"/></a>
<br /> 



## 実装について

### 1. 実装手順

2月の中旬くらいから始めました。なにを作ろうかとは特に決めてなく、いきなり実装から始めました。

1. Dockerで開発環境構築
2. Backend、Frontendの実装(Ruby on Rails, React)
  2.0 RailsとReactの紐付け(CORS, axios)
  2.1 認証機能の実装(devise_token_auth, React-hook-form)
  2.2 投稿機能の実装
  2.3 画像投稿機能の実装(CarrierWave)
  2.4 ブックマーク機能の実装
  2.5 削除、編集機能の実装
3. 本番環境に適応(Heroku) 

### 2. 苦労したポイント

まずログイン機能にはとても苦労しましたね。。

Railsだけでアプリを作っていた時はdeviseを使って現場Rails通りにやれば実装できましたが、ReactとAPI通信をする場合、どうすれば良いのかわかりませんでした。
調べた結果、devise_token_authというgemを使うとFrontから送られてきた認証情報をRailsのAPIモードで受け取ることができるらしいのでそれで実装してみることに。

大きなエラーや小さなエラーまで様々なエラーがでましたが特に苦戦したのはユーザー情報の取得、保持です。
まずバックエンドから送られてきたユーザー情報を取得することができませんでした。

原因はローカルストレージにaccess_tokenしか保存してなかったのが原因でした。つまりバックエンドに送る情報もaccess_tokenのみ。これだけだとユーザーが識別できません。clientとuidも送ることで解決しました。
```Javascript
const response = await axios.get(
       `${process.env.REACT_APP_API_URL}/auth/sessions`,
      {
        headers: {
          'Content-Type': 'application/json', // access_token,client,uidを送る
          'access-token': accessToken,
           client: client,
           uid: uid,
        },
      }
    );
    
```

そして今度はログインしてる時とログインしてない時で状態を分けるためにdeviseお馴染みのヘルパーメソッド```current_user```を使おうとしましたがなぜか機能しない。なぜだ？
原因はcurrent_userを使ってるcontrollerが```api/v1```配下にあるので```current_api_v1_user```にしないとダメらしい。そんなん知らんがな。。。
下記の記事がなかったら解決できていませんでした。ありがとうございます。

https://qiita.com/WisheeBell/items/0ac5ac41648b2b9c0627

ただ```current_api_v1_user```にしてそのままコントローラーに書いても機能しませんでした。
```RUby
# posts_controller.rb

 def index
  user = current_api_v1_user
  posts = user.posts      #なぜかuserがnilになる
  render json: posts
 end
```

原因はindexアクションにユーザー情報を送ってないことが原因でした。Rails側で認証情報を取得することで初めてヘルパーメソッドが利用できることを知りました。
ちなみにこれを解決するのに1週間くらいかかりました。

```Javascript
// Index.jsx

useEffect(() => {
  fetchPosts()    // fetchPostsでRailsのindexアクションにaccess_token,client,uidを送信して特定のユーザーのpostデータを取得
    .then((data) => setPosts(data))
    .catch((error) => console.error("投稿の取得エラー:", error));
}, []);
```

<br />

そして最後に苦労したのは本番環境への適用です。
デプロイ作業だけでおよそ2週間くらいかかりました。これが原因で就活が遅れてしまいました..(←もっと早くから作っとけ)

まずデプロイするためのレンタルサーバーは[Heroku](https://jp.heroku.com/)を利用しました。
AWSにしようかと最初は思いましたがなんか難しいらしいのでHerokuでデプロイすることにしました。

Backend側は簡単にデプロイできましたがFrontend側のデプロイでめちゃくちゃ苦労しました。
Frontend側はモダンなReactのビルドツールである[Vite](https://ja.vitejs.dev/)を利用しましたがデプロイ知識がない自分にとってこれが裏目になりました。

ビルドまではできるんですけどいざHerokuでアプリを開いてみると原因不明のエラーコード**H-10**(アプリケーションクラッシュ)が発生しました。
Herokuのlogをみても全く分からず、試行錯誤を重ねて悩み続けた結果、結局Frontendだけ```create-react-app```で**新たに作り直しました**。 

このように色々エラーに悩まされましたがそれが自分の成長につながったので**ポートフォリオを作ってよかった**と思いました！

### 3. 今後導入したい技術

**⚫︎ RSpec**

RSpecを利用してテストを書きエラーの早期発見を目指したいです。


**⚫︎ CI/CD**

​​ビルドやテスト、リリース、デプロイなどの各作業を自動化し、リリースできる状態にまで効率的に進められるようにしたいです。

**⚫︎ Figma**

AWS Amplify Studioを利用してFigmaで作成したデザインをReactアプリに連携しUIデザインの向上を目指したいです。