[Laravel]閲覧回数を表示する
はじめに
Laravelで投稿のアクセス数・閲覧回数が分かるように実装していきます。
環境
PHP 8.x
Laravel 10.x
MySQL 8.x
tl;dr
- テーブルを作成する
-
$fillable
プロパティを定義する - コントローラーに閲覧回数をカウントするロジックを追加する
- モデルのアソシエーションを設定する
- ビューに表示する
テーブルを作成する
閲覧回数を記録する用テーブルを作成します。
php artisan make:model ListingView -m
INFO Model [app/Models/ListingView.php] created successfully.
INFO Migration [database/migrations/2023_11_03_170015_create_listing_views_table.php] created successfully.
カラムを定義する
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('listing_views', function (Blueprint $table) {
$table->id();
$table->string('ip_address', 55);
$table->string('user_agent', 255);
$table->foreignId('listing_id')->constrained()->onDelete('cascade');
$table->foreignId('user_id')->nullable()->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('listing_views');
}
};
php artisan migrate
でマイグレーションを実行します。
➜ php artisan migrate
INFO Running migrations.
2023_11_03_170015_create_listing_views_table .................... 818ms DONE
$fillable
プロパティを定義する
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ListingView extends Model
{
use HasFactory;
protected $fillable = [
'ip_address',
'user_agent',
'listing_id',
'user_id'
];
}
コントローラーに閲覧回数をカウントするロジックを追加する
<?php
namespace App\Http\Controllers;
use App\Models\Listing;
use App\Models\ListingView;
class ListingController extends Controller
{
public function show(string $id, Request $request)
{
$listing = Listing::find($id);
$user = $request->user();
ListingView::create([
'ip_address' => $request->ip(),
'user_agent' => $request->userAgent(),
'listing_id' => $id,
'user_id' => $user?->id
]);
return view('listings.show', compact('listing'));
}
}
'ip_address' => $request->ip()
: リクエストからIPアドレスを取得し、ip_address
というデータベースカラムに設定します。
'user_agent' => $request->userAgent()
: リクエストからユーザーエージェント情報を取得し、user_agent
というデータベースカラムに設定します。ユーザーがどのブラウザや端末からアクセスしているかを表示します。
'user_id' => $user?->id
: $user?->id
の?
はオプショナルプロパティアクセス演算子です。$user
が存在しない場合にエラーが出ません。ログインしてないユーザーのアクセス数もカウントしたいので使ってます。
user_id
カラムが無くても成立しますが、投稿のおすすめ機能やよくみらている記事機能などを追加する時に便利なので入れてみました。
投稿をクリックし、アクセス数がカウントされていることを確認します。
モデルのアソシエーションを設定する
一つの投稿の閲覧回数を取得したいのでモデルのアソシエーションを設定します。
<?php
namespace App\Models;
use App\Models\ListingView;
class Listing extends Model
{
...
public function views()
{
return $this->hasMany(ListingView::class);
}
}
<?php
namespace App\Models;
use App\Models\Listing;
class ListingView extends Model
{
...
public function listing()
{
return $this->belongsTo(Listing::class);
}
}
ビューに表示する
コンポーネントを作成し、投稿にアクセスされた回数を表示します。
{{ $listing->views->count() }}
投稿一覧に閲覧回数の多い順で投稿を表示したり、ユーザーごとの閲覧履歴を表示したりなどDBを活用しいろんな情報を表示できますねー
終わりに
閲覧回数をカウント&表示することができました。
ページをリロードする度にレコード数が増えてしまうのでフィルタリングした方が良いと思いました。同じIPアドレスからの直近1時間以内の重複したアクセスがカウントされないようにするのも良さそうです。
Discussion