Skip to content

Commit 14e2911

Browse files
authored
Organisations (#3)
* Create Organisation model (with factory and seeder) * Link User and Organisation models * Create User/Organisation relationship for current organisation * Create pivot relationship for User belonging to Organisation * Add Composer script for running tests with coverage
1 parent d5d60ea commit 14e2911

13 files changed

+179
-39
lines changed

.env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ APP_KEY=base64:jpd/wy450S/8N0y6OfuRoZ8yS3AWEzrbkSgo08djF4w=
44
APP_DEBUG=true
55
APP_URL=http://laravel-inertia-template.test
66

7+
SEED_ADMIN_EMAIL=admin@laravel-inertia-template.test
8+
79
LOG_CHANNEL=stack
810
LOG_DEPRECATIONS_CHANNEL=null
911
LOG_LEVEL=debug
1012

1113
DB_CONNECTION=mysql
1214
DB_HOST=127.0.0.1
1315
DB_PORT=3306
14-
DB_DATABASE=laravel
16+
DB_DATABASE=laravel_inertia_template
1517
DB_USERNAME=root
1618
DB_PASSWORD=
1719

app/Models/Organisation.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Factories\HasFactory;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class Organisation extends Model
9+
{
10+
use HasFactory;
11+
12+
protected $fillable = [
13+
'name',
14+
'user_id',
15+
];
16+
17+
public function user()
18+
{
19+
return $this->belongsTo(User::class)->withDefault();
20+
}
21+
22+
public function users()
23+
{
24+
return $this->belongsToMany(User::class)->withTimestamps();
25+
}
26+
}

app/Models/User.php

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,49 @@
33
namespace App\Models;
44

55
// use Illuminate\Contracts\Auth\MustVerifyEmail;
6+
7+
use Illuminate\Database\Eloquent\Casts\Attribute;
68
use Illuminate\Database\Eloquent\Factories\HasFactory;
79
use Illuminate\Foundation\Auth\User as Authenticatable;
810
use Illuminate\Notifications\Notifiable;
11+
use Illuminate\Support\Facades\Hash;
912
use Laravel\Sanctum\HasApiTokens;
1013

1114
class User extends Authenticatable
1215
{
13-
use HasApiTokens, HasFactory, Notifiable;
16+
use HasApiTokens;
17+
use HasFactory;
18+
use Notifiable;
1419

15-
/**
16-
* The attributes that are mass assignable.
17-
*
18-
* @var array<int, string>
19-
*/
2020
protected $fillable = [
2121
'name',
2222
'email',
2323
'password',
2424
];
2525

26-
/**
27-
* The attributes that should be hidden for serialization.
28-
*
29-
* @var array<int, string>
30-
*/
3126
protected $hidden = [
3227
'password',
3328
'remember_token',
3429
];
3530

36-
/**
37-
* The attributes that should be cast.
38-
*
39-
* @var array<string, string>
40-
*/
4131
protected $casts = [
4232
'email_verified_at' => 'datetime',
4333
];
34+
35+
protected function password(): Attribute
36+
{
37+
return Attribute::make(
38+
set: fn ($value) => Hash::make($value),
39+
);
40+
}
41+
42+
public function organisations()
43+
{
44+
return $this->hasMany(Organisation::class);
45+
}
46+
47+
public function currentOrganisation()
48+
{
49+
return $this->belongsTo(Organisation::class);
50+
}
4451
}

composer.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,9 @@
5050
"npm install",
5151
"npm run prod"
5252
],
53-
"build:test": [
54-
"composer install --no-interaction"
55-
],
53+
"build:test": "composer install --no-interaction",
5654
"test": "php artisan test --parallel --stop-on-failure",
55+
"test:coverage": "XDEBUG_MODE=coverage php artisan test --parallel --coverage --min=85",
5756
"post-autoload-dump": [
5857
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
5958
"@php artisan package:discover --ansi"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Database\Factories;
4+
5+
use App\Models\User;
6+
use Illuminate\Database\Eloquent\Factories\Factory;
7+
8+
/**
9+
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Organisation>
10+
*/
11+
class OrganisationFactory extends Factory
12+
{
13+
public function definition()
14+
{
15+
return [
16+
'name' => $this->faker->company,
17+
'user_id' => User::factory(),
18+
];
19+
}
20+
}

database/factories/UserFactory.php

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,17 @@
1010
*/
1111
class UserFactory extends Factory
1212
{
13-
/**
14-
* Define the model's default state.
15-
*
16-
* @return array<string, mixed>
17-
*/
1813
public function definition()
1914
{
2015
return [
21-
'name' => fake()->name(),
22-
'email' => fake()->unique()->safeEmail(),
16+
'name' => fake()->name(),
17+
'email' => fake()->unique()->safeEmail(),
2318
'email_verified_at' => now(),
24-
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
25-
'remember_token' => Str::random(10),
19+
'password' => '12345',
20+
'remember_token' => Str::random(10),
2621
];
2722
}
2823

29-
/**
30-
* Indicate that the model's email address should be unverified.
31-
*
32-
* @return static
33-
*/
3424
public function unverified()
3525
{
3626
return $this->state(fn (array $attributes) => [

database/migrations/2014_10_12_000000_create_users_table.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use App\Models\Organisation;
34
use Illuminate\Database\Migrations\Migration;
45
use Illuminate\Database\Schema\Blueprint;
56
use Illuminate\Support\Facades\Schema;
@@ -15,6 +16,7 @@ public function up()
1516
{
1617
Schema::create('users', function (Blueprint $table) {
1718
$table->id();
19+
$table->foreignIdFor(Organisation::class, 'current_organisation_id')->nullable();
1820
$table->string('name');
1921
$table->string('email')->unique();
2022
$table->timestamp('email_verified_at')->nullable();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
use App\Models\User;
4+
use Illuminate\Database\Migrations\Migration;
5+
use Illuminate\Database\Schema\Blueprint;
6+
use Illuminate\Support\Facades\Schema;
7+
8+
return new class extends Migration
9+
{
10+
/**
11+
* Run the migrations.
12+
*
13+
* @return void
14+
*/
15+
public function up()
16+
{
17+
Schema::create('organisations', function (Blueprint $table) {
18+
$table->id();
19+
$table->foreignIdFor(User::class)->nullable()->constrained();
20+
$table->string('name');
21+
$table->timestamps();
22+
});
23+
}
24+
25+
/**
26+
* Reverse the migrations.
27+
*
28+
* @return void
29+
*/
30+
public function down()
31+
{
32+
Schema::dropIfExists('organisations');
33+
}
34+
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
use App\Models\Organisation;
4+
use App\Models\User;
5+
use Illuminate\Database\Migrations\Migration;
6+
use Illuminate\Database\Schema\Blueprint;
7+
use Illuminate\Support\Facades\Schema;
8+
9+
return new class () extends Migration {
10+
/**
11+
* Run the migrations.
12+
*
13+
* @return void
14+
*/
15+
public function up()
16+
{
17+
Schema::create('organisation_user', function (Blueprint $table) {
18+
$table->id();
19+
$table->foreignIdFor(Organisation::class);
20+
$table->foreignIdFor(User::class);
21+
$table->timestamps();
22+
});
23+
}
24+
25+
/**
26+
* Reverse the migrations.
27+
*
28+
* @return void
29+
*/
30+
public function down()
31+
{
32+
Schema::dropIfExists('organisations_users');
33+
}
34+
};

database/seeders/DatabaseSeeder.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public function run()
1313
{
1414
$this->call([
1515
UsersSeeder::class,
16+
OrganisationsSeeder::class,
1617
]);
1718
}
1819
}

0 commit comments

Comments
 (0)