
RailsでECサイトのAdmimアカウントを追加し、商品を登録出来る方法を紹介していきたいと思います。
adminアカウントとは、管理者用のアカウントですね!
誰でもECサイトの商品を追加できないように、管理者用のアカウントを作り、UserアカウントとAdminアカウントを分ける必要があります。
作業内容
・Adminアカウントでログインを可能にする
・Admin がログインしたら /admins
という Admin がログインしないと見れないページ(ダッシュボード)にリダイレクトする
・AdminアカウントはRails consoleからしか作成できないようにする(勝手に利用者が登録できないようにする)
・Admin画面で商品を登録できるようにする
以上が今回やっていく作業内容です。
作業手順
devise:Adminの追加
まずはAdminアカウントを追加するためにdeviseでAdminアカウントを追加していきます。
下記のコードをコンソールに入力します。
$rails g devise Admin
$rails db:migrate
下記のようにroute.rb
にdevise_for :admins
が自動的に追加されましたね。
Rails.application.routes.draw do
devise_for :admins
devise_for :users
その次にModelを見てみましょう。Adminモデル
にもこんな感じで追加されてました。今回はconsole
からしか登録できないようにしたいので、:registerable
は消しちゃいます。誰でも登録できないようにするためですね。
class Admin < ApplicationRecord
devise :database_authenticatable,
:recoverable, :rememberable, :validatable
end
それではAdminのアカウントを作成してみましょう。db/seeds.rb
ファイルに記入して、コンソールで$ rails db:seed
を追加すればすぐにアカウントを作成することができます。
Admin.create!(
email: 'test@test.com',
password: '******',
)
$ rails db:seed
コンソールの方で実際にアカウントが作られているのかどうかをみてみます。確認方法はAdmin.all
でもAdmin.last
でもどちらでも大丈夫です。
$ rails c
2.5.3 :001 > Admin.all
=> #<ActiveRecord::Relation [#<Admin id: 1, email: "test@test.com", created_at: "2020-10-08 14:32:06", updated_at: "2020-10-08 14:32:06">]>
無事に作られていますね。
Adminトップページの作成
それではルーティングを作っていきましょう!
私の作業の進め方はモデル→マイグレーション→ルーティング→コントローラー→ビューの順番で進めていきますので、今回もこの順番で進めていきます。
Adminアカウントでログインした後のAdmin専用のトップページを作成したいので、下記のようにルーティングします。
namespace :admins do
root "toppages#index"
end
URLはこれで/admins
になります。
$rails routes
を入力して、きちんとルーティングできているかどうかを見てみましょう。
admin_root GET /admins(.:format) admins/toppages#index
上記のようになっていれば大丈夫です。
これで/admins
のというURLが完成しました。次に、controller
とviews
を設定していこうと思います。
コントローラーとビューの作成
adminsの元にtoppages
を作りたいので、以下のようにコンソールに追加します。
$rails g controller admins/toppages index
次に、新しくadmins/application_controller.rb
というファイルを作成します。ディレクトリがadmins
のため、上記のようにAdmins::
と名前空間を追加します。
class Admins::ApplicationController < ApplicationController
end
そしたらtoppages_controller.rb
にもAdmin::
を追加します。
class Admins::ToppagesController < Admin::ApplicationController
def index
end
end
controllerとviewsにコードを追加していきたいのですが、その前にまずはログインして/admins
に入れるか見てみましょう。

上の画像ではナビゲーションバーがログイン前とログイン後で変化していないので、変更できるようにしましょう。
<header class="mb-4">
<nav class="navbar navbar-expand-sm navbar-light p-4"style="background-color: #e3f2fd">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent">
<ul class="navbar-nav">
<% if user_signed_in? %>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"></a>
<ul class="dropdown-menu dropdown-menu-right">
<li class="dropdown-divider"></li>
<li class="dropdown-item"><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></li>
</ul>
</li>
<% elsif admin_signed_in? %>
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown"></a>
<ul class="dropdown-menu dropdown-menu-right">
<li class="dropdown-divider"></li>
<li class="dropdown-item"><%= link_to "ログアウト", destroy_admin_session_path, method: :delete %></li>
</ul>
</li>
<% else %>
<li class="nav-item"><%= link_to 'Signup', new_user_registration_path, class: 'nav-link' %></li>
<li class="nav-item"><%= link_to 'Login', new_user_session_path, class: 'nav-link' %></li>
<% end %>
</ul>
</div>
</nav>
</header>
<% elsif admin_signed_in? %>
を追加することでAdminアカウントのログアウト機能をナビゲーションバーに追加することできました。
それではcontrollerとviewsにコードを追加していきます。
Adminに商品登録機能をつける
admin/products/new
という感じにしたいため、product
にadmin
のreferences
をつけます。しかし、products
のマイグレーションファイルをadmin
より先に作ってしまっているため、ファイルの順番を入れ替える必要があります。そのため、下記のように日付を変えてあげると、順番を変更できます
<before>
20200913131359_create_products.rb
20201009140157_devise_create_admins.rb
⬇️
<after>
20200909140157_devise_create_admins.rb
20200913131359_create_products.rb
products
のマイグレーションにadmin
のreferences
がを追加します。
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.references :admin, foreign_key: true
t.references :user, foreign_key: true
t.string :name, :null => false
t.text :description, :null => false
t.integer :price, :null => false
t.timestamps
end
end
end
このままだとマイグレーションができないので、一旦データベースをリセットしていきます。
$ rails db:migrate:reset
無事マイグレーションができましたら、また再度アカウントを作ります。
$ rails db:seed
アカウントが無事作られたら、モデルの関連性を追加します。
class Admin < ApplicationRecord
has_many :products, dependent: :destroy
end
class Product < ApplicationRecord
belongs_to :admin
end
モデルに関連性ができたらコントローラーを作成していきます。
そのまえにルーティングの設定をします。
ルーティングの設定
admins
の元にproducts
を追加していきます。下記のようにルーティングにproducts
を追加します。
Rails.application.routes.draw do
devise_for :admins
devise_for :users
root to: "products#index"
resources :products, only: [:show] do
scope module: :products do
resources :add_to_carts, only: [:create]
resources :delete_in_carts, only: [:create]
end
end
resource :cart, only: [:show]
resource :charge, only: [:create]
namespace :admins do
root to: "toppages#index"
resources :products, only: [:new, :create]
end
end
下記のようになればOKです。

admins
の配下にproducts
を置くことができました。それでは、app/admins/products_controller.rb
をを作成していきます。
コントローラーの作成
products
のコントローラーを追加していきます。
class Admins::ProductsController < Admins::ApplicationController
end
既にadmins/applicationController
は作成しているので、class Admins::ProductsController < ApplicationController
ではなく、class Admins::ProductsController < Admins::ApplicationController
となります。
それではこのcontroller
で商品登録をし、元々あるproducts
のcontroller
からnew
とcreate
を移します。
class ProductsController < ApplicationController
def index
@products = Product.order(id: :desc).page(params[:page]).per(10)
end
def show
@product = Product.find(params[:id])
end
end
class Admins::ProductsController < Admins::ApplicationController
def new
@product = current_admin.products.build
end
def create
@product = current_admin.products.build(product_params)
if @product.save
flash[:success] = "Productが正常に作成されました"
redirect_to root_path
else
flash.now[:danger] = "Productが正常に再生されませんでした"
render :new
end
end
private
def product_params
params.require(:product).permit(:name, :description, :price, :image)
end
end
current_user
の部分を全てcurrent_admin
に変更しただけですね。
ビューの作成
こちらもUserアカウント用からAdminアカウント用の商品追加機能に変更します。
<h1>新規商品の追加</h1>
<%= simple_form_for [:admins,@product] do |f| %>
<div class="form-group">
<%= f.label :name, '*Name' %>
<%= f.text_field :name ,class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :description, '*Description' %>
<%= f.text_field :description ,class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :price, '*Price' %>
<%= f.text_field :price ,class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :image, 'image' %>
<%= f.file_field :image %>
</div>
<%= f.button :submit, "CREATE PRODUCT", :class => 'btn' %>
<% end %>
<%= simple_form_for @product do |f| %>
が元々のコードですが、これだとproducts_path
にリクエストを送ることになってしまします。namespaceの場合は、<%= simple_form_for [:admins,@product] do |f| %>
このようにするとadmins_products_path
にリクエストを送れます。

"CREATE PRODUCT"ボタンを押すと、無事商品が登録されました。

Adminアカウントがログインしないと使えないようにする
ログインしないと商品を登録できないようにするために、下記のようにします。
class Admins::ApplicationController < ApplicationController
before_action :authenticate_admin!
end
before_action :authenticate_user!
と同じですね。これのadminバージョンです。
ログイン直後とログアウト直後のページを指定する
現状、ログイン直後は全てproducts#index
になってしまっているので、下記のようにApplicationController
を変更します。
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
if resource.is_a?(Admin)
admins_root_path
else
root_path
end
end
def after_sign_out_path_for(resource)
if resource == :admin
new_admin_session_path
else
new_user_session_path
end
end
end
resource.is_a?(Admin)
というのはresource
がAdmin
のインスタンスであれば true を返すという処理です。要するに、 resource
は Devise
に定義されているアカウントのクラスのインスタンスを意味します。
Admin
でログインすると/admins
に無事リダイレクトされました!
まとめ
以上がECサイトのAdminアカウントの追加方法です!
今回の記事ではnamespaceを使っているので、namespaceのいい勉強になると思います。
僕も最初はnamespaceについての理解が難しかったのですが、調べて自分でアウトプットしていくと理解が深くなりました。
ECサイトはいろんな機能があるので、ものすごく勉強になります。
プログラミングの勉強の際に、この記事を参考にして頂けると幸いです。
最後まで読んで頂きありがとうございました。