- How does Bouncer integrate with Laravel’s built-in Policies and Gates?
- Bouncer runs *after* Policies and Gates by default (since v1.0.0), ensuring Laravel’s native authorization takes precedence. This prevents conflicts and aligns with Laravel’s design. You can still use both systems together—Bouncer extends them with roles and abilities. For example, a Policy can check basic rules, while Bouncer handles role-based access.
- Can I use Bouncer in a Laravel 10 or older project?
- Yes, but you’ll need to pin to **v1.0.1** via Composer. Bouncer auto-handles legacy Laravel versions (5.2–10) without manual configuration. However, some features (like Laravel 11’s improved Eloquent) may not be fully optimized. Test thoroughly if upgrading later.
- How do I set up multi-tenancy with Bouncer?
- Bouncer supports scoped permissions natively via `Bouncer::scope()`—ideal for SaaS apps. Use `onceTo()` or `removeOnce()` for temporary scopes to avoid leaks. Example: `Bouncer::scope()->onceTo(Tenant::find(1))->allow('edit_posts')`. Ensure your tenant model is registered in the morph map if using custom tables.
- What’s the performance impact of caching in Bouncer?
- Caching was significantly improved in **v1.0.0-rc.4** to avoid adverse effects. Cross-request caching requires `Bouncer::refresh()` post-upgrade to clear stale data. For high-traffic apps, enable caching via `Bouncer::cache()` and monitor memory usage. Disabling caching trades speed for real-time permission checks.
- Do I need to modify my database schema for Bouncer?
- Minimal changes are required. The `permissions` table is auto-created during migration. If using `allowEveryone()`, add nullable `entity_id` and `entity_type` columns. Custom models/tables need morph map registration (one-time migration). Always back up your database before running migrations.
- How do I assign roles and abilities to users or models?
- Use Eloquent-like syntax: `User::find(1)->assignRole('admin')` or `Post::find(1)->allow('publish')`. For bulk assignments, chain methods: `Role::find(1)->allow('edit')->revoke('delete')`. Abilities can be scoped to models (e.g., `Post::allow('edit')`) or global (e.g., `Bouncer::allowEveryone('view')`).
- What happens if I upgrade Laravel 11+ but keep Bouncer v1.0.1?
- Bouncer **v1.0.1** will work but may miss Laravel 11 optimizations (e.g., improved Eloquent). Composer auto-pins to the correct version for your Laravel install. For full features, upgrade Bouncer via `composer require silber/bouncer:^1.0.2`. Test thoroughly after upgrading, especially if using caching or multi-tenancy.
- Are there alternatives to Bouncer for Laravel RBAC?
- Yes, alternatives include **Spatie Laravel-Permission** (more feature-rich but heavier) and **Entrust** (legacy). Bouncer stands out for its **Eloquent-first API**, minimal dependencies, and seamless Laravel integration. Spatie is better for complex hierarchies; Bouncer excels in simplicity and performance. Choose based on whether you need nested roles (Spatie) or lightweight RBAC (Bouncer).
- How do I test Bouncer’s authorization logic in PHPUnit?
- Mock the `Bouncer` facade or use `Bouncer::fake()` to simulate permissions. Example: `Bouncer::shouldReceive('userCan')->andReturn(true)`. Test both positive and negative cases (e.g., `expectException(AuthorizationException)`). For model abilities, test with `Post::find(1)->can('edit')`. Use Laravel’s `actingAs()` for user context.
- Can Bouncer replace my existing Policies and Gates entirely?
- Yes, but it’s often better to use them together. Bouncer runs *after* Policies/Gates, so you can phase out Gates by migrating logic to roles/abilities. Start by replacing simple checks (e.g., `Gate::denyIf()`) with `Bouncer::denyIf()`. For complex workflows, keep Policies for model-specific logic and use Bouncer for role-based rules.