- 投稿日:2020-01-18T23:35:27+09:00
Laravel6でページネーションのカスタマイズ
概要
Laravelのページネーションに触れてみたので備忘録です。
基本的に公式ページに全て書いてある。
Database: Pagination - Laravel - The PHP Framework For Web Artisans環境
PHP: 7.2.22
Laravel: 6.11.0事前準備
テスト用の各種設定は以下の通りです。ユーザやルーティングを適当に設定しています。
UsersController.phpclass UsersController extends Controller { public function index() { $users = DB::table('users')->paginate(10); return view('user.index', compact('users')); } }index.blade.php<html> <head> <title>Paging Sample</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> </head> <body> <div class="container"> <h1>Paging Sample</h1> <ul class="list-group"> @foreach ($users as $user) <li class="list-group-item"> {{ $user->name }} </li> @endforeach </ul> {{ $users->links() }} </div> </body> </html>ページネーション設定
以下コマンドを実行するとresources/views/vendor以下にpaginationのビューファイルが作成されます。現在のバージョンではデフォルトはこの中にあるbootstrap-4.blade.phpが使用されているようです。
$ php artisan vendor:publish --tag=laravel-pagination Copied Directory [/vendor/laravel/framework/src/Illuminate/Pagination/resources/views] To [/resources/views/vendor/pagination] Publishing complete. Publishing complete.$ ls resources/views/vendor/pagination/ bootstrap-4.blade.php default.blade.php semantic-ui.blade.php simple-bootstrap-4.blade.php simple-default.blade.php以下のようにしても同じです。
$ php artisan vendor:publish Which provider or tag's files would you like to publish?: [0 ] Publish files from all providers and tags listed below [1 ] Provider: Facade\Ignition\IgnitionServiceProvider [2 ] Provider: Fideloper\Proxy\TrustedProxyServiceProvider [3 ] Provider: Illuminate\Foundation\Providers\FoundationServiceProvider [4 ] Provider: Illuminate\Mail\MailServiceProvider [5 ] Provider: Illuminate\Notifications\NotificationServiceProvider [6 ] Provider: Illuminate\Pagination\PaginationServiceProvider [7 ] Provider: Laravel\Tinker\TinkerServiceProvider [8 ] Tag: flare-config [9 ] Tag: ignition-config [10] Tag: laravel-errors [11] Tag: laravel-mail [12] Tag: laravel-notifications [13] Tag: laravel-pagination > 13 Copied Directory [/vendor/laravel/framework/src/Illuminate/Pagination/resources/views] To [/resources/views/vendor/pagination] Publishing complete. Publishing complete.bladeテンプレート内で呼び出しているlinks()でページネーションにのテンプレートを指定できます。
index.blade.php{{ $users->links('vendor.pagination.default') }}index.blade.php{{ $users->links('vendor.pagination.semantic-ui') }}前か次かだけのシンプルなページングを指定することも可能です。
index.blade.php{{ $users->links('vendor.pagination.simple-default') }}デフォルトでbootstrap-4.blade.phpが呼び出されている訳なので、これを編集することでページネーションの表示をカスタマイズすることもできます。
また、自身で作成したテンプレートも使用できますので、今回はbootstrap-4をちょっとだけ修正してsample-paginationというテンプレートを作成し使用してみる。
index.blade.php{{ $users->links('vendor.pagination.sample-pagination') }}sample-pagination.php@if ($paginator->hasPages()) <nav> <ul class="pagination justify-content-center pagination-lg"> {{-- Previous Page Link --}}@cannot('update', Model::class) @endcannot @if ($paginator->onFirstPage()) <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')"> <span class="page-link" aria-hidden="true">«</span> </li> @else <li class="page-item"> <a class="page-link text-success" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">«</a> </li> @endif {{-- Pagination Elements --}} @foreach ($elements as $element) {{-- "Three Dots" Separator --}} @if (is_string($element)) <li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li> @endif {{-- Array Of Links --}} @if (is_array($element)) @foreach ($element as $page => $url) @if ($page == $paginator->currentPage()) <li class="page-item active" aria-current="page"><span class="page-link bg-success border-success">{{ $page }}</span></li> @else <li class="page-item"><a class="page-link text-success" href="{{ $url }}">{{ $page }}</a></li> @endif @endforeach @endif @endforeach {{-- Next Page Link --}} @if ($paginator->hasMorePages()) <li class="page-item"> <a class="page-link text-success" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">»</a> </li> @else <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')"> <span class="page-link" aria-hidden="true">»</span> </li> @endif </ul> </nav> @endifまとめ
Laravelのページネーションは意外と簡単に実装できる。
スタイルの変更も分かりやすく、自由に修正できる。参考サイト
- 投稿日:2020-01-18T16:54:58+09:00
LaravelのEloquent ORMでどっちがhasでどっちがbelongsなのか?
はじめに
LaravelのEloquent ORMでは、Modelに対してhasOne、hasMany、belongsTo、belongsToManyを定義することにより、Model間の関連を表すことが出来ます。
主従(親子)関係より、主(親)となる側にhasOne、hasManyを定義し、従(子)となる側にbelongsToを定義すれば良いのですが、初心者の方には主従関係の見極めが難しいので、どっちにhasを定義し、どっちにbelongsToを定義するのかの決め方をまとめてみました。どっちがhasかbelongかの決め方
- 1対1の場合
- テーブル構造において、相手のidのカラムを持っているModelにbelongsToを定義し、他方のModelにhasOneを定義する。
- 1対多の場合
- テーブル構造において、相手のidのカラムを持っているModelにbelongsToを定義し、他方のModelにhasManyを定義する。
- 多対多の場合
- 両方のModelにbelongsToManyを定義する。
Laravelの関連の定義
LaravelのModelでの関連の定義については、以下をご参照ください。
https://readouble.com/laravel/5.8/ja/eloquent-relationships.html#one-to-one-polymorphic-relations
例
1対多の場合
こんな関連
Modelの定義
productsテーブルにmaker_idが存在するので、ProductモデルにbelongsToを定義する。
class Product extends Model { public function maker() { return $this->belongsTo('App\Maker'); } }他方のMakerモデルにhasManyを定義する。
class Maker extends Model { public function products() { return $this->hasMany('App\Product'); } }多対多の場合
こんな関連
Modelの定義
両方のModelにbelongsToManyを定義する。
class Product extends Model { public function categories() { return $this->belongsToMany('App\Category'); } }class Category extends Model { public function products() { return $this->belongsToMany('App\Product'); }
- 投稿日:2020-01-18T11:55:11+09:00
【Laravel】『Database does not exist.』エラーの原因と対処法
PHPフレームワークLaravel入門を学習中にデータベースにアクセスできない問題が発生しました。
エラーメッセージは『Database does not exist.(SQL:PRAGMA foreign_keys = ON;)』との表示。
.env
ファイルのDB_DATABASE=database.sqlite
をコメントアウトすることで解決したのですが、この記事では詳しい原因と対処法をお伝えします。エラーメッセージの意味
『Database does not exist.(SQL:PRAGMA foreign_keys = ON;)』
こちらのメッセージ、意味は「データベースが存在しません。」です。
本では誤植があったようで、実際にはデータベースファイル(database.sqlite
)のパスを指定する必要がありましたが、DB_DATABASE=database.sqLite
と入力していたため、「データベースが存在しない」というエラーが発生したようです。さらなる問題と対処法
誤植に気付き、ファイルパスを絶対パスで記入したところ、
The environment file is invalid!
のエラー。
詳細はFailed to parse dotenv file due to unexpected whitespace.
(予期しない空白のため、dotenvファイルの解析に失敗しました。)とのこと。
おそらくファイルパスに日本語が含まれていたため、うまくいかなかったのでしょう。相対パスでの表記もうまくいかず、対処法を探したところ
.env
ファイルのDB_DATABASE=〜
をコメントアウトすることでうまくいくとのこと。.envビフォー# 前略 DB_DATABASE=〜 # 後略.envアフター# 前略 # DB_DATABASE=〜 # 後略【参考】laravelにてdatabase.sqliteが存在しない(does not exist)と表示される|teratail
実際に書き換えて、サーバーを立ち上げ直したところ、きちんと動作しました。
対処法解説
では、なぜ
DB_DATABASE=〜
をコメントアウトすることで、きちんと動作するようになったのでしょうか?Laravelではデータベースを指定する際に
config/database.php
から設定を読み込みます。
このdatabase.php
ではデータベースの指定に以下のようなコードが書かれています。database.php# 前略 'database' => env('DB_DATABASE', database_path('database.sqlite')), # 後略まず、
env()
から見ていきましょう。グローバルヘルパー関数 env()
ここで使われている
env()
はLaravelに用意されているグローバルヘルパー関数の1つで、環境変数の値を取得します。
取得できない場合はデフォルト値を返します。$env = env('APP_ENV'); // APP_ENVがセットされていない場合、第二引数がデフォルト値('production')として返る $env = env('APP_ENV', 'production');
database.php
に書かれているenv('DB_DATABASE', database_path('database.sqlite'))
は、「環境変数DB_DATABASE
に保存されている値を取得する!なければdatabase_path('database.sqlite')の値を使う!」ということだったんですね。では、
DB_DATABASE
をコメントアウトすることで、取得するようになる第二引数database_path('database.sqlite')
はどういう関数なのでしょうか?グローバルヘルパー関数 database_path()
database_path()
もグローバルヘルパー関数のひとつです。
database/
ディレクトリの完全パスを返します。
database/
ディレクトリ内の指定ファイルへの完全パスを生成することもできます。$path = database_path(); // databaseディレクトリ内のfactories/UserFactory.phpへの完全パスを生成 $path = database_path('factories/UserFactory.php');
env('DB_DATABASE', database_path('database.sqlite'))
で使われていたdatabase_path('database.sqlite')
は「database/
ディレクトリのdatabase.sqlite
の完全パスを取得する!」ということだったんですね。【参考】ヘルパ 5.5 Laravel( database_path() )
2つの関数をまとめると
それぞれの関数でやっていることがわかったので、
database.php
に書かれているdatabase.php# 前略 'database' => env('DB_DATABASE', database_path('database.sqlite')), # 後略が何をしているかをまとめると、
「環境変数
DB_DATABASE
に保存されている値を取得する!なければdatabase/
ディレクトリのdatabase.sqlite
の完全パスを取得する!」ということになります。
対処法として行った「
.env
ファイルのDB_DATABASE=database.sqlite
をコメントアウトする」というのは、database_path()
で取得した完全パスをデータベースとして指定するようにするということだったんですね!その他の対処法
そうなると、「
.env
ファイルのDB_DATABASE=database.sqlite
をコメントアウトする」以外にも対処法が見えてきますね!
.env
ファイルのDB_DATABASE=database.sqlite
をコメントアウトせずにdatabase.php# 前略 'database' => env('DB_DATABASE', database_path('database.sqlite')), # 後略を
database.php# 前略 'database' => database_path('database.sqlite'), # 後略のように変更して、環境変数の読み込みをなくして直接
database.sqlite
の完全パスを指定してもきちんと動作するようになりました。まとめ
Laravelで『Database does not exist.』のエラーが出た際は、データベースのパスの指定が間違っている可能性があるので、
.env
ファイルのDB_DATABASE=database.sqlite
をコメントアウト.env# 前略 # DB_DATABASE=〜 # 後略もしくは
- 環境変数の読み込みをなくして直接
database.sqlite
の完全パスを指定database.php# 前略 'database' => database_path('database.sqlite'), # 後略を試してみましょう!
参考まとめ