学び直しPart1 環境構築、ログイン機能

1日目は初歩の初歩から、

- 環境構築
- ログイン機能

上2つをやっていきます。もう何度もやりましたが、
「できるけど理解はしていない」状態なのでやり直します！

今日の教科書
[神戸プログラミングアカデミーrailsチュートリアル](https://www.prog-ac.com/archives/1230)

↑のリンクを参考にやっていきます。

#環境構築

この章の学習ページ
[Ruby on Rails ハンズオン勉強会①](https://www.prog-ac.com/archives/1230)

##メモ

特に注意することはなかった。

##気になったポイント

###bundlerとは？

学習ページ
[【Rails】結局bundlerって何？bundlerの仕組みを図解形式で徹底解説](https://pikawaka.com/rails/bundler)

gemのバージョンやgemの依存関係を管理してくれるgem…らしい。
バージョン確認コマンド

```
bundler -v
```
###GemfileとGemfile.lockの違い
[【Rails】結局bundlerって何？bundlerの仕組みを図解形式で徹底解説](https://pikawaka.com/rails/bundler)
Gemfileはアプリで利用するgemの一覧が載っているファイルで、アプリケーションディレクトリの直下にある。これを参照してgemをインストールする。
Gemfile.lockはアプリで利用するバージョンも含めた全てのgem一覧が載っているファイル。アプリで利用するgemのバージョンをロックしている。
インストールしたgemのバージョンの違いによって開発環境が異なるのを防ぐためにロックしている。
インストールされる前と後ということは覚えておこう。

###bundle installと bundle updateの違い
[【Rails】結局bundlerって何？bundlerの仕組みを図解形式で徹底解説](https://pikawaka.com/rails/bundler)

`bundle install`はGemfileからgemをインストール
Gemfile.lockを先に確認して、足りないものを入れる。
`bundle update`はGemfile.lockに書かれている内容を無視してgemをインストール
低いGemfile.lockのバージョンを全てupdateしてくれる。
Gemfileに記載されているgemを全てアップデートするので本来ならロックがかかっていて互換性が保たれているがなくなってしまう。
アプリが動かなくなったりするので多用しない。

単体でupdateするときは`bundle update gem名`


#ログイン機能

この章の学習ページ
[[初心者] deviseを使ってログイン機能を実装してみよう](https://qiita.com/Orangina1050/items/a16e655519a60f35b394)

[deviseでログイン機能を簡単に実装する](https://qiita.com/cocoa-engineer/items/625da569fcac1ad2db1f)


##つまづきポイント

###mysqlを利用したアプリ作成で不具合

```
rails new login_app -d mysql  
```

これをやってインストール中に

```
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
```
一部のgemに不具合が起きて結果

```
An error occurred while installing mysql2 (0.5.3), and Bundler cannot
continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'`
succeeds before bundling.
In Gemfile:
  mysql2
         run  bundle binstubs bundler
Could not find gem 'rails (~> 6.0.3, >= 6.0.3.3)' in any of the gem sources
listed in your Gemfile.
         run  bundle exec spring binstub --all
bundler: command not found: spring
Install missing gem executables with `bundle install`
       rails  webpacker:install
Could not find gem 'rails (~> 6.0.3, >= 6.0.3.3)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
```

railsとmysqlのバージョンが合わないみたい…。
アプリのディレクトリに移動して

```
bundle install
```
するとまたエラー

```
Installing mysql2 0.5.3 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
中略
An error occurred while installing mysql2 (0.5.3), and Bundler cannot
continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'`
succeeds before bundling.
```
言われた通り

```
gem install mysql2 -v '0.5.3'   
```

その後、また`bundle install`しても同じエラーを繰り返し。
調べてどこかで見つけた下のコードを打ち込みました。
（出典メモするのわすれました…調べればすぐ見つかります。）

```
bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"
```

これで`bundle install`が通りました。
多分、gemfileに書かれた記述を内部で反映させてくれるコードか何かだったと思います。

###rails s　でサーバーが立てられない

```
Webpacker configuration file not found /Users/daiho0323/rails-1/login_app/config/webpacker.yml. Please run rails webpacker:install Error: No such file or directory @ rb_sysopen - /Users/daiho0323/rails-1/login_app/config/webpacker.yml (RuntimeError)
```
言われた通り`rails webpacker:install`でインストール

```
Webpacker successfully installed 🎉 🍰
```
長いロードの末に完了

しかし今度は
```
Mysql2::Error::ConnectionError (Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)):
```

だとさ、この障害は以前経験したことがあったので
`sudo mysql.server start`
でmysqlを起動します。

直りました！

##気になったポイント

###bundle execを使わないとマイグレーションできない
参考ページ
[【Rails】結局bundlerって何？bundlerの仕組みを図解形式で徹底解説](https://pikawaka.com/rails/bundler)
`rake db:migrate`でマイグレーションしようとしましたが

```
rake aborted!
Gem::LoadError: You have already activated rake 12.3.3, but your Gemfile requires rake 13.0.1. Prepending `bundle exec` to your command may solve this.
```
`bundle exec`を頭につけて欲しいみたい。つけたらできました。でもなぜつける必要が？
 >アプリのGemfile.lockに記載されているgemを使用する

らしい。railsアプリでインストールしたgemを指定して使うことができる。
つまりディレクトリに複数のバージョンのgemがあって、その中からgemfile.lockにあるものを実装してくれるということか。

 >もしbundle execコマンドを使用しなければシステム共通のライブラリ保存場所を環境下にしてコマンドが実行されるので、bundle installでinstallしたgemのバージョンでないgemを使用してアプリが動かない可能性があります。

複数のアプリを使う以上、他のgemを使わないようにしないといけないようですね。

####結局bundle exec rake db:migrate とは？

参考ページ
[bundle execとかdb:createとかが何をしているのか - Qiita](https://qiita.com/windhorn/items/0f58866291f8273f18fb)
[bundle exec rake db:migrateって何をしているの？ - Qiita](https://qiita.com/kazu_kazu/items/6aa3de08b72a099388dc)

Gemfile.lockの中にあるバージョンでgemを実行しつつ、マイグレーションファイルをもとにデータベーステーブルを作成？、こんな感じだと思います。解釈があっているかわかりませんが、流れはこんな感じだと思います。

###deviceって何？

参考ページ
[rails devise完全入門！結局deviseって何ができるの？](https://www.sejuku.net/blog/13378)

Webアプリに簡単にログイン機能を実装できるgem。
使い方はGemfileに記述して、`bundle install`。そして、
`rails g devise:install`で作ったアプリにインストール。
途中のメッセージには
 >1, Ensure you have defined default url options in your environments files.
デフォルトのURLを設定してくださいという意味です。デフォルトのURLは開発環境の場合localhost:3000になるので、例を元に記入していってください。
2, Ensure you have defined root_url to *something* in your config/routes.rb.
rootを設定してくださいという意味です。rootにしたいpathを例にならって設定しましょう。
3, Ensure you have flash messages in app/views/layouts/application.html.erb.
flashメッセージを表示するためのタグをapplication.html.erbに記入しましょう。
flashメッセージはそれぞれnotice, alertという変数に格納されます。
4, You can copy Devise views (for customization) to your app by running:
deviseのviewはデフォルトだと味気ないものになってしまいます。
viewをカスタマイズするためには rails g devise:views を打つ必要があります。
今回はカスタマイズを行わないので、何も打ち込まず進めていきます。

と書かれている。つまり、
デフォルトurlの設定→rootの設定⇨flashメッセージタグの記入⇨viewカスタマイズのためのコマンド。
これらを何かとかして欲しみたい。

`rails g devise User`でUserのモデルを作成
`rake db:migrate`でマイグレーション

作ったモデルのファイルにモジュール？で機能追加ができるみたい。
SNS認証やメール認証、ログイン記憶やタイムアウト…いろいろできて便利ってことは覚えておこう。

####deviceの設定のやり方
インストール時に出てきたメッセージの元、設定をしなければ使えない。
参考：[【Rails入門説明書】deviseについて解説](https://web-camp.io/magazine/archives/16811)

#####1.「config/environments/development.rb」ファイルにWebアプリケーションのURLの設定
参考：[Action Mailer の基礎](https://railsguides.jp/action_mailer_basics.html)
以下の行を追加

```
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```
hostとportをアクセスするurlに変える。
本来認証メールの送受信に使用される。

######config/environments/development.rbって何？
参考[設定ファイルについて](https://railsdoc.com/config)

左から順に設定ファイルがある所/環境ごとの設定ファイルを格納するディレクトリ/開発環境での設定ファイル　という意味らしい。

#####2.操作をした結果(エラーの可否)をユーザーへメッセージを表示するためapp/views/layouts/application.html.erbに追記

```
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
```
<%= yield %>の直前に追記。
ディレクトリ名の通りレイアウトを決めるみたい。
おさらい：[deviseでログイン機能を簡単に実装する
](https://qiita.com/cocoa-engineer/items/625da569fcac1ad2db1f)
`notice alert`は変数で呼び出すとデフォルトでエラーメッセージを表示してくれる。

###layoutsファイルについて
参考：[[Rails入門] layoutsファイルを分かりやすく解説!
](https://www.web-knowledge-info.com/wp/ruby_on_rails8/)
 >Railsではviewファイルにbodyタグ内のコードを記述するだけでWebページ全体が表示される仕組みになっています。

webページ全体用HTMLテンプレートがあって、それが組み込まれているからbodyを記述するだけで、表示してくれる…。
ゲームとカートリッジの関係みたいな感じか？そして、vieフォルダの中にlayoutsフォルダがあり、そこにあるファイルがテンプレートになっていると。デフォルトであるのは
`application.html.erb` Webページ全体に適用されるレイアウト
`mailer.html.erb` メール送信用のレイアウト
`mailer.text.erb` テキストメール用のレイアウト

####`application.html.erb`の中身
一番重要なのは、もちろん全体に適用される↑
中にある主なタグは
`<%= csrf_meta_tags %>`CSRF対策？をしてくれる？セキュリティ的に重要そう。
`<%= stylesheet_link_tag ‘application’, media: ‘all’, ‘data-turbolinks-track’: ‘reload’ %>`スタイルシート生成に関与するタグ。
`<%= javascript_include_tag ‘application’, ‘data-turbolinks-track’: ‘reload’ %>`Javascriptを使うときに必要らしい。
`<%= yield %>`上記のタグを使用して表示されるページの内容を組み込む…。これも必須みたい。

###diviceのヘルパーメソッドまとめ
おさらい：[deviseでログイン機能を簡単に実装する
](https://qiita.com/cocoa-engineer/items/625da569fcac1ad2db1f)
参考：[Rails deviseで使えるようになるヘルパーメソッド一覧](https://qiita.com/tobita0000/items/866de191635e6d74e392)
覚える必要はない、あることを知っていれば大丈夫。

###diviceを拡張ーカラムの追加
参考：[[初心者] deviseを使ってログイン機能を実装してみよう](https://qiita.com/Orangina1050/items/a16e655519a60f35b394)
[Railsのマイグレーションについて](https://qiita.com/okamoto_ryo/items/55e823b4cd0cc602244e)
 >必要な作業は4つあります。
・usersテーブルにnameカラムを追加する
・新規登録画面に名前を入力できる欄を追加する
・ストロングパラメータで名前を保存できるようにする
・メインページで登録した名前が表示されるようにする

```
rails g migration AddNameToUsers name:string # usersテーブルにnameカラムをstring型で追加するマイグレーションファイルを作成
```
このコードはnameという名前のカラムをstring型で、AddNameToUsersというクラスで追加してくれる（マイグレーションファイルの作成）ということ。

新規登録画面の追加はapp/views/devise/registrations/new.html.erb
デフォルトでそこに決まっている、他のビューファイルの一覧は↓から
https://web-camp.io/magazine/archives/16811#devise

###フォームを追加するためのメソッド
form_forというフォームを追加するためのメソッドがある。
便利なので覚えておこう。実際に使っているタグは
`f.label`とか。
タグの詳細はこちら[特定のモデルに特化したフォームを生成](https://railsdoc.com/form#label)
メソッドの使い方はこちら[Railsのform_forの書き方を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/22194)

 ><%= form_for(モデル,[オプション]) do |f| %>
    フォームの中身
<% end %>
モデルの部分には、@userや@postなどモデルオブジェクトを入れます。オプションでは、送信先のurlやタグの設定（クラスをつけたり、MIMEタイプを指定したり）をします。

###ストロングパラメータを編集？
おさらい⇨https://qiita.com/Orangina1050/items/a16e655519a60f35b394
deviceでは初期状態で↑が設定されている。DBに新しいカラムのデータを保存するために編集が必要らしい。
`configure_permitted_parameters`deviceのメソッドで追加ができる。application_controllerに上のメソッドを追記する

####そもそもストロングパラメータって何？
参考サイト：[[Ruby on Rails]ストロングパラメーターについてカンタンに説明する](https://kirohi.com/strong_parameters_rails#:~:text=%E3%82%B9%E3%83%88%E3%83%AD%E3%83%B3%E3%82%B0%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%A8%E3%81%AF%E3%80%8CWeb,%E3%81%AB%E3%81%97%E3%81%A6%E3%81%8F%E3%82%8C%E3%82%8B%E3%82%B9%E3%83%88%E3%83%AD%E3%83%B3%E3%82%B0%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%80%82)
：[【Ruby on Rails】ストロングパラメータって何なの？](https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8)

web上から不正なデータが送信されてきた場合に備えて、送信データを制限してくれるありがたい仕組み。

####configure_permitted_parametersメソッドを詳しくみる

[before_action](https://qiita.com/kouhei_matuura/items/5d0fb826363878535510)
他のアクションを実行する前に処理してくれるメソッド
[configure_permitted_parameters](https://qiita.com/ohnitakahiro/items/4487aed43fa264ddcdee)
とても詳しく載っている。デフォルト以外のストロングパラメータを追加するためのメソッド。後ろの`if`がもしtrueなら動くということか。

[devise_parameter_sanitizer.permit](http://once-and-only.com/programing/ruby/devise%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/#toc13)
これも一つのメソッドで追加するときに使う。

####`current_user.name`って何よ？
意味はログインしているユーザのカラムからnameを取得するということ。
実に簡単だが、初めての場合これの意味もわからなかった。ちゃんと言葉の意味を理解すれば他のメソッド？(変数？)でも使いこなせそう。
（メソッドと変数の定義が良くわからなくなってきた。JSで練習コーディングしていたときとは全然姿形が違う。）

#覚えておくと便利そうなもの
ありがたくコピペさせてもらっておいとこ。
##メソッド
####user_signed_in?：ユーザーがログインしているか調べる。ログインしているかどうかでビューを変えたい時などに利用する。
####current_user.カラム名：現在ログインしているユーザーのデータをDBから取ってくる。
####configure_permitted_parameters：ストロングパラメーターの許可を追加する。

#完走した感想
一つ一つ気になることを調べながらここに書いていくのは時間がかかる。編集合わせて3日かかったよ！
メソッドの定義も良くわからなくなってきたし、詳しいこと書いているサイトを見つけるのも時間かかったりと時間が食われていく。これ最後までできるか？全部が一つ一つのメソッドについてまとまっているリファレンスサイトが欲しい。公式のgithubじゃあ良くわからぬ。