Railsでポートフォリオ制作③【実装：GitHubにあげる〜ユーザー機能実装】

ポートフォリオの環境構築が完了したので、実装に入ります。

## これまで
https://qiita.com/mahariiku/items/1f062eed36dab8ace782

https://qiita.com/mahariiku/items/31a741d478004598b995

## 実装手順
- GitHubに上げる
- issueを作っていく
- gemのインストールと各種設定
- GitHub Actionsを導入
- Dockerを導入
- タイムゾーンの設定
- devise(ユーザー認証gem）の導入
- 国際化（localize）
- UIのテンプレートを導入
- ユーザー関連機能のviewとspec実装

## GitHubに上げる
- GitHubのマイページで、リポジトリの新規作成
- ローカルのrailsプロジェクトのディレクトリで`add`→`commit`→`remote add`→`push`
- GitHubのリポジトリページを更新してローカルの内容がプッシュされているのを確認！
![スクリーンショット 2022-11-12 7.10.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669070/8efd024f-d3ec-724d-042c-a988bf55d34d.png)

## issueを作っていく
- GitHubのマイページの、`Projects`→`New Project`→`Board`テンプレートを選択
- カラムを足したりして、好みのボードにカスタマイズ
- `Add item`で思いつくままにアイデアやタスクを追加していく
- 文字部分をクリックして、`Convert to issue`でポートフォリオのリポジトリを選択し、issue化
- issue作成〜ローカルブランチでの作業は[こちら](https://qiita.com/tkmd35/items/9612c03dc60b1c516969)を参考に

私は、思いついたこと（`Doodles`）、やること（`Todo`）、作業中（`In Progress`）、今週の完了タスク（`Done(**.**-**.**)`）、これまでの完了タスク（`Done`）の５つのカラムに整理しました。![スクリーンショット 2022-11-12 8.42.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2669070/faa4ffbf-91de-0e54-028e-2fe60a2d1f73.png)


## gemのインストール
- Gemfileにgem追加中にわいた疑問：`require: false`って何？
  - A. アプリケーション自体には必要ない（=requireしなくていい）けど、開発する時に使いたいgem（rspec, erblintなど）をインストールしておく時に設定するもの（[参照](https://blog.saeloun.com/2022/08/16/understanding_gemfile_and_gemfile_lock.html#what-does-require-false-mean )） 
- gemのインストールコマンド：`bundle install`
- rubocopの導入
    - [導入方法の参考](https://nishinatoshiharu.com/insatall-rubocop/)
    - [カスタマイズの参考](https://nishinatoshiharu.com/customize-rubocop/)
    - [.rubocop.yml 見本](https://github.com/rubocop/rubocop/blob/master/.rubocop.yml)
    - `bundle exec rubocop -a`で自動修正
- erblintの導入
    - [導入方法の参考](https://zenn.dev/junara/articles/efa04ce1ab02c9)
    - [GitHub](https://github.com/Shopify/erb-lint)
    - `bundle exec erblint -a .`で自動修正
- rspecの導入
    - [導入方法の参考](https://zenn.dev/yukihaga/articles/816758ff6f0bdf)
    - [Filter_run_when_matchingについて](https://relishapp.com/rspec/rspec-core/v/3-6/docs/filtering/filter-run-when-matching#examples-can-be-focused-with-%60fit%60) 
    - `bundle exec rspec`で自動テスト  
- annotateの導入
    - [導入方法の参考](https://relishapp.com/rspec/rspec-core/v/3-6/docs/filtering/filter-run-when-matching#examples-can-be-focused-with-%60fit%60) 
    - `bundle exec annotate --routes`でルーティング情報も書き出してくれる

## GitHub Actionsを導入
GitHub Actionsでrubocop, erblint, rspecを実行するような設定ファイルを作成。

https://qiita.com/mahariiku/items/0e83c959b33a4ac9bc2e

## Dockerを導入

https://qiita.com/mahariiku/items/18dc05dbf204fc16fad7

https://qiita.com/mahariiku/items/a12cf84c08502284de61

https://qiita.com/mahariiku/items/05ba48f6f6c640b5b69a

## タイムゾーンの設定
タイムゾーンとともに日時を扱うには、ActiveSupport::TimeWithZoneクラスを使う。
デフォルトでタイムゾーン（ActiveSupport::TimeZoneオブジェクト, `Time.zone`）はUTC（協定世界時）に設定されている。
`created_at`や`Time.zone.now`などはActiveSupport::TimeWithZoneオブジェクトで、タイムゾーンに沿った時刻表現となっている。
`created_at`などの日時オブジェクトの設定方法は以下の２つ。
- 日時データをどのタイムゾーンの表現でDBに保存し、読み出し時にどのタイムゾーンの日時データとして解釈するか
    - DBに実際に入る時刻表現が変わる
    - デフォルトの`:utc`のままにすることが多い。（運用メンテナンスを考慮）
- DBから取り出した日時データやユーザー入力由来などの日時データを、アプリケーション内でどのタイムゾーンのTimeWithZoneオブジェクトとして生成するか
    - タイムゾーンの値の制御の仕方は２つ
        - アプリケーション起動時のデフォルト値を設定　 __←今回はこちら__
            - 設定場所：config/application.rbで`config.time_zone`
        - アプリケーションの中で動的にタイムゾーンを変更
            - 設定場所：フィルタなどでTime.zoneを値を切り替えたり、`in_time_zone`メソッドを使ったり

## devise(ユーザー認証gem）の導入
下記のサイトを参考に、最低限のユーザー認証（sign in, log in, log out）のMVCとルーティングを設定した。
- [devise GitHub page](https://github.com/heartcombo/devise)
- [【Rails】deviseを導入してみる](https://qiita.com/Hal_mai/items/350c400e8763ce0487a3)
- [devise導入からユーザーのプロフィール画面を作成するまで](https://qiita.com/ryokky59/items/71b5a853989721b89c6e)

## 国際化
　エラーメッセージなどを日本語で表示
```bash
# 翻訳されたファイルをダウンロード
$ wget https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -P config/locales/`
```
```rb
# デフォルトで日本語のコンテンツを使うようにアプリケーションの設定を変更
Rails.application.config.i18n.default_locale = :ja 
```

## UIのテンプレートを導入
- アセットパイプラインについて
    - アセットパイプライン： JS, CSS, 画像などのアセットを効率的に扱うための仕組み。高級言語のコンパイル、アセットの連結＆最小化（develep環境ではスキップ）、ダイジェストの付与を行う。
    - [アセットパイプライン - Railsガイド](https://railsguides.jp/asset_pipeline.html)
    - 今回は、Sprockets + Import mapsを利用
    - [Rails 7.0 で標準になった importmap-rails とは何なのか？](https://zenn.dev/takeyuweb/articles/996adfac0d58fb)

- UIテンプレート導入手順
    - テンプレートからscss, jsファイルをコピーし適切なディレクトリに置き、それらのファイルを参照できるようマニフェストファイルに追記していく
    - スタイルシート（css, scss）の導入
        - `app/assets/stylesheets`内に、テンプレートのscssファイルをコピー
        - `app/assets/stylesheets/applicatioin.scss`に全てのscssファイルを参照するよう記述

    - javascriptの導入
        - `app/javascript`内に、テンプレートのjsファイルをコピー
        - `config/importmap.rb`に、importするディレクトリ・ファイルをリストアップ
        - `app/javascript/application.js`内にjsファイルを参照するよう記述
        - [Rails 7でJavaScriptファイルを読み込みたい](https://zenn.dev/iloveomelette/scraps/4e033878f84b56)
        - [Rails 7: importmap-rails gem README（翻訳）](https://techracho.bpsinc.jp/hachi8833/2022_06_29/112183)

## ユーザー関連機能のviewとspec実装
- スペックを書く
    - FactoryBot + Fakerで効率化
    - [【Ruby on Rails】FactoryBotとFakerについてまとめ](https://qiita.com/mumucochimu/items/10432fd5173e63ebd418)
    - [Faker GitHub](https://github.com/faker-ruby/faker)
- サインアップ機能とviewとスペック
    - `views/users/registrations/new.html.erb`
    - ログイン後、"ログインしました"というフラッシュメッセージを表示
- ログイン（＝サインイン）画面スペック
    - `views/users/sessions/new.html.erb`
- ログアウト画面とスペック
    - "ログアウトしました"というフラッシュメッセージを表示（予定。当面はデフォルトのフラッシュメッセージを表示）
- フラッシュメッセージの表示
    - https://techtechmedia.com/flash-messages-rails/
- :exclamation: 重要ポイント：turboはステータスコード303でないとredirectができない。deviseはデフォルトでは303を返さないため、該当のメソッドをオーバーライドする必要がある。他にもturboに対応させるためにカスタマイズが必要。（[参考](https://qiita.com/mitsuki_march/items/771930c8ba89629cd72b)）