#laravelで検索機能の実装
#要件定義
今回はユーザー一覧から検索機能を実装する。
ユーザーの管理対象項目は名前、年齢、性別
#データベース設計
プロジェクト名:serch
モデル名:User
テーブル名:users
#プロジェクトファイルの作成
$ composer create-project --prefer-dist laravel/laravel='5.8' serch
#.envファイルにデータベースの設定
#database.sqliteファイルの作成
#Userモデルとマイグレーションファイルを作成
$ php artisan make:model User -m
Model created successfully.
Created Migration: 2019_12_21_043638_create_users_table
#マイグレーションファイルの修正
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('sex');
$table->integer('age');
$table->timestamps();
});
#マイグレーションの実行
$ php artisan migrate
Migration table created successfully.
Migrating: 2019_12_21_043638_create_users_table
Migrated: 2019_12_21_043638_create_users_table (0.01 seconds)
#UsersControllerの作成
$ php artisan make:controller UsersController
Controller created successfully.
#usersテーブルにデータを挿入するseederファイルを作成
$ php artisan make:seeder UsersTableSeeder
Seeder created successfully.
#seederファイルに書き込むデータを記載する。
DB::table('users')->insert([
[
'name' => '岩崎蓮',
'age' => 34,
'sex' => '男',
'created_at' => new Datetime(),
'updated_at' => new Datetime()
],
[
'name' => '町田里奈',
'age' => 20,
'sex' => '女',
'created_at' => new Datetime(),
'updated_at' => new Datetime()
],
[
'name' => '横田拓也',
'age' => 25,
'sex' => '男',
'created_at' => new Datetime(),
'updated_at' => new Datetime()
],
[
'name' => '矢野萌',
'age' => 25,
'sex' => '女',
'created_at' => new Datetime(),
'updated_at' => new Datetime()
],
[
'name' => '沼田舞',
'age' => 31,
'sex' => '女',
'created_at' => new Datetime(),
'updated_at' => new Datetime()
],
]);
}
#DatabaseSeederに実行できるように編集
public function run()
{
// $this->call(UsersTableSeeder::class);
$this->call(UsersTableSeeder::class);
}
#seederの実行
$ php artisan db:seed
Seeding: UsersTableSeeder
Database seeding completed successfully.
#ルーティングの設定
//検索結果を表示する
Route::get('/serch','UsersController@serch');
//ユーザー一覧と検索画面
Route::get('/','UsersController@index');
#Userモデルに書き込み可能な権限を加える
class User extends Model
{
//
protected $fillable = ['name','age','sex'];
}
#コントローラーの編集
とりあえず、ユーザー一覧を取得するindexメソッドを作成
public function index() {
$users = User::all();
return view('index')->with('users', $users);
}
#全体ビューを作成
共通化するビューのフォルダとファイルを作成
$ cd resources/views
$ mkdir layouts
$ cd layouts
$ vi defalt.blade.php
defalt.blade.phpの編集
<!doctype html>
<html lang="ja">
<head>
<title>ユーザー管理</title>
<!-- 必要なメタタグ -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div class="container" style="margin-top:50px;">
<ul class="nav justify-content-end">
<li class="nav-item">
<a class="nav-link active" href="{{ url('/')}}">検索と一覧</a>
</li>
</ul>
@yield('content')
</div>
...
<!-- オプションのJavaScript -->
<!-- 最初にjQuery、次にPopper.js、次にBootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
#indexビューを作成
@extends('layouts.defalt')
@section('content')
<h1>検索条件を入力してください</h1>
<form action="{{ url('/serch')}}" method="post">
{{ csrf_field()}}
{{method_field('get')}}
<div class="form-group">
<label>名前</label>
<input type="text" class="form-control col-md-5" placeholder="検索したい名前を入力してください" name="name">
</div>
<div class="form-group">
<label>年齢</label>
<input type="text" class="form-control col-md-5" placeholder="年齢を入力してください" name="age" value="{{ old("name")}}">
</div>
<div class="form-group">
<label>年齢の条件</label>
<select class="form-control col-md-5" name="age_condition">
<option selected value="0">選択...</option>
<option value="1">以上</option>
<option value="2">以下</option>
</select>
</div>
<div class="form-group">
<label>性別</label>
<select class="form-control col-md-5" name="sex">
<option selected value="0">選択...</option>
<option value="1">男</option>
<option value="2">女</option>
</select>
</div>
<button type="submit" class="btn btn-primary col-md-5">検索</button>
</form>
@if(session('flash_message'))
<div class="alert alert-primary" role="alert" style="margin-top:50px;">{{ session('flash_message')}}</div>
@endif
<div style="margin-top:50px;">
<h1>ユーザー一覧</h1>
<table class="table">
<tr>
<th>ユーザー名</th><th>年齢</th><th>性別</th>
</tr>
@foreach($users as $user)
<tr>
<td>{{$user->name}}</td><td>{{$user->age}}</td><td>{{$user->sex}}</td>
</tr>
@endforeach
</table>
</div>
@endsection
#laravelサーバーを立ち上げて確認
$ php artisan serve --host ***.****.**.** --port 8000
こんな感じでできていれば、okです。
#検索機能を実装していきます。
##検索画面を作成
@extends('layouts.defalt')
@section('content')
<div style="margin-top:50px;">
<h1>検索結果</h1>
@if(isset($users))
<table class="table">
<tr>
<th>ユーザー名</th><th>年齢</th><th>性別</th>
</tr>
@foreach($users as $user)
<tr>
<td>{{$user->name}}</td><td>{{$user->age}}</td><td>{{$user->sex}}</td>
</tr>
@endforeach
</table>
@endif
@if(!empty($message))
<div class="alert alert-primary" role="alert">{{ $message}}</div>
@endif
</div>
@endsection
##検索メソッドを作成。コントローラーの編集
public function serch(Request $request) {
$keyword_name = $request->name;
$keyword_age = $request->age;
$keyword_sex = $request->sex;
$keyword_age_condition = $request->age_condition;
if(!empty($keyword_name) && empty($keyword_age) && empty($keyword_age_condition)) {
$query = User::query();
$users = $query->where('name','like', '%' .$keyword_name. '%')->get();
$message = "「". $keyword_name."」を含む名前の検索が完了しました。";
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
elseif(empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 0){
$message = "年齢の条件を選択してください";
return view('/serch')->with([
'message' => $message,
]);
}
elseif(empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 1){
$query = User::query();
$users = $query->where('age','>=', $keyword_age)->get();
$message = $keyword_age. "歳以上の検索が完了しました";
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
elseif(empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 2){
$query = User::query();
$users = $query->where('age','<=', $keyword_age)->get();
$message = $keyword_age. "歳以下の検索が完了しました";
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
elseif(!empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 1){
$query = User::query();
$users = $query->where('name','like', '%' .$keyword_name. '%')->where('age','>=', $keyword_age)->get();
$message = "「".$keyword_name . "」を含む名前と". $keyword_age. "歳以上の検索が完了しました";
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
elseif(!empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 2){
$query = User::query();
$users = $query->where('name','like', '%' .$keyword_name. '%')->where('age','<=', $keyword_age)->get();
$message = "「".$keyword_name . "」を含む名前と". $keyword_age. "歳以下の検索が完了しました";
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
elseif(empty($keyword_name) && empty($keyword_age) && $keyword_sex == 1){
$query = User::query();
$users = $query->where('sex','男')->get();
$message = "男性の検索が完了しました";
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
elseif(empty($keyword_name) && empty($keyword_age) && $keyword_sex == 2){
$query = User::query();
$users = $query->where('sex','女')->get();
$message = "女性の検索が完了しました";
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
else {
$message = "検索結果はありません。";
return view('/serch')->with('message',$message);
}
}
#おまけ
#目的
laravelで検索機能を実装してみたが、検索時のコントローラーに書いたメソッドが長すぎるので、すっきりさせる。その際にファザードという機能を使う。
#全体的な流れ
"serch"という名称のサービスプロバイダーを作成
#プロバイダーの設定
##SerchServiceProviderを作成
$ php artisan make:provider SerchServiceProvider
Provider created successfully.
##serchクラスの登録
public function register()
{
$this->app->bind(
'serch',
'App\Http\Compornents\Serch'
);
}
#ファザードの設定
##ファザードクラスの作成
laravel/app 配下にFacadesディレクトリを作成し、その中にSerch.phpを作成
コンポーネントの登録名を取得する為のアクセサーgetFacadeAccessor()メソッドを以下のように定義します。
<?php
namespace App\Facades;
use Illumnate\Support\Facades\Facade;
class Serch extends Facade
{
protected static function getfacadeAccessor() {
retrun 'serch';
}
}
##検索メソッドをSerchクラスにまとめる
laravel/app/Http 配下に Components ディレクトリを作成し、その中にSerch.phpを作成
<?php
namespace App\Http\Components;
use App\User;
class Serch
{
public static function serch($keyword_name,$keyword_age,$keyword_sex,$keyword_age_condition)
{
$query = User::query();
if(!empty($keyword_name) && empty($keyword_age) && empty($keyword_age_condition)) {
$users = $query->where('name','like', '%' .$keyword_name. '%')->get();
$message = "「". $keyword_name."」を含む名前の検索が完了しました。";
}
elseif(empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 0){
$message = "年齢の条件を選択してください";
}
elseif(empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 1){
$users = $query->where('age','>=', $keyword_age)->get();
$message = $keyword_age. "歳以上の検索が完了しました";
}
elseif(empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 2){
$users = $query->where('age','<=', $keyword_age)->get();
$message = $keyword_age. "歳以下の検索が完了しました";
}
elseif(!empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 1){
$users = $query->where('name','like', '%' .$keyword_name. '%')->where('age','>=', $keyword_age)->get();
$message = "「".$keyword_name . "」を含む名前と". $keyword_age. "歳以上の検索が完了しました";
}
elseif(!empty($keyword_name) && !empty($keyword_age) && $keyword_age_condition == 2){
$users = $query->where('name','like', '%' .$keyword_name. '%')->where('age','<=', $keyword_age)->get();
$message = "「".$keyword_name . "」を含む名前と". $keyword_age. "歳以下の検索が完了しました";
}
elseif(empty($keyword_name) && empty($keyword_age) && $keyword_sex == 1){
$users = $query->where('sex','男')->get();
$message = "男性の検索が完了しました";
}
elseif(empty($keyword_name) && empty($keyword_age) && $keyword_sex == 2){
$users = $query->where('sex','女')->get();
$message = "女性の検索が完了しました";
}
else {
$users = null;
$message = "検索結果はありません。";
}
return [$users,$message];
}
}
#コントローラーを編集
class UsersController extends Controller
{
//
public function index() {
$users = User::all();
return view('index')->with('users', $users);
}
public function serch(Request $request) {
$keyword_name = $request->name;
$keyword_age = $request->age;
$keyword_sex = $request->sex;
$keyword_age_condition = $request->age_condition;
list($users,$message) = Serch::serch($keyword_name,$keyword_age,$keyword_sex,$keyword_age_condition);
return view('/serch')->with([
'users' => $users,
'message' => $message,
]);
}
}
#サービスプロパイダーとエイリアスの登録
'providers' => [
App\Providers\SerchServiceProvider::class,
'aliases' => [
'Serch' => App\Facades\Serch::class,
.
.
#終了です。