In this example, we demonstrate how to create a quiz application. Only admin users can create quizzes with questions. Regular users can take published quizzes, see their own results, and view the leaderboard.
We have two Filament resources for managing quizzes and questions. Only admin users can access these two resources. Permissions are done via policies.
app/Policies/QuizPolicy.php:
use App\Models\Quiz;use App\Models\User;use Illuminate\Auth\Access\HandlesAuthorization; class QuizPolicy{ use HandlesAuthorization; public function viewAny(User $user): bool { return $user->is_admin; } public function view(User $user, Quiz $quiz): bool { return $quiz->is_published || $user->is_admin; } public function create(User $user): bool { return $user->is_admin; } public function update(User $user, Quiz $quiz): bool { return $user->is_admin; } public function delete(User $user, Quiz $quiz): bool { return $user->is_admin; }}
app/Policies/QuestionPolicy.php:
use App\Models\User;use App\Models\Question;use Illuminate\Auth\Access\HandlesAuthorization; class QuestionPolicy{ use HandlesAuthorization; public function viewAny(User $user): bool { return $user->is_admin; } public function view(User $user, Question $question): bool { return $user->is_admin; } public function create(User $user): bool { return $user->is_admin; } public function update(User $user, Question $question): bool { return $user->is_admin; } public function delete(User $user, Question $question): bool { return $user->is_admin; }}
The question form is extracted to a separate method for reuse in the quiz resource. When creating a new question, you can also select a quiz in the QuestionResource
on the edit page.
app/Filament/Resources/QuestionResource.php:
use App\Models\Question;use Filament\Forms;use Filament\Forms\Form;use Filament\Resources\Resource; class QuestionResource extends Resource{ protected static ?string $model = Question::class; protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; public static function form(Form $form): Form { return $form ->schema(array_merge( static::questionForm(), [ Forms\Components\Select::make('quiz_id') ->multiple() ->columnSpanFull() ->visibleOn('edit') ->relationship('quizzes', 'title') ]) ); } // ...
Next, we will build: