
Laravel-adminで顧客管理システムの構築手順【爆速】
Laravelのインストールは下記を参考に済ませておきましょう。
LaravelをLaradockでインストールする手順
【Laravel】Laradockで複数プロジェクトを動かす手順
Laravel-adminインストール
composerでlaravel-adminをインストールします。
composer require encore/laravel-admin
下記のコマンドを実行することでインストールが完了します。
# to publish assets and config php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider" php artisan admin:install
うまくいけば管理画面にアクセスすることができます。確認してみましょう。下記でログインできればokです。(localhostは適宜ご自身の環境に変更してください。)
http://localhost/admin/
ユーザー名: admin
パスワード: admin
データベース作成(migration)
データベースを設計します。下記のようなDBを作成します。
- 顧客(customer) - 顧客id(id) - 顧客名(name) - 担当スタッフid(staff_id) - ステータス(status) - 顧客詳細(customer_details) - 顧客詳細id(id) - 顧客id(customer_id) - 電話番号(tel) - 備考(remarks) - 契約開始日(contracted_at) - スタッフ(staffs) - スタッフid(id) - 名前(name)
Migrationファイルを作成して、テーブルを作っていきましょう。
スタッフテーブル
まずはスタッフテーブルから作成しましょう。
ターミナル
php artisan make:migration create_staffs_table --cretae=staffs
編集ファイル:
database/migrations/2018_xx_xx_xxxxxx_create_staffs_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateStaffsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('staffs', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->comment('従業員名');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('staffs');
}
}
顧客テーブル
顧客テーブル、顧客詳細テーブルは後回しにして、先にスタッフの画面を作ってもokです。一応ここでは先にテーブルを書いてしまいます。
ターミナル
php artisan make:migration create_customers_table --create=customers
編集ファイル:
database/migrations/2018_xx_xx_xxxxxx_create_customers_table.php
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCustomersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('customers', function (Blueprint $table) { $table->increments('id'); $table->string('name')->comment('顧客名'); $table->integer('staff_id')->unsigned()->nullable()->comment('担当スタッフid'); $table->enum('status', ['active', 'stop']); $table->timestamps(); $table->foreign('staff_id')->references('id')->on('staffs'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('customers'); } }
Statusにenum(列挙型)というのを使っています。予め決められた値(今回であれば「active」か「stop」か)を入れるのに使います。
顧客詳細テーブル
ターミナル
php artisan make:migration create_customer_details_table --create=customer_details
編集ファイル: 2018_xx_xx_xxxxxx_create_customer_details_talbe.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCustomerDetailsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('customer_details', function (Blueprint $table) {
$table->increments('id');
$table->integer('customer_id')->unsigned()->comment('顧客id');
$table->string('tel')->nullable()->comment('電話番号');
$table->string('contracted_at')->nullable()->comment('契約開始日');
$table->text('remarks')->nullable()->comment('備考');
$table->timestamps();
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade')->onUpdate('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('customer_details');
}
}
モデル作成
スタッフモデルを作成します。
php artisan make:model Models\\Staff
上記のコマンドにより、app/Models/Staff.php
が生成されます。中身は規則通りDB名は複数形、モデルは単数形で登録していたら何も書かなくても動きます。
動作しない場合は下記のように使用するテーブル名を記述しましょう。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Staff extends Model { protected $table = 'staffs'; }
続いてコントローラーを作成しましょう(customerについては後ほど)
コントローラー作成
Staff.phpのモデルを使うように指定してコントローラーを作成します。
php artisan admin:make StaffController --model=App\\Models\\Staff
簡単にできあがったControllerについて説明しておくと、下記のようなイメージです。
- URLとなる部分
index(一覧表示)
show(詳細表示)
edit(編集)
create(新規作成) - メソッド
grid(一覧表示に使うメソッド)
detail(詳細表示に使うメソッド)
* form(編集・作成に使うメソッド)
まず、Admin Facadeを使えるようにuseを追記します。
編集ファイル: app/Admin/Controllers/StaffController.php
use Encore\Admin\Facades\Admin;
次にgrid(一覧表示)の部分を編集します。ここではIDとスタッフの名前を表示して、Viewのアクションをdisableにしています。
編集ファイル: app/Admin/Controllers/StaffController.php
protected function grid() { $grid = Admin::grid(Staff::class, function (Grid $grid) { $grid->id('ID')->sortable(); $grid->column('name')->sortable(); $grid->actions(function ($actions) { // $actions->disableDelete(); // 削除無効 // $actions->disableEdit(); // 編集無効 $actions->disableView(); // 詳細表示無効 }); }); return $grid; }
Id、名前をソート可能なようにして一覧表示、actionは編集・削除のみといった感じです。
ルーティング設定
laravel-adminのルーティング設定はapp/Admin/routing.php
に記述します。staffsにアクセスされたらStaffControllerで処理してねというのを書きます。
編集ファイル: app/Admin/routes.php
use Illuminate\Routing\Router; Admin::registerAuthRoutes(); Route::group([ 'prefix' => config('admin.route.prefix'), 'namespace' => config('admin.route.namespace'), 'middleware' => config('admin.route.middleware'), ], function (Router $router) { $router->get('/', 'HomeController@index'); $router->resource('staffs', StaffController::class); });
日本語化
ついでに日本語化しておきましょう。localの部分をenからjaに変更するだけです。
編集ファイル: config/app.php
'local' => 'ja',
確認
ここまできたら一度確認してみましょう。http://localhost/admin/staffs
にアクセスして、一覧表示、新規作成、編集、削除が出来たらokです。
リレーションのあるModel作成
顧客テーブルは下記のようなリレーションを持っています。
顧客テーブルのid(customers.id) = 顧客詳細テーブルの顧客id(costomer_details.customer_id) (顧客テーブルは顧客詳細テーブルを1つ持っている→hasOne) 顧客テーブルのスタッフid(customers.staff_id) = スタッフテーブルのid(staffs.id) (顧客テーブルのスタッフidはスタッフテーブルに属している→belongsTo)
この関係をモデルに記述するとこうなります。
ターミナル
php artisan make:model Models\\Customer
編集ファイル: app/Models/Customer.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
//顧客詳細情報
public function detail()
{
return $this->hasOne('App\Models\CustomerDetail');
}
// スタッフ情報
public function staff() {
return $this->belongsTo('App\Models\Staff');
}
}
Laravel-adminでリレーションのあるテーブルを表示する
続いてコントローラーを設定していきましょう。Customerコントローラーを作成して編集していきます。
ターミナル
php artisan admin:make CustomerController --model=App\\Models\\Customer
編集ファイル:
app/Admin/Controllers/CustomerController.php
...(省略) protected function grid() { $grid = new Grid(new Customer); $grid->id('id'); $grid->name('名前'); $grid->detail()->tel('TEL'); $grid->staff()->name('スタッフ名'); $grid->status('状態'); $grid->created_at('作成日時'); $grid->updated_at('更新日時'); $grid->actions(function ($actions) { $actions->disableView(); }); return $grid; } ...(省略) protected function form() { $form = new Form(new Customer); $form->text('name', '顧客名'); $form->select('staff_id')->options(Staff::pluck('name', 'id')); $form->text('detail.tel', 'TEL'); $form->date('detail.contracted_at', '契約日')->format('YYYY-MM-DD'); $states = [ 'on' => ['value' => 'active', 'text' => '稼働', 'color' => 'success'], 'off' => ['value' => 'stop', 'text' => '停止', 'color' => 'danger'], ]; $form->switch('status', '状態')->states($states)->default('on'); return $form; } ...(省略)
ポイントだけ解説します。まずは一覧表示部分について。
// Customerのモデルを渡して、 $grid = new Grid(new Customer); // Customerで定義してあるdetail()により顧客詳細を取得 $grid->detail()->tel('TEL'); // Customerで定義してあるstaff()によりスタッフを取得 $grid->staff()->name('スタッフ名');
次はフォーム部分について
// Customerのモデルを渡して、 $form = new Form(new Customer); // ドットでつないでCustomerモデルのdetail()より情報を引っ張ってくる $form->text('detail.tel', 'TEL'); // 従業員は従業員一覧を取得して選択できるように // pluckによってnameをkeyにidをvalueとしてselectを生成します $form->select('staff_id')->options(Staff::pluck('name', 'id'));
これでルートにcustomersを追記してあげれば完成です!
編集ファイル: app/Admin/routes.php
$router->resource('customers', CustomerController::class);
参考URL:
データベース:マイグレーション 5.5 Laravel
Laravelのマイグレーションで使えるカラムタイプについて。onUpdate(‘cascade’)は変更に追随する。
Which is more efficient: Multiple MySQL tables or one large table? - Stack Overflow
1:1のテーブルを分けるかどうかについて
MySQLの外部キー制約RESTRICT,CASCADE,SET NULL,NO ACTIONの違いは?
外部キー制約について
【メモ】【Laravel】外部キー制約付きMigrateが通らない時のチェックポイント(Mysql)
外部キー制約をつけてMigrationが通らない時。ポイントはひっつける方(id=user_idのuser_idの方)にunsignedをつけること。
increments()で作ったカラムには、実は裏でunsined(符号無し)属性が付与される。要は採番項目なので正の値しか登録できないわけだが、役割テーブル側のuser_idとauthority_idには同様の制約を付けていない。
つまり、形式の不一致で落ちているわけですな。