はじめてのLaravel – Laravel Scout Algolia Search Tutorial With Example をやってみた

ここ数年アプリケーションの開発からは遠ざかっていたのですが、ググってみると、Laravel + Vue.js が流行ってるっぽいので。

まずは手元のMacにcomposerを入れるところから。

$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...
Composer (version 1.8.0) successfully installed to: /Users/eshinoha/vue-instantsearch-getting-started/src/20190128/composer.phar
Use it: php composer.phar

コマンドをパスの通ってるところに移動させる

$ sudo mv composer.phar /usr/local/bin/composer

コマンド叩ける確認を踏まえてバージョン確認

$ composer --version
Composer version 1.8.0 2018-12-03 10:31:16

今回やってみるとチュートリアルはコチラ→ Laravel Scout Algolia Search Tutorial With Example

Laravelプロジェクトを作ります。symfonyが〜とかって懐かしい名前が見えたりして和みつつ、ちゃんと入ったっぽい。

$ composer create-project --prefer-dist laravel/laravel scout
Installing laravel/laravel (v5.7.19)
  - Installing laravel/laravel (v5.7.19): Downloading (100%)
Created project in scout
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 86 installs, 0 updates, 0 removals
  - Installing vlucas/phpdotenv (v2.5.2): Downloading (100%)
〜略〜
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
> @php artisan key:generate --ansi
Application key set successfully.

configディレクトリのdatabase.phpを編集。デフォルトがmysqlぽかったのでMacにbrewでMySQL入れてrootで。(MySQL8にrootでローカルから入れなかったので MySQL8でユーザーのパスワードの変更 / リセット方法 を参考にさせていただきましたmm)

 16     'default' => env('DB_CONNECTION', 'mysql'),
〜略〜
 43         'mysql' => [
 44             'driver' => 'mysql',
 45             'host' => env('DB_HOST', '127.0.0.1'),
 46             'port' => env('DB_PORT', '3306'),
 47             'database' => env('DB_DATABASE', 'scout'),
 48             'username' => env('DB_USERNAME', 'root'),
 49             'password' => env('DB_PASSWORD', ''),
 50             'unix_socket' => env('DB_SOCKET', ''),
 51             'charset' => 'utf8mb4',
 52             'collation' => 'utf8mb4_unicode_ci',
 53             'prefix' => '',
 54             'prefix_indexes' => true,
 55             'strict' => true,
 56             'engine' => null,
 57         ],

Scoutをインストール

$ composer require laravel/scout
Using version ^6.1 for laravel/scout
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing laravel/scout (v6.1.3): Loading from cache
〜略〜
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

artisanとか言われてもナンノコッチャ的な感は否めませんが、言われるがまま。笑 Artisanコマンド(早見表)を読むと、便利なコマンドが扱えそうですね。

$ php artisan vendor:publish --provider="LaravelScoutScoutServiceProvider"
Copied File [/vendor/laravel/scout/config/scout.php] To [/config/scout.php]
Publishing complete.

知らない間に.envファイルができてて、ココに↓を追加します。(ここに書かれたDB接続情報とかってどう扱われるのかな。。)

SCOUT_QUEUE = true

Algolia用のクライアントライブラリをインストール

$ composer require algolia/algoliasearch-client-php
Using version ^2.2 for algolia/algoliasearch-client-php
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing algolia/algoliasearch-client-php (2.2.0): Downloading (100%)
〜略〜
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

.envにAlgoliaのクレデンシャルを追記します。AdminのKeyが必要なので取扱注意的な。

ALGOLIA_APP_ID = Enter your Application ID
ALGOLIA_SECRET = Enter your Admin API Key
Screen Shot 2019-01-29 at 11.49.06

User.phpにAlgolia周りのコードを追加(LaravelScoutSearchableをロードして、searchableAsというメソッドを作る)

  1 <?php
  2
  3 namespace App;
  4
  5 use IlluminateNotificationsNotifiable;
  6 use IlluminateContractsAuthMustVerifyEmail;
  7 use IlluminateFoundationAuthUser as Authenticatable;
  8 use LaravelScoutSearchable;
  9
 10 class User extends Authenticatable
 11 {
 12     use Notifiable;
 13     use Searchable;
 14
 15     /**
 16      * The attributes that are mass assignable.
 17      *
 18      * @var array
 19      */
 20     protected $fillable = [
 21         'name', 'email', 'password',
 22     ];
 23     public function searchableAs()
 24     {
 25         return 'users_index';
 26     }
 27
 28     /**
 29      * The attributes that should be hidden for arrays.
 30      *
 31      * @var array
 32      */
 33     protected $hidden = [
 34         'password', 'remember_token',
 35     ];
 36 }

