[Rails]ツイッターのクローンを作ってみました。

# はじめに

Docker, Ruby, Railsの学習を終えた時点で、実践を通じて理解を深めるためのスクールの課題、ツイッターのクローンです。
機能ごとに、概要、機能の要件、工夫した点、 習ったことについて解説したいと思います！

# サービス環境
- ruby 2.6.8
- Rails 6.1.5
- docker
- mysql
- Slim, SCSS

# できるようになったこと。
- MVCの理解
- Slim,SCSSの書き方
- Devise
- ModelのValidation
- Rails-JSの繋ぎ
- ActiveRecord
- Omniauth
- ポリモーフィック関連付け
- テスト



# 目次
| |機能|
|-------|:----------:|
|1|[**ログインと会員登録(Devise)**]
|2|[**ユーザー詳細ページ作成**]
|3|[**ツイート機能＆ツイートにコメント作成**]
|4|[**画像アップロード (AcriveRecord)**]
|5|[**Git Hub Login (Omniauth)**]
|6|[**いいね機能 (ポリモーフィック)**]
|7|[**フォロー機能＆検索機能**]
|8|[**テスト(RSpec)**]





# 1.  ログインと会員登録(Devise)

``　 概要 　``
ログインと会員登録です。
①会員登録をして、ログインする。
②ログインをしてない状態でもトップ画面を見ることができる。
③パスワード違い等のログインできなかった時にエラーを返す。

**ログイン画面**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/0105d526-e939-8bf9-c242-9df6aba23b5c.png)
**会員登録画面**
- viewはslimを利用して自作しました。エラーはDeviseのエラーを活用しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/934024b8-2d2f-97a7-bd7a-97ec13708421.png)


``　 機能の要件  　``
①Deviseを使用しユーザーを作成。ログイン・ログアウト・サインアップができるようにする。（会員登録時の記入項目はID、パスワード、名前）
②ログイン・サインアップ・トップページはDeviseではなく自作
③ユーザーモデルの作成
④ログイン中はトップページに自分の名前とつぶやきボタンが出る。(ボタンはまだ動作しなくて良いです。)
⑤ログアウトができること
⑥パスワード違い等のログインできなかった時にエラーを返す。


## ログインと会員登録で工夫した点

### ①Deviseの活用方法
Deviseの機能をもってくるけど、veiwは自作しないといけない要件だったので、DeviseのControllerのコードをきちんと読んで挙動を把握してからviewを書くようにしました。
### ②ログイン誘導
ログインをしてなくても、最新のツイートが見えるようにし、
 `23万のユーザーが待っています。Log inをしてください。`という文句をいれて、ログインを誘導しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/55f0f148-9d82-f4fd-c8d0-fb8b6e376090.png)

### ③`autocomplete: 'off'`
ログインと会員登録時に共用パソコンを使う場合、過去の入力履歴が表示されないようにしました。

## ログインと会員登録で習ったこと

### ①Deviseの使い方
Deviseはとても便利で、本課題では投入してない機能等もためしたり、Deivseで提供してくれるviewもためしてみたりすることで、Deviseの使いかたを学ぶことができました。


# 2.  ユーザー詳細ページ作成
``　概要　``
ユーザー詳細ページです。
①トップページの「つぶやく」の上にある自分の名前をクリックするとユーザー詳細ページへ遷移して、自分のプロフィールを編集できる。（名前、自己紹介文、プロフィール画像）
②ユーザー詳細ページの退会ボタンから退会することができる。
③ユーザーが作成したツイート、コメントが見れる。
④いいねボタン押したツイート、コメントが見れる。

- ユーザー詳細ページです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/081b5faa-4849-10df-8ba0-e2b4d91587b6.png)

``　 機能の要件  　``
①トップページの「つぶやく」の上にある自分の名前をクリックするとユーザー詳細ページへ遷
② 自分のプロフィールを編集できる。（名前、自己紹介文、プロフィール画像　※後述）
③ ユーザー詳細ページの退会ボタンから退会することができる。（論理削除）
④ ユーザーが作成したツイート＆コメント表示　※後述
⑤ いいねボタン押したツイート表示　※後述


##  ユーザー詳細ページ作成で工夫した点

### ①他ユーザーの詳細画面では編集できないように制限
自分のプロフィール以外編集できなくするのは当たり前ですが、
機能を具現化する上でユーザーの情報を守ることが大事ということに気づき、情報を守る工夫をしました。

##  ユーザー詳細ページ作成で習ったこと

### ①退会について
論理退会という概念について学ぶことができた。

# 3.  ツイート機能＆  ツイートにコメント作成

``　概要　``
SNSにはお馴染みの2機能です。


