Penggunaan Dan Study Kasus Pada Eloquent Atribut Casting
Eloquent Atribut Castable adalah salah satu fitur Laravel yang powerful. Beberapa orang menggunakannya secara religius sementara yang lain cenderung menjauh darinya. Tutorial ini akan menjelaskan beberapa contoh usersan yang berbeda dan, yang paling penting, mengapa Anda harus menggunakannya.
Dalam tutorial ini, Anda dapat membuat proyek Laravel baru atau menggunakan yang sudah ada. Jangan ragu untuk mengikuti saya dengan saya atau jika Anda ingin membaca dan mengingat-tidak apa-apa juga. Hal penting yang harus disingkirkan mulai sekarang adalah seberapa bagus eloquent casts.
Mari kita mulai dengan contoh pertama, mirip dengan yang ada di dokumentasi Laravel. Dokumentasi Laravel menunjukkan cara mendapatkan alamat users, tetapi juga menggunakan model. Sekarang bayangkan jika ini adalah kolom JSON users, atau model dari fakta itu. Anda bisa mendapatkan dan mengonfigurasi beberapa data dan menambahkannya agar berfungsi sesuai kebutuhan. Anda perlu menginstal paket bernama Laravel Castable Data Transfer Object oleh Jess Archer. Itu dapat diinstal menggunakan perintah composer berikut:
composer require jessarcher/laravel-castable-data-transfer-object
Sekarang setelah Anda menginstal ini, mari kita desain kelas Castable.
namespace App\Casts;
use JessArcher\CastableDataTransferObject\CastableDataTransferObject;
class Address implements CastableDataTransferObject
{
public string $nameOrNumber,
public string $streetName,
public string $localityName,
public string $town,
public string $county,
public string $postalCode,
public string $country,
}
Ada kelas PHP yang mengextends CastableDataTransferObject. Ini memungkinkan Anda untuk menandai properti dan jenisnya serta menangani semua opsi pengambilan dan konfigurasi di latar belakang. Paket ini menggunakan paket Spatie yang secara internal disebut Data Transfer Object yang sangat populer di masyarakat. Jadi jika Anda ingin memperpanjang ini, Anda dapat:
namespace App\Casts;
use JessArcher\CastableDataTransferObject\CastableDataTransferObject;
class Address implements CastableDataTransferObject
{
public string $nameOrNumber,
public string $streetName,
public string $localityName,
public string $town,
public string $county,
public string $postalCode,
public string $country,
public function formatString(): string
{
return implode(', ', [
"$this->nameOrNumber $this->streetName",
$this->localityName,
$this->townName,
$this->county,
$this->postalCode,
$this->country,
]);
}
}
Ada kelas Address yang mengextends kelas CastableDataTransferObject dari paket. Ini menangani semua pengambilan data dan konfigurasi ke database. Sekarang Anda memiliki semua properti yang ingin Anda simpan. Ini adalah adress dengan format UK . Akhirnya, saya menambahkan metode untuk membantu memformat address ini sebagai string. Jika Anda ingin menampilkan ini dalam bentuk antarmuka users apa pun. Anda dapat melangkah lebih jauh dengan validasi postcode menggunakan regex atau API, tetapi itu dapat mengurangi inti dari tutorial.
Mari kita beralih ke contoh lain: uang. Kita semua mengerti uang. Kami tahu bahwa Anda dapat membelanjakan uang untuk koin terkecil dan uang kertas yang lebih besar. Dengan kata lain, misalkan Anda memiliki toko e-niaga yang menyimpan barang (ini adalah toko sederhana sehingga Anda tidak perlu khawatir tentang fluktuasi) dan harga yang disimpan dalam penyebut mata uang terkecil. jika di Inggris, menyebutnya pence. Namun, jika satu sen di Amerika Serikat. Pendekatan umum untuk menyimpan nilai moneter dalam database untuk menghindari masalah aritmatika floating point. Sekarang mari kita desain cast untuk kolom harga ini menggunakan paket php moneyphp/money kali ini.
namespace App\Casts;
use Money\Currency;
use Money\Money;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class Money implements CastsAttributes
{
public function __construct(
protected int $amount,
) {}
public function get($model, string $key, $value, array $attributes)
{
return new Money(
$attributes[$this->amount],
new Currency('GBP'),
);
}
public function set($model, string $key, $value, array $attributes)
{
return [
$this->amount => (int) $value->getAmount(),
$this->curreny => (string) $value->getCurrency(),
];
}
}
Oleh karena itu, kelas ini tidak menggunakan paket DTO dan sebaliknya mengembalikan instance baru dengan metodenya sendiri. Di konstruktor, berikan jumlahnya. Saat mengambil dan mengatur jumlahnya, masukkan ke dalam array untuk penyimpanan di database, atau parsing array dan kembalikan objek Uang baru. Tentu saja, Anda dapat menjadikan ini sebagai objek transfer data dan memiliki sedikit lebih banyak kendali atas bagaimana uang Anda ditangani. Namun, library money php cukup teruji dan dapat diandalkan. Sejujurnya, saya tidak sering melakukannya secara berbeda.
Mari kita pergi ke contoh baru. Saya memiliki aplikasi CRM dan ingin menghemat jam kerja atau hari kerja. Setiap bisnis harus dapat menandai hari kerja, tetapi hanya dengan cara sederhana yang benar atau salah. Jadi kamu bisa membuat cast baru, tapi buat dulu class untuk cast, seperti class Money PHP di atas.
namespace App\DataObjects;
class Open
{
public function __construct(
public readonly bool $monday,
public readonly bool $tuesday,
public readonly bool $wednesday,
public readonly bool $thursday,
public readonly bool $friday,
public readonly bool $saturday,
public readonly bool $sunday,
public readonly array $holidays,
) {}
}
Di tempat pertama, ini tidak masalah. Jika hari kerja Anda setiap hari dan Anda memiliki banyak hari yang dihitung sebagai hari libur, Anda hanya ingin menyimpannya. Kemudian Anda bisa mendesain pemerannya.
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class OpenDaysCast implements CastsAttributes
{
public function __construct(
public readonly array $dates,
) {}
public function set($model, string $key, $value, array $attributes)
{
return $this->dates;
}
public function get($model, string $key, $value, array $attributes)
{
return Open::fromArray(
dates: $this->dates,
);
}
}
Konstruktor menerima array tanggal untuk menyederhanakan penyimpanan (walaupun Anda perlu memvalidasi input Anda dengan benar di sini). Kemudian, saat mengambil data dari database, berikan tanggal dan buat objek Open baru. Namun, kita memanggil metode fromArray yang belum kita buat, jadi mari kita desain di sini.
public static function fromArray(array $dates): static
{
return new static(
monday: (bool) data_get($dates, 'monday'),
tuesday: (bool) data_get($dates, 'tuesday'),
wednesday: (bool) data_get($dates, 'wednesday'),
thursday: (bool) data_get($dates, 'thursday'),
friday: (bool) data_get($dates, 'friday'),
saturday: (bool) data_get($dates, 'saturday'),
sunday: (bool) data_get($dates, 'sunday'),
holidays: (array) data_get($dates, 'holidays'),
);
}
Oleh karena itu, gunakan data_get helper Laravel untuk membuat objek Open secara manual. Ini sangat nyaman dan memastikan Anda melakukan casting ke jenis yang benar. Sekarang ketika Anda menjalankan query, Anda memiliki izin berikut:
$business = Business:query()->find(1);
// Is this business open on mondays?
$business->open->monday; // true|false
// Is the business open on tuesdays?
$business->open->tuesday; // true|false
// What are the busines holiday dates?
$business->open->holidays; // array
Seperti yang Anda lihat, membuat ini sangat mudah dibaca membuat pengalaman pengembang logis dan lugas. Lalu bisakah saya mengextends ini untuk menambahkan metode seperti yang dibuka hari ini?
public function today(): bool
{
$date = now();
$day = strtolower($date->englishDayOfWeek());
if (! $this->$day) {
return false;
}
return ! in_array(
$date->toDateString(),
$this->holidays,
);
}
Oleh karena itu, metode ini mungkin membuat asumsi kecil bahwa hari libur disimpan dalam string tanggal, tetapi logikanya adalah sebagai berikut: Dapatkan hari dalam seminggu dalam bahasa Inggris, yang merupakan nama properti. Jika hari salah, ia mengembalikan false. Namun, Anda juga perlu memeriksa hari libur. Jika string tanggal saat ini tidak ada dalam array hari libur, string tersebut terbuka. Jika tidak, itu ditutup.
Oleh karena itu, Anda dapat menggunakan metode hari ini dalam pemeran untuk melihat apakah bisnis Anda terbuka.
$business = Business:query()->find(1);
// Is the business open today?
$business->open->today();
Seperti yang dapat Anda bayangkan, Anda dapat menambahkan banyak metode untuk melihat lebih dari satu hal dan menambahkan cara untuk menampilkan informasi ini dengan benar.
berikut yang bisa saya bagikan kepada teman-teman, terimakasih dan selamat mencoba :)