module namespaceを用ひたルーティング 　deviseの設定

<h2>コントローラー作成</h2>
ほしいコントローラごとに
admin/
member/
user/,,,
などとし、を先に指定して作成する

```ruby:コンソール
rails g controller admin/items
rails g controller admin/genres
rails g controller admin/members
:
rails g controller member/adresses
rails g controller member/items
rails g controller member/cart_items
```

```
username:~/environment/naganocake $ rails g controller [namespaceのグループ名]/[コントローラー名]
```

<h2>route.rbを編集　modlue namespace scope</h2>
```ruby:route.rb
Rails.application.routes.draw do

  namespace :[グループ名] do
    # グループ内で適用するルーティングをここに記述
    # resourcesを使用し一括作成or
    # get/post/deleteを指定して、個別に作成可能。
　　#namespaceはURLパスとファイル構成も指定される。
　　　　URL→/member/items/new
  end
　　
　　scope module: :[グループ名] do
     # グループ内で適用するルーティングをここに記述
     #URLは変えず、ファイル構成だけ指定
　　　URL→/items/new
    end
　　　
　　　
 　　scope :member do
    　resources :[グループ名]
　　　#URLは指定、ファイル構成変わらず
 　　end
end
```

<p>collection do や　member　doでresourcesで生成されないactionのroutingを行う</p>


```ruby:route/rb
 # member側のルーティング設定　
 root 'member/items#top'  get 'items' => 'member/items#index'　　　フォルダ名/ファイル名#アクション名
 get 'about' => 'member/items#about'
  scope module: :member do
    resources :addresses, :except => [:new] 
    resources :items,only: [:show,:index]

    resources :members,only: [:show,:edit,:update] do
      collection do #collection doは、resourcesで生成されないactionのroutingができる
        get 'unsubscribe' 　#URLが /members/unsubscribe(.:format)    id付与はしない                    
        patch 'withdraw' 
      end
    end
　　resources :items do
    member do   #member doは、resourcesで生成されないactionのroutingができる
      get :follow  #URLが /items/:id/follow(.:format)    id付与される
    end
end
  end
  devise_for :member,controllers: {
    sessions: 'members/sessions',
    registrations: 'members/registrations',
    passwords: 'members/passwords'}
```
：

```ruby:ruby:route/rb
# 管理者側のルーティング設定
   namespace :admin do
    resources :members, :except => [:new,:destroy]
    resources :items, :except => [:destroy] 
    resources :genres, :except => [:new,:show,:destroy]
    resources :orders,only: [:show,:update,:index]
    resources :ordered_items,only: [:update] 
  end
    
    devise_for :admin,controllers: {
      sessions: 'admins/sessions',
      registrations: 'admins/registrations',
      passwords: 'admins/passwords'}
```

https://qiita.com/kawasakiatsushi/items/8209a979d86ab3468799

https://qiita.com/kazuyoshi-tech/items/f9648668c2e7b6626ca4


<h2>ログイン機能２つ作る</h2>
```ruby:GEM
gem 'devise'
```

```
 bundle install
 rails g devise:install
```

<h2>モデル２つ作る</h2>
```
rails g devise User
rails g devise Admin
```

<p>モデルでバリテーション設定しておく</p>
<p></p>

```ruby:model/member.rb
  validates :first_name, presence: true
  validates :last_name, presence: true
  validates :street_address, presence: true  #APIで住所検索つけるときは項目分けるので注意
  validates :phone_number, format: { with: /\A\d{10,11}\z/ }
  # アカウント作成時の電話番号はハイフンなしの10桁もしくは11桁のみ登録可能とするバリデーション
  validates :first_name_kana, :last_name_kana, presence: true, format: { with: /\A([ァ-ン]|ー)+\z/, message: "is must NOT contain any other characters than alphanumerics." }
  # アカウント作成時の苗字名前のカナ入力欄のカタカナのみ入力可能とするバリデーション
  validates :postal_code, format: { with: /\A\d{7}\z/ }
  # アカウント作成時の郵便番号はハイフンなしの7桁のみ登録可能とするバリデーション
```

<h2>deviseのテーブルをカスタマイズ</h2>
<p>ユーザー登録に必要なもの追記する</p>

```ruby:09876521913_devise_create_members.rb 
class DeviseCreateMembers < ActiveRecord::Migration[5.2]
  def change
    create_table :members do |t|
 :
 :
## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at
      t.string :last_name, null: false
      t.string :first_name, null: false
      t.string :last_name_kana, null: false
      t.string :first_name_kana, null: false
      t.string :post_code, null: false
      t.string :address, null: false
      t.string :phone_number, null: false
      t.boolean :is_deleted, null: false , default: false

      t.timestamps null: false ⇦ここデフォルトで入ってる
    end
 end
end
```
```ruby:
rails db:migrate
```
<p>deviseのコントローラに修正が必要なときは、application_controllerに記述する</p>
<p>初期設定ではないカラム（nameなど）をmemberテーブルに追加したので以下で設定</p>

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
#以下追記
before_action :configure_permitted_parameters, if: :devise_controller?
 protected