コマンドを使ってユーザーデータを作りましょう、と。ってか、そもそもDBにテーブル作ってないし、アプリからDBに接続したこともないよな、と…。案の定、エラー吐いて落ちてるし。。

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>> factory(AppUser::class, 100)->create();
Illuminate/Database/QueryException with message 'SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (SQL: insert into `users` (`name`, `email`, `email_verified_at`, `password`, `remember_token`, `updated_at`, `created_at`) values (Dr. Jackeline Vandervort III, dickens.krystal@example.com, 2019-01-29 03:10:37, $2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm, xH667wwvyn, 2019-01-29 03:10:37, 2019-01-29 03:10:37))'

database/migrationsっていうディレクトリの中に 2014_10_12_000000_create_users_table.php っていうそれっぽいファイルがあるので、rake db:migrate みたいなことを事前にすれば良いきがしてきた。

ググるとphp artisan migrateがそれっぽいコマンドのようなので、叩いてみると、やっぱり.envのDB接続情報みにいってーって感じみたい。

$ php artisan migrate
   IlluminateDatabaseQueryException  : SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (SQL: select * from information_schema.tables where table_schema = homestead and table_name = migrations)
〜略〜PDO::__construct("mysql:host=127.0.0.1;port=3306;dbname=homestead", "homestead", "secret", [])
      /Users/eshinoha/vue-instantsearch-getting-started/src/20190128/scout/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70
  Please use the argument -v to see more details.

とりあえず、MySQLにscoutってデータベース作って

mysql> create database scout;
Query OK, 1 row affected (0.09 sec)

それっぽくデータベースには入れるようになったのを確認しつつ、

$ mysql -uroot -h127.0.0.1 scout
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 15
Server version: 8.0.13 Homebrew
〜略〜
mysql> 

.envは↓こんな感じにして、

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=scout
DB_USERNAME=root
DB_PASSWORD=

database.phpはforgeにしておく(.envからよしなにやってくれるってことすよね?)

'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),

それでもダメでググったらMySQL8でLaravelだと的なアレでdatabase.phpにmodeってのを追加する必要があると…。でもこのmodeいじるとMySQL7ユーザーに影響あったりするみたい…。GitHubのLaravelのチケット→ [5.6] Update MySqlConnector to be compatible to MySQL 8.0 #23948

んま、とりあえずdatabase.phpのmysqlの設定にに↓追加しましたが、上手いこといかず。。

           'modes'       => [
                'ONLY_FULL_GROUP_BY',
                'STRICT_TRANS_TABLES',
                'NO_ZERO_IN_DATE',
                'NO_ZERO_DATE',
                'ERROR_FOR_DIVISION_BY_ZERO',
                'NO_ENGINE_SUBSTITUTION',
            ],

MySQL8のデフォルトの認証の機構が変わった?とかでmy.cnfを編集してみます。。my.cnfどこじゃーってことで。

$ mysql --help | grep my.cnf
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf 

左から順番に見てったら、 /usr/local/etc/my.cnf があったので、そこに default_authentication_plugin=mysql_native_password を追加して再起動。

# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
default_authentication_plugin=mysql_native_password

mysql繋いでみると、、それっぽい感じな気がする。

mysql> show variables like 'default_authentication_plugin';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| default_authentication_plugin | mysql_native_password |
+-------------------------------+-----------------------+
1 row in set (0.02 sec)

けど、既存のrootユーザーは変わってないのか。。

mysql> select User, Plugin from mysql.user where User = 'root';
+------+-----------------------+
| User | Plugin                |
+------+-----------------------+
| root | caching_sha2_password |
+------+-----------------------+
1 row in set (0.00 sec)

ってことで、ようやく。。

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';
Query OK, 0 rows affected (0.06 sec)
mysql> select User, Plugin from mysql.user where User = 'root';
+------+-----------------------+
| User | Plugin                |
+------+-----------------------+
| root | mysql_native_password |
+------+-----------------------+
1 row in set (0.00 sec)

database.phpのmode要らない気がしてきたので削除してから、php artisan migrateを再び。。キターーーッ!

$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