**タイムライン**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/78ddf618-dccc-0053-cc2e-a6eb39a855bf.png)
**ツイート詳細ページ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/8508939e-e0ae-4abb-31a4-46f9d5d5520f.png)


``　 機能の要件  　``
- ツイート
①「つぶやく」ボタンクリックで新規ツイート作成ページに遷移
②テキストを入力し投稿することでトップページにツイートが表示される。
③Tweetモデルの作成をし、UserモデルとTweetモデルを関連付け
④ツイートは最大140文字まで
⑤ユーザー詳細ページに作成したツイート表示　

- コメント
①ツイートをクリックでツイート詳細ページに遷移
②ツイート詳細ページでツイートのコメント表示
③ ツイート詳細ページ  の「コメント」をクリックでコメント新規作成に遷移
④コメントを投稿するとコメントページにリダイレクト
⑤コメントモデルの作成し、Userモデル, Tweetモデルとコメントを関連付け
⑥コメントも140文字まで
⑦ユーザー詳細ページに作成したコメント表示　

## ツイート機能＆  ツイートにコメント作成 で工夫した点

### ①コードの再利用
トップページとユーザー詳細ページにツイートとコメントを表示するコードが重複しないようにコードを再利用しました。

## ツイート機能＆  ツイートにコメント作成 で習ったこと

### ①関連付け
関連付けを実践することで、１：多の関連付けの理解を深めることができた。

### ②CRUD
機能要件に削除を追加して具現化することで、CRUDがしっかり理解することができました。

# 4.  画像アップロード [ActiveRecord]

``　概要 　``
ユーザー詳細ページでプロフィール画像のアップロード、編集ができるようにし、
画像を選択すると、アップロード確定前に見出しが表示される。

**ユーザー詳細編集画面**
-　詳細の編集共に、画像アップロードができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/e3a27f64-647e-6164-b0a4-17520de79387.png)
- 画像を選択すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/1be4fbf4-7cb1-43e3-9abd-b360824a84ee.png)
- 編集確定前に画像の見出しが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/67835966-d8f7-98b5-a3b4-0ba27ed7fe03.png)


``　 機能の要件  　``

①ユーザー詳細ページの自分のアイコンをクリックでプロフィール画像をアップロードできる
②画像アップロードにはActiveRecordを使用

## 画像アップロード [ActiveRecord]で工夫した点

### ①編集確定前に見出し表示。
プロフィール画像を登録するとき、見出しが出てなくて、確定ボタンを押して、なんか気に入らなくてまた編集ボタンを押して画像選びを押すというちょっとした手間が面倒だったので、
画像を選択するとどういう風になるかの見出しを表示するようにしました。
Javascriptの学習してからしばらくたったので、必要なコードの分だけを学習しなおして具現化しました。
簡単なコードだったが、結構苦労しましたね、、


## 画像アップロード[ActiveRecord]で習ったこと

### ①ActiveRecordの使い方
ActiveRecordを使って、画像データの保存、画像のサイズ編集等を学ぶことができました。

### ②AJAX
AJAXを利用し画像の見出しを動的に表現することができました。Onchang関数は本当に便利だなと思いました。

# 5.  Git Hub Login [Omniauth]

``　概要 　``
Git Hubのアカウントでログインする機能です。

**Sign in with GitHub**
- Sing in with GitHubボタンを押すと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/4494c643-8f48-9903-b802-56ab6fa21c4e.png)
- ログイン成功時に`Successfully authenticated from Github account.`というnoticeが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/8c7de92d-e8f8-5d27-367a-46a5d97642dd.png)




``　 機能の要件  　``

①Git Hubアカウントでログインできる
②DeviseのモジュールOmniauthableを使用

## Git Hub Login [Omniauth]で習ったこと

### ①Omniauthの使い方
実際に具現化してみる前は、難しそうだと思ったんですが、コード自体は簡単でしたので、わかりやすかったです。UXをかなり向上してくれるいい機能なので、習えてよかったと思います。

### ②Dockerfileを書く時の注意点
コード自体は簡単だったといいましたが、実はエラーで機能の具現化に20h以上かかりました。原因がコードにあると思ってコードの確認や、エラーの検索をずっとやってましたが、、
原因の判明がなかなかできなかったです。それでも粘り強くエラーについて調べたら、Dockerfileの書き方の問題で`gemfileがdocker-compose up`をコマンドを実行したときリセットされることがわかりましたので、やっと解決できました。Dockerを使うときは、Dockerが原因でエラーになることも頭に入れておくのが大事！といういい勉強になりました。

# 6.  いいね機能 [ポリモーフィック]
``　概要　``
SNSのお馴染みのいいね機能です。
**いいね機能**
- ハートボタンを押すとハートが赤く染めていいねを押したことを表します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/2a8ba17f-27ce-a467-9d34-a63d94dc1077.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/bddba011-7053-5f35-07cd-5ac13c175fc2.png)


``　 機能の要件  　``

①Tweetのハートマーククリックで「いいね」ができる
②ユーザー詳細ページで「いいね」押したツイート、コメント表示
③Likeモデルはユーザーと関連付け
④ポリモーフィックでツイート、コメントと関連
⑤ユーザー詳細ページの「いいねした投稿一覧」でポリモーフィックを活用

##  いいね機能 [ポリモーフィック]で工夫した点

### ①コードの再利用
トップページ、ユーザー詳細ページ、ツイート詳細ページのツイートとコメントそれぞれいいね機能がついているので、コードが重複しないようにコードを再利用しました。

### ②いいねした投稿一覧のUX
ユーザー詳細ページのいいねした投稿一覧でもいいねボタンを外せるようにしました。これで、いいね一覧の管理がしやすくなり、UX向上につながると思いました。そして、いいねボタンを押したコメントの場合はコメントを書いたツイートまで見れるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/9f0bb988-e5c3-2d3a-4a60-e8a54332aada.png)

## いいね機能 [ポリモーフィック]  で習ったこと

### ①ポリモーフィック
ポリモーフィックは普通の関連付けよりちょっとわかりづらいどころもありましたが、1回理解してしまうとコードの量も減って非常に便利で使うことができてよかったと思いました。


# 7. フォロー機能＆検索機能

``　概要 　``
SNSに必要不可欠なフォロー機能です。
フォローしたユーザーのツイートが投稿時間の降順で表示されます。
ツイートとコメントの内容を検索することもできます。

**ユーザー詳細画面でフォロー**
- フォローすると、時間順にタイムラインにフォローしたユーザーのツイートが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/31d2fc59-bc43-0c49-5aff-508bcfe0e6c9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/2b78eaac-ddb3-9bf2-b742-454bc5e3e873.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/1ee0669a-e1cf-6a3b-7344-eec60aebd896.png)
**検索機能**
- 検索すると、検索結果として表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/ccc38f51-1cfe-4b80-4bb2-67c19533845c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/bb5dc5b4-2f47-92a2-f8a2-d9b309056dea.png)



``　 機能の要件  　``
①ユーザーをフォロー・フォロー解除できる  
② トップページの検索欄からツイート、コメントを検索できる
③フォローしたユーザーのツイートがトップページに表示される（タイムライン）
④タイムラインはTweetの投稿時間について降順で表示

## フォロー機能で工夫した点

### ①新規ユーザーのUX
フォローがない新規ユーザーのために新規のツイートを表示するようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/a19357df-9f79-884f-6648-72d07c77c1f8.png)



## フォロー機能で習ったこと

### ①関連付け
ユーザー間の関連付けを具現化することがちょっと難しかったですが、このサービスを作る過程で1：1、1：多関連付け、ポリモーフィックなどいろいろ使ってみることができて、関連付けをしかり学べたと思います。


# 8. テスト(RSpec)

``　 機能の要件  　``
①主要な機能にテストを追加
②モデルのテスト(単体テスト)とシステムテスト(e2e)
③正常系と以上系
④RSpec

## テストで工夫した点

### ①細かいテスト
ボタン一つ一つ細かくテストしようと心掛けました。

## テストで習ったこと

### ①テストのやりかた
初めてのテストでテストを実行する自体にエラーがいろいろ出て解決しながらテストに慣れることができました。テストを書いておくと、コード修正時にすごく楽になるのも後々気づきましたので、テストの重要性がわかりました。


# さいごに
長くなりましたが、以上です。
最後まで読んでいただき、誠にありがとうございます！

機能毎にスクールの先生にPRをして指摘事項を修正することで、Railsをしっかり学ぶことができたと思います。
完成まで230h時間かりました。毎日2-3時間だったので、3ヶ月ぐらいですね。
実務だと知らないことがあれば、何時間トライしてみてもできなかったら先輩に聞くのが正しいと思いますが、
今回の課題はあくまで学習なので、できるだけエラーを一人で解決するため頑張りました。
そのおかげで、どんなエラーでも解決できる！と自信がつきました。

そして、Rails中心の課題でしたが、一つのWebサービスを作るためには、フロント側もdocker知識も
きちんと学習しないといけないこともわかりまして、次のフロント学習にもやる気が出てきまして、本当にいい経験だったと思います。
この経験を活かして、いろんなサービスを作っていきたいと思います。

次回の記事もよろしくお願いします。