２ Railsでログインユーザのアカウント管理機能 実装

Railsを用いてユーザアカウント管理機能を作成する。

## 1 エンドユーザーの会員情報編集画面を作成する

###### 編集画面 , 更新機能のルーティングを下記のように定義した。

```Ruby
get 'customers/edit' => 'public/customers#edit'
patch 'customers' => 'public/customers#update'
```

###### (1)編集画面を表示するアクションを記述する

app/controllers/public/customers_controller.rb

```Ruby
def edit
   @customer = current_end_user
end
```

###### (2)ビューファイルを作成する
```Ruby
<h1>エンドユーザ#会員情報編集</h1>

このurlは、データを送るupdateアクションのurl
<%= form_with model:@customer, url: "/customers", local:true do |f| %>

  <h4>姓</h4>
  <%= f.text_field :first_name %>

  <h4>セイ</h4>
  <%= f.text_field :katakana_first_name %>

  <h4>名</h4>
  <%= f.text_field :last_name %>

  <h4>メイ</h4>
  <%= f.text_field :katakana_last_name %>

  <h4>メールアドレス</h4>
  <%= f.email_field :email %>

  <h4>郵便番号</h4>
  <%= f.text_field :postal_code %>

  <h4>住所</h4>
  <%= f.text_field :address %>


  <h4>電話番号</h4>
  <%= f.text_field :telephone_number %>

  <%= f.submit '保存' %>

<% end %>
```

###### (3)更新機能の為のアクションを作成する

```Ruby
def update
  customer = current_public
  customer.update(customer_params)
  redirect_to  customers_mypage_path
end

private

def customer_params
    params.require(:public).permit(:email, :first_name,:katakana_first_name,:last_name,:katakana_last_name,:postal_code,:address,:telephone_number)
end
```

## <font color="Red">エラー発生!!</font>:scream:
#### wrong number of arguments (given 0, expected 1)というエラーが発生
```Ruby
def update
    customer = current_end_user
    customer.update
    redirect_to  customers_mypage_path
end
``` 

原因: 
customer.update(customer_params)を customer.updateにしていた。
customer.update(customer_params)に修正して解決。


## <font color="Red">エラー発生!!</font>:scream:
#### param is missing or the value is empty: publicというエラーが発生

``` Ruby
def customer_params
    params.require(:public).permit(:email, :first_name,:katakana_first_name,:last_name,:katakana_last_name,:postal_code,:address,:telephone_number)
end
``` 


会員情報を編集する際に、送られてきたパラメータ
``` Ruby
"end_user"=>{"first_name"=>"田", "last_name"=>"涼雅", "katakana_first_name"=>"タナカ", "katakana_last_name"=>"リョウガ", "address"=>"123456", "telephone_number"=>"123456", "email"=>"1@1"}, "commit"=>"編集内容を保存する", "controller"=>"public/customers", "action"=>"update"
``` 

定義したストロングパラメータ
``` Ruby
{"email"=>"1@1", "first_name"=>"田", "katakana_first_name"=>"タナカ", "last_name"=>"涼雅", "katakana_last_name"=>"リョウガ", "address"=>"123456", "telephone_number"=>"123456"}
``` 

原因:
フォームで送られた情報とストロングパラメータで定義した受け取れる情報の形が違う!
ストロングパラメータを下記のように定義し、解決

```Ruby
def customer_params
    params.require(:end_user).permit(:email, :first_name,:katakana_first_name,:last_name,:katakana_last_name,:postal_code,:address,:telephone_number)
end 
``` 


## 2 退会機能を実装する

###### (1)退会管理用のカラムを追加する

コマンドを実行する
``` 
$ rails g migration AddIsDeletedToCustomers is_deleted:boolean
``` 

デフォルト値をfalseに設定する
``` Ruby
class AddIsDeletedToCustomers < ActiveRecord::Migration[5.2]
  def change
    add_column :customers, :is_deleted, :boolean, default: false
  end
end
``` 

マイグレーションファイルをデータベースに反映させる
``` 
rails db:migrate
``` 

###### <font color="Red">ポイント</font>
退会管理用のカラムを追加し、
その中の値で退会したユーザーか、退会していないユーザーか判断する
default値をfalseと設定 => 退会処理したらTrueにする

#### (2)コントローラーに退会している場合の処理を記述する

#### <font color="Red">仕組み</font>
顧客のログイン処理が実行される前に退会管理用のカラムを確認しtrue(退会済み)だった場合ログインせずにサインアップ画面に遷移させる。

``` Ruby
class Public::SessionsController < Devise::SessionsController

before_action :customer_state, only: [:create]

protected
def customer_state
    @customer = EndUser.find_by(email: params[:end_user][:email])
    @customer.valid_password?(params[:end_user][:password])
    if (@customer.valid_password?(params[:end_user][:password])) && (@customer.is_deleted == true)
      redirect_to  new_public_registration_path
    end
end
``` 

###### <font color="Red">ポイント</font>

ログイン時のパラメータ
``` 
"end_user"=>{"email"=>"1@1", "password"=>"123456", "remember_me"=>"0"}, "commit"=>"Log in", "controller"=>"public/sessions", "action"=>"create"}
``` 

###### (1)
```Ruby
@customer = EndUser.find_by(email: params[:end_user][:email])
```
params[:end_user][:email]は、ログイン時のパラメータより、1@1
find_byより、EndUserモデル内のemailカラムの値が1@1の情報を取得し、@customerに格納する


###### (2)
```Ruby
 @customer.valid_password?(params[:end_user][:password])
```
params[:end_user][:password]は、ログイン時のパラメータより、123456
valid_password?より、特定のアカウントのパスワードと入力されたパスワードが一致しているかを確認

valid_password?の使い方
```
ユーザー情報.valid_password?(入力されたパスワード)
```

###### (3)
```Ruby
if (@customer.valid_password?(params[:end_user][:password])) && (@customer.is_deleted == true)
      redirect_to  new_public_registration_path
end
```

取得したユーザーのis_deletedカラムの値がtrueであれば
新規登録画面に遷移させる


## 3 退会確認画面を作成

###### (1)退会確認画面のルーティングを作成する
```Ruby
get 'customers/unsubscribe' => 'public/customers#unsubscribe'
```

###### (2)退会確認画面を表示するアクションを記述する
```Ruby
def unsubscribe
end
```

###### (3) ビューファイルの作成
```Ruby
エンドユーザ#退会確認画面
<%= link_to "退会しない", customers_mypage_path %>

退会処理をするアクションへのlink (このアクションは後に定義する)
<%= link_to "退会する", customers_withdraw_path, method: :patch, data: { confilm: "本当に退会しますか？" } %>
```


## 4 退会処理
is_deletedの値をtrueにすれば良い。
下記のようにアクションを定義した


app/controllers/public/customers_controller.rb
```Ruby
def withdraw
    @customer = current_end_user
    
    #is_deletedカラムをtrueに変更する
    @customer.update(is_deleted: true)
   
　　#ログアウトさせる
    reset_session
    redirect_to root_path
end
```