ってことで、ようやく、、、ユーザー100人追加するZE!って思ったら、、’Class ‘AlgoliaSearch/Version’ not found’ですと…?(何この前途多難感。笑)

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>>
>>> factory(AppUser::class, 100)->create();
Symfony/Component/Debug/Exception/FatalThrowableError with message 'Class 'AlgoliaSearch/Version' not found'

GitHubの Class ‘AlgoliaSearchVersion’ not found #328 を見ると↓ってことなので、

Laravel Scout is not yet compatible with algoliasearch-client-php: ^2.0. Please update your composer.json file to require the version algoliasearch-client-php: ^1.27 of Algolia API Client.

https://github.com/laravel/scout/issues/328#issuecomment-442822231

compose.json書き換えてからcomposerで1.27を。

$ composer require algolia/algoliasearch-client-php:^1.27
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
  - Downgrading algolia/algoliasearch-client-php (2.2.0 => 1.28.0): Downloading (100%)
Writing lock file
Generating optimized autoload files
> IlluminateFoundationComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: beyondcode/laravel-dump-server
Discovered Package: fideloper/proxy
Discovered Package: laravel/nexmo-notification-channel
Discovered Package: laravel/scout
Discovered Package: laravel/slack-notification-channel
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.

php artisan tinker (tinkerなんだかよくわかってないけどシェルモードってことなのかな)で、”factory(AppUser::class, 100)->create();”したら、ようやくデータ入った気がする!!

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>> factory(AppUser::class, 100)->create();
=> IlluminateDatabaseEloquentCollection {#2942
     all: [
       AppUser {#2946
         name: "Erick Volkman",
         email: "amiya15@example.net",
         email_verified_at: IlluminateSupportCarbon @1548739582 {#2950
           date: 2019-01-29 05:26:22.597677 UTC (+00:00),
         },
         updated_at: "2019-01-29 05:26:22",
         created_at: "2019-01-29 05:26:22",
         id: 4,
       },
       AppUser {#2951
         name: "Timmy Windler",
         email: "buck.casper@example.com",
         email_verified_at: IlluminateSupportCarbon @1548739582 {#2952
           date: 2019-01-29 05:26:22.598016 UTC (+00:00),
         },
         updated_at: "2019-01-29 05:26:23",
         created_at: "2019-01-29 05:26:23",
         id: 5,
       },

MySQLの方は103件データ入ってて、

mysql> use scout
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_scout |
+-----------------+
| migrations      |
| password_resets |
| users           |
+-----------------+
3 rows in set (0.00 sec)
mysql> select count(*) from users
    -> ;
+----------+
| count(*) |
+----------+
|      103 |
+----------+
1 row in set (0.00 sec)

Algoliaのusers_indexには100件のデータが入ってた(3件のレコードの違いは何??笑)

Screen Shot 2019-01-29 at 14.29.12

ようやくフロント側に取り掛かります。index.blade.phpというファイル。中身を吟味する時間的余裕が無くなってきたので無慈悲にコピペしていきます。笑

Screen Shot 2019-01-29 at 14.33.33

検索用のコントローラーをartisanで作って

$ php artisan make:controller SearchController
Controller created successfully.

app/Http/Controllersにある(この辺のディレクトリ構造とか馴染みがないのでいちいちつまづく。笑)、SearchController.phpに以下のコードをコピペ。

<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppUser;
class SearchController extends Controller
{
    public function search(Request $request)
    {
    	if($request->has('search')){
    		$users = User::search($request->get('search'))->get();
    	}else{
    		$users = User::get();
    	}
        return view('index', compact('users'));
    }
}

web.phpは↓こんな感じで良いのかな?

<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
Route::get('index','SearchController@search');

でもって、http://localhost:8000/index にアクセスすると…。無事にユーザー一覧が表示されて、検索窓から検索できました!

Screen Shot 2019-01-29 at 14.42.53
amzn_assoc_ad_type =”responsive_search_widget”; amzn_assoc_tracking_id =”diary045-22″; amzn_assoc_marketplace =”amazon”; amzn_assoc_region =”JP”; amzn_assoc_placement =””; amzn_assoc_search_type = “search_widget”;amzn_assoc_width =”auto”; amzn_assoc_height =”auto”; amzn_assoc_default_search_category =””; amzn_assoc_default_search_key =”Laravel”;amzn_assoc_theme =”light”; amzn_assoc_bg_color =”FFFFFF”; //z-fe.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&Operation=GetScript&ID=OneJS&WS=1&Marketplace=JP
タイトルとURLをコピーしました