Tracking Read/Unread or Viewed/NotViewed
This is a how-to, not a help-request:
Tracking Views of a record, per user.
Then, for the component that "shows" the record, set its
CSS can be used to set a class when the
Tracking Views of a record, per user.
viewsviews migration:return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('views', function (Blueprint $table) {
$table->id();
$table->foreignUlid('user_id')->nullable()->constrained()->cascadeOnDelete()->cascadeOnUpdate();
$table->foreignUlid('post_id')->nullable()->constrained()->cascadeOnDelete()->cascadeOnUpdate();
$table->timestamps();
});
}return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('views', function (Blueprint $table) {
$table->id();
$table->foreignUlid('user_id')->nullable()->constrained()->cascadeOnDelete()->cascadeOnUpdate();
$table->foreignUlid('post_id')->nullable()->constrained()->cascadeOnDelete()->cascadeOnUpdate();
$table->timestamps();
});
}ViewView model:namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class View extends Model
{
use HasFactory;
protected $fillable = [
'post_id',
'user_id',
];
public function post(): BelongsTo
{
return $this->belongsTo(Post::class, 'post_id');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
}namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class View extends Model
{
use HasFactory;
protected $fillable = [
'post_id',
'user_id',
];
public function post(): BelongsTo
{
return $this->belongsTo(Post::class, 'post_id');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
}UserUser model: public function views(): HasMany
{
return $this->hasMany(View::class, 'user_id', 'id');
} public function views(): HasMany
{
return $this->hasMany(View::class, 'user_id', 'id');
}PostPost model: public function trackView(?User $user): void
{
$user_id = $user?->id ?? Auth::user()->id;
View::create([
'user_id' => $user_id,
'post_id' => $this->id,
]);
}
public function getIsViewedAttribute(?User $user)
{
$user_id = $user?->id ?? Auth::user()->id;
return $this->views->where('user_id', $user_id)->count();
} public function trackView(?User $user): void
{
$user_id = $user?->id ?? Auth::user()->id;
View::create([
'user_id' => $user_id,
'post_id' => $this->id,
]);
}
public function getIsViewedAttribute(?User $user)
{
$user_id = $user?->id ?? Auth::user()->id;
return $this->views->where('user_id', $user_id)->count();
}Then, for the component that "shows" the record, set its
mountUsing()mountUsing() to track the "view": ->mountUsing(function (Post $record) {
$record->trackView(Auth::user());
}) ->mountUsing(function (Post $record) {
$record->trackView(Auth::user());
})CSS can be used to set a class when the
isViewed()isViewed() attribute is truthy.