:
 def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:last_name,:first_name,
    :last_name_kana, :first_name_kana,:post_code,:address,:phone_number ])
 end
end
```


<p>deviseコントローラーつくる</p>
```
rails g devise:controllers members
rails g devise:controller admins

```
<p>ルーティングを直す∵</p>
```ruby:routes.rb
Rails.application.routes.draw do
  devise_for :admins, controllers: {
    sessions:      'admins/sessions',
    passwords:     'admins/passwords',
    registrations: 'admins/registrations'
  }
  devise_for :users, controllers: {
    sessions:      'users/sessions',
    passwords:     'users/passwords',
    registrations: 'users/registrations'
  }
  root to: 'home#index'
end
```

<h2>deviseのviewつくる</h2>
```
rails g devise:views members
rails g devise:views admins
```
<p>モデルを追加しているのでフィールドを追加</p>
<p>sign upページになるので日本語化しておく</p>

```ruby:app/views/devise/registrations/new.html.erb
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "devise/shared/error_messages", resource: resource %>
: #以下追記していく
 <tr>
    <td class="col-2">名前</td>
    <td class="text-right col-1">
      <%= f.label :last_name,"(姓)"%>
     </td>
      <td class="col-3">
         <%= f.text_field :last_name, autofocus: true, :placeholder => "令和" %>
  　　　</td>
     <td class="text-right col-1">
           <%= f.label :first_name,"(名)"%>
       </td>
      <td class="col-3">
         <%= f.text_field :first_name, :placeholder => "花子" %>
       </td>
 </tr>
:
```
<p>ヘッダー設定しておくとあとで楽になる</p>
```ruby:app/views/layouts/application.html.erb
 <% if admin_signed_in? %>
:
 <% elsif member_signed_in? %>
:
 <% else %> <!--管理者でも会員でもログインしていないとき-->
<li class="nav-item px-4">
 <%= link_to "About", about_path, method: :get, class: 'btn btn-outline-dark' %>
 </li>
 <li class="nav-item px-4">
   <%= link_to "商品一覧", items_path, method: :get, class: 'btn btn-outline-dark' %>
 </li>
<li class="nav-item px-4">
   <%= link_to "新規登録", new_member_registration_path, class: 'btn btn-outline-dark' %>
</li>
<li class="nav-item pl-4">
     <%= link_to "ログイン", new_member_session_path, class: 'btn btn-outline-dark' %>
</li>
</header>
    
    <%= yield %>
  </body>
</html>
```
<h2>deviseのフォームヘルパーを変更</h2>
<p>deviseではform_forが使用されているため、form_withへと変更しておく</p>
<p>app/views/devise/registrations/new.html.erb</p>
<p>app/views/devise/sessions/new.html.erbを確認する</p>
```
<%= form_with model
```

<p>namespaceの影響で</p>
<p>元：ドメイン名/admins/sign_up</p>
<p>今：ドメイン名/admins/admins/sign_up</p>
<p>に変化してしている</p>
∴アクセスして確認する時注意

<h2>API使って郵便番号入れるのありかも</h2>

https://qiita.com/japwork/items/8667a076777fab35c0c4


<h2>アカウント管理　 sign_up されたくない場合</h2>
<p></app/modelsフォルダのadmin.rbファイルも自動作成され、Adminモデルが定義されるp>
<p>:database_authenticatable（パスワードの正確性を検証）</p>
<p>:registerable（ユーザ登録や編集、削除）</p>
<p>:recoverable（パスワードをリセット）</p>
<p>:rememberable（ログイン情報を保存）</p>
<p>:validatable（emailのフォーマットなどのバリデーション）</p>
<p>管理者アカウント admin に対して勝手に sign_up されたくない場合は Admin モデルを修正。
不要部分をコメントアウトしておく</p>
<p>deviseの管理するmodel（userならapp/models/user.rb）から:registerableを抜くかコメントアウトしておく</p>

```ruby:models/admin
class Admin < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, # :registerable,　　⇦ここの部分
         :recoverable, :rememberable, :validatable
end
```
<p>管理者アカウントはコンソールまたはseedで作成</p>
<p>rails db:migrate:resetした時にデータが全て消えるので注意</p>
```ruby:コンソール
$ rails console
> admin= Admin.new
> admin.email = 'admin@example.com'
> admin.password = 'password'
> admin.save
 
```