Railsビギナーやってみた【第2章】

###第２章　ユーザー登録・ログイン機能作成
***

#####devise(gem)を使う準備
Gemfileに`gem 'devise'`を追加し、ターミナルで`bundle install`実行
`rails g devise:install`を実行した後、`rails g devise user`でuserモデルを作成
これでルーティングも自動で作成される。

#####ログアウトリンクの設置
部分テンプレートの表示：appビューののbody内部に`<%= render 'layouts/header' %>`を追加
部分テンプレートの作成：ビューのlayoutsフォルダに_header.html.erbファイルを作成

#####ログイン、ログアウトで表示するリンクを変える
<% if user_signed_in? %>を使う←user_signed_in?はdeviseが用意してくれているメソッドなので定義しなくてもよい

***
####メール認証機能をつける

本人のメールアドレスのみ登録を受け付ける
#####deviseを使った認証機能
・userモデルのファイルに`:confirmable`を追加
・config/environments/development.rb(＝設定/環境/開発ファイル)に`config.action_mailer.default_url_options = { host: "localhost", port: 3000 }`を追加

●開発環境で送られたメールを確認する
・Gemfileのgroup :development do内に`gem 'letter_opener_web`を追加しbundle installを実行
・開発ファイルの、先ほど追加した下あたりに`config.action_mailer.delivery_method = :letter_opener_web`を追加
・ルートファイルに下記コードを追加

```routes.rb
if Rails.env.development?
 mount LetterOpenerWeb::Engine, at: "/letter_opener"
end
```

#####⚠️メール認証機能を実装した後に新規登録ができなくなった
<img width="1440" alt="スクリーンショット 2020-06-13 18.43.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600709/98b03bd9-51e7-1325-5721-891214002e73.png">
confirmed_atが見つからないと言われてしまいました
多分userモデル作成時に、マイグレーションファイル内のコメントアウトを外さないままrails db:migrateしてしまったことが原因？
[こちら](https://teratail.com/questions/140788)を参考に、エラー解消できました。
`bin/rails db:drop`でデータベースをdrop(削除)して再度設定・マイグレートし直します

#####メールの文章内容や新規登録・ログイン画面の文章を編集する
`rails g devise:views`でdeviseが用意しているビューフォルダを呼び出す

***
####ユーザーの詳細ページを作成
#####usersテーブルにnameカラムを追加する
●`rails g migration AddNameToUsers`を実行し、作成されたマイグレーションファイルのdef change内に`add_column :users, :name, :string`を追加➡️migrateする
●新規登録フォームの書き換え
●ストロングパラメータを設定する
・ユーザー新規登録機能のコントローラファイルを作成：`rails g devise:controllers users`
app/controllers/users/registrations_controller.rbが新規登録用のコントローラになる。configure_sign_up_paramsに関する部分のコメントアウトを外す
・カスタマイズしたコントローラファイルを適用するためにルーティングファイルを書き換える
devise_for :usersの続きに`controllers: { registrations: 'users/registrations' }`を追加
●ユーザーの詳細ページを表示するコントローラの作成　`rails g controller users`
●showアクションの定義、ルーティング、ビューファイルの作成

#####⚠️新規登録してもnameカラムが空になる？
新規登録用コントローラのコメントアウトを外した部分のkeyをnameにしていなかったこと・ルートファイル内のスペルミスが原因でした。

***
####ユーザーと質問を紐付ける
questionテーブルに、user_idとカラムを持たせる
●マイグレーションファイルを作成　`rails g migration AddUserIDToQuestions`
・def change内に`add_reference :questions, :user, foreign_key: true`➡️migrate実行

●user_idに値を入れる処理
・questionコントローラのcreateアクション書き換え
current_userはdeviseが用意してくれている

●モデルの関連づけ（アソシエーション）
・userモデルファイルに`has_many :questions`
　questionモデルファイルに`belongs_to :user`を追加することで、1人のユーザーに対して複数の質問、また１つの質問に対して1人のユーザーを関連づけることができる
・↑のhas_many〜の続きに、`depandent: destroy`を追加すると、ユーザーを削除した時、作成した質問も一緒に削除する

●ユーザー詳細ページに、作成した質問のタイトル一覧を表示する
・アソシエーションを使っているので、@user.questionsでそのユーザーの質問を取得できる

***
####質問の編集・削除機能を作る
●ルーティング
・`get "/questions/:id/edit", to: "questions#edit"
・patch "/questions/:id", to: "questions#update"⭐️
・delete "/questions/:id", to: "questions#destroy"

●アクション定義とビュー作成
・editアクションで@questionに代入しているので、form_withタグで指定した`model: @question`で編集フォームができる

●質問の詳細ページに編集・削除ページへのリンクを貼る
・削除ページのリンクタグ内には`method: :HTTPリクエストメソッド, data: {confirm: "メッセージ"}`を指定する

●ログインしているユーザーのみ編集・削除・質問できるようにする
deviseのメソッドを使う(`authenticate_user!`)
・questionsコントローラに`before_action :authenticate_user!, only: [:new, :create, edit, update, :destroy]`

●質問を作成した本人のみ編集・削除できるようにする
・↑の下に`before_action :ensure_correct_user, only: [:edit, :update, :destroy]`
・ensure_correct_userをprivate下に定義する
 ◎find(params[:id])とfind_by(id: params[:id])の違いについて
　値が見つからなかった時の処理が異なる　[参考](https://doruby.jp/users/tn_on_rails/entries/-Rails-find(%3Cid%3E)%E3%81%A8find_by(id--%3Cid%3E)%E3%81%AE%E9%81%95%E3%81%84)
　find：エラーになる
　find_by：nilを返す

●編集・削除リンクを、質問を作成した本人にのみ表示する


***
###学んだこと
●ビューでのrenderは部分テンプレートを表示する
●link_toメソッドの`method: `はHTTPリクエストメソッドの種類を指定する。指定しなければgetになる
`data: {confirm: "テキスト"}`でリンクがクリックされた時のアラートを表示する
●ulタグ＝順序のないリストタグ。関連性・規則性のあるものに使用（ナビゲーションメニューやスライドショーなど）
●Rubyの埋め込みコード：表示したい場合は<%= %>だが、表示の必要がなければイコールは必要ない
●一度マイグレーションを実行した後に修正する時は、ロールバックしてから修正し、`bin/rails db:migrate`を実行する必要がある
●add_referenceはテーブルの関連づけに必要なカラムを作成する。自動的にカラム名に_idが付けられる
　外部キー制約（`foreign_key: true`）：外部キーを作る時にあるとよりセキュリティが強固になるもの
●アソシエーションって便利
●ルーティングのメソッド：patch(リソースの部分更新)とdelete
●一括自動ルーティング　`resources :コントローラ名`
　`rails routes`実行し確認