Creating teams
Create a team from a CreateTeamData DTO through the facade — it seats the owner and is recorded by Teams::fake():
use RoundlyConsulting\Teams\DataTransferObjects\CreateTeamData;
use RoundlyConsulting\Teams\Facades\Teams;
$team = Teams::create(new CreateTeamData(
name: 'Acme Inc',
isPublic: false, // default false
owner: $user, // default null — added as a member with the owner role
meta: ['plan' => 'pro'], // default []
));With an owner, the team is stamped with the owner morph and the owner is added as a member with the roles.owner role (owner by default). Without one, the team has no owner and no initial member. Everything after creation goes through Teams::for($team) — see The Teams facade.
Creating a team directly
Team is a regular Eloquent model, so Team::create() works too — it creates the row only, without an owner member:
use RoundlyConsulting\Teams\Models\Team;
$team = Team::create([
'name' => 'Acme Design',
'is_public' => false,
'meta' => ['pricing' => 'per_member'],
]);
// Scopes
Team::query()->public()->get(); // only public teams
Team::query()->withMember($user)->get(); // teams the model belongs toTeam relations
$team->members(); // HasMany<Member>
$team->invites(); // HasMany<Invite>
$team->joinRequests(); // HasMany<JoinRequest>
$team->teamRoles(); // HasMany<TeamRole> — per-team role overrides
$team->owner(); // MorphTo — the owning model (nullable)
$team->name; // string
$team->is_public; // bool
$team->meta; // Collection, cast from JSONFacade lookups
Teams::roles()->find('admin'); // ?Role
Teams::roles()->all(); // array<string, Role>
Teams::permissions()->all(); // array<string, Permission>Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.