• Czas czytania ~6 min
  • 20.09.2022

Model danych jest jedną z najważniejszych części każdej aplikacji Laravel. Wiele systemów zostanie zaprojektowanych w oparciu o ten model danych, więc jest to zazwyczaj jedna z pierwszych rzeczy, do których podchodzimy podczas projektowania. Niektórzy z nas robią to od lat i mają dobry pomysł, jak podejść do tego -, podczas gdy inni mogą jeszcze nie być do tego przyzwyczajeni. Dowiedziałem się o modelowaniu danych, zanim dowiedziałem się, że istnieje coś takiego jak framework, projektując mój model danych w instrukcjach CREATE TABLE.

W tym samouczku omówię, w jaki sposób można podejść do danych modelowanie w twojej aplikacji Laravel - i kilka wskazówek na temat tego, co uważam za pomocne.

Ten samouczek jest pierwszą częścią trwającej serii, w której powinniśmy zbudować cały działający system gotowy do produkcji od początku do końca. Innymi słowy, z IDE na serwer.

Co zamierzamy zbudować? Cieszę się, że pytałeś. Mógłbym tutaj zrobić coś prostego, na przykład aplikację ToDo lub blog - ale nie nauczysz się z tego niczego użytecznego. Zamiast tego zamierzamy zbudować coś wyjątkowego i ekscytującego z kilkoma ruchomymi częściami, które pod koniec tego wszystkiego powinny być czymś wartym zachodu. Niedawno poszedłem na polowanie na system rezerwacji sal konferencyjnych i szczerze mówiąc, miałem trudności ze znalezieniem takiego. Więc będziemy budować open source w Laravel. Celem jest zbudowanie czegoś w sposób, którego oczekiwalibyśmy w środowisku produkcyjnym, a jednocześnie oferowanie czegoś za darmo.

Co zostanie uwzględnione w ramach zarządzania salą konferencyjną Platforma? To nie będzie aplikacja w stylu SaaS, w której każdy może się zarejestrować i z niej korzystać, będzie to coś, co sam pobierzesz i uruchomisz. Na tym etapie kluczowe jest myślenie o tych decyzjach, ponieważ wpływają one na dużą część naszego modelu danych.

Sposób, w jaki chcemy, aby nasza aplikacja działała, to na początku proces konfiguracji, który ma miejsce tam, gdzie jest to ważne można przejść do instrukcji konfiguracji. Do platformy można zaprosić ogólnego administratora systemu, aby umożliwić mu zapraszanie użytkowników i konfigurowanie systemu zgodnie z wymaganiami.

Let'Pierwsze spojrzenie na nasz model użytkownika, który nie jest taki sam jak typowy model użytkownika Laravela. Ostatecznie będziemy refaktoryzować nasz model użytkownika do pakietu, który kontroluje dla nas uwierzytelnianie - ale na razie zachowamy prostotę.

Nasz model użytkownika będzie wymagał dodatkowej kolumny o nazwie typ, który będzie Enum. Zachowamy kolumnę weryfikacji adresu e-mail, aby skuteczniej weryfikować użytkowników w środowisku opartym na interfejsie API.

Migracja użytkowników powinna teraz wyglądać następująco:

public function up(): void
{
    Schema::create('users', function (Blueprint $table): void {
        $table->id();
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
 
        $table->string('type')->default(Type::ADMIN->value);
 
        $table->timestamps();
    });
}

Jak widać, jest to stosunkowo standardowe dla aplikacji Laravela innej niż dodatkowa kolumna, którą chcemy dodać. Od tego momentu możemy zacząć patrzeć na fabrykę modeli, którą musimy stworzyć dla naszych użytkowników.

final class UserFactory extends Factory
{
    protected $model = User::class;
 
    public function definition(): array
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => Hash::make(
                value: 'password',
            ),
            'type' => Type::ADMIN,
        ];
    }
 
    public function unverified(): UserFactory
    {
        return $this->state(
            state: fn (array $attributes) => ['email_verified_at' => null],
        );
    }
 
    public function type(Type $type): UserFactory
    {
        return $this->state(
            state: fn (array $attributes) => ['type' => $type],
        );
    }
}

Dodajemy domyślny typ, który chcemy zastosować do dowolnego utworzonego użytkownika. Tworzymy jednak również metodę pomocniczą, dzięki której możemy dostosować typ użytkownika, którego chcemy utworzyć.

To prowadzi nas do modelu i zmian, które chcemy do niego zastosować. W modelu elokwentnym wprowadzono minimalne zmiany, inne niż dodatkowa kolumna do wypełnienia i zapewnienie, że możemy rzutować właściwość type na nasz Enum.

final class User extends Authenticatable implements MustVerifyEmail
{
    use HasApiTokens;
    use HasFactory;
    use Notifiable;
 
    protected $fillable = [
        'name',
        'email',
        'password',
        'type',
    ];
 
    protected $hidden = [
        'password',
    ];
 
    protected $casts = [
        'type' => Type::class,
        'email_verified_at' => 'datetime',
    ];
}

Zanim przejdziemy do szczegółów, prawdopodobnie zastanawiasz się nad samym Enum i jego dostępnymi opcjami.

enum Type: string
{
    case ADMIN = 'admin';
    case OFFICE_MANAGER = 'office manager';
    case STAFF = 'staff';
}

Nasza aplikacja będzie się składać z następujących elementów:

  • Admins; are people who are in charge of configuring the system and managing the system.
  • Office Managers; are people who have the authority to override bookings on the system.
  • Staff; are people on the system who have the ability to book the meeting rooms.

Przepływ pracy polega na tym, że administratorzy zapraszają menedżerów biura, którzy mogą następnie rozpocząć wdrażanie członków personelu na platformę.

Oprócz modelowania reprezentacji danych w bazie danych, potrzebujemy również sposobu na zrozumienie danych wewnątrz aplikacji. Możemy to osiągnąć za pomocą obiektu transferu domeny, w skrócie DTO.

Zaczynamy od sprawdzenia, co zawiera baza danych dla tego modelu danych, a następnie ustalenia, co jest potrzebne w całej aplikacji . Jednak czasami musimy mieć możliwość tworzenia tych obiektów, zanim pojawią się w bazie danych.

final class User implements DataObjectContract
{
    public function __construct(
        private readonly string $name,
        private readonly string $email,
        private readonly Type $type,
    ) {}
 
    public function toArray(): array
    {
        return [
            'name' => $this->name,
            'email' => $this->email,
            'type' => $this->type,
        ];
    }
}

Abyśmy mogli utworzyć lub zaprosić potencjalnego użytkownika lub dowiedzieć się czegoś o użytkowniku, potrzebujemy dostępu do ich imienia i nazwiska, adresu e-mail i typu. Obejmuje to większość przypadków użycia, ponieważ zasoby są w większości identyfikowane za pomocą powiązania modelu trasy.

Mamy teraz sposób na zrozumienie danych poprzez bazę danych i aplikację. Jest to proces, który powtarzam w tej kolejności, budując dowolną aplikację Laravela. Daje mi abstrakcję od modelu do przekazania, nie będąc prostą tablicą, jednocześnie wymuszając poziom bezpieczeństwa typu we właściwościach. Czasami potrzebuję bezpośredniego dostępu do właściwości, ale nie tak często, a kiedy to robię, zamiast zmieniać właściwości, utworzyłbym akcesor' widoczność.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297