Mencegah Data Type Enum Di Eloquent Laravel - CRUDPRO

Mencegah Data Type Enum Di Eloquent Laravel

Mencegah Data Type Enum Di Eloquent Laravel

Di aplikasi Anda, pengguna mungkin memiliki peran yang berbeda seperti Admin, Penulis, penerbit, dll. atau kamar hotel mungkin memiliki status yang berbeda seperti Gratis, Dipesan, Dipesan.

ada dua cara yang mungkin untuk menerapkan ini:

a) menggunakan kolom enum: seperti yang Anda ketahui, bukan ide yang baik untuk menggunakan tipe data enum dalam database. anda dapat dengan mudah google untuk enum kontra.

b) membuat tabel statis: jika kita membuat tabel untuk setiap tipe data enum, kita akhirnya memiliki banyak tabel kecil dengan hanya beberapa baris, terutama dalam aplikasi skala besar. Tidak banyak operasi CRUD yang akan dilakukan pada tabel ini, mereka adalah tabel kecil yang hampir konstan.

tapi ada cara yang lebih baik…

Membuat array konstan dalam Model alih-alih membangun tabel database kecil

seperti judulnya, Anda dapat membuat array konstan kecil dalam model fasih dan menggunakannya sebagai ganti tabel database kecil.

class User extends Model
{   /**
   * Users' roles
   * 
   * @var array
   */
   public const ROLES = [
      'admin'     => 1,
      'author'    => 2
   ];}

Kamu juga dapat memiliki fungsi seperti getRole() dan metode lain seperti:

/**
* determins if the user role is Admin
* @return bool
*/
public function isAdmin()
{
   return Auth::user()->role == self::ROLES['admin'];
}/**
* determins if the user role is Author
* @return bool
*/
public function isAuthor()
{
   return Auth::user()->role == self::ROLES['author'];
}

ini yang biasa saya gunakan di aplikasi saya, tetapi ada cara yang lebih baik…

melarikan diri Enum menggunakan pengakses & mutator Eloquent

Di Laravel, Anda dapat memiliki penyetel dan pengambil khusus dalam Model yang fasih.

untuk mempelajari lebih lanjut tentang cara kerja accessor & mutator yang fasih, baca ini:

class User extends Model
{   /**
   * Users' roles
   * 
   * @var array
   */
   public const ROLES = [
      1 => 'admin',
      2 => 'author'
   ];   /**
   * returns the id of a given role
   *
   * @param string $role  user's role
   * @return int roleID
   */
   public static function getRoleID($role)
   {
      return array_search($role, self::ROLES);
   }   /**
   * get user role
   */
   public function getRoleAttribute()
   {
      return self::ROLES[ $this->attributes['role_id'] ];
   }   /**
   * set user role
   */
   public function setRoleAttribute($value)
   {
      $roleID = self::getRoleID($value);      if ($roleID) {
         $this->attributes['role_id'] = $roleID;
      }
   }

}

Itu dia. dengan melakukan ini, Anda melihat angka di database dan di sisi lain di aplikasi, Anda melihat kata-kata seperti 'admin' dan 'penulis'.

mari kita lihat contohnya:

$user = \App\User::first();
echo $user->role;          // output: 'admin'echo $user->role_id;       // output: 1
$user->role = 'author';echo $user->role;          // output: 'author'

atau

class User extends Model
{   function isAdmin()
   {
      return $this->role == 'admin';
   }

}

mengagumkan, bukan? Anda dapat berperilaku $user-role seperti ketika ada string yang disimpan dalam database.

Perhatikan bahwa ketika Anda menanyakan database, Anda harus meneruskan id pengguna yang sebenarnya:

/**
* get the user by id and role
*
* @param  integer $id userID
* @param  string $role userRole
* @return App\User
*/
public static function findUser($id, $role)
{
   
   return self::where('role', self::getRoleID($role) )->findOrFail($id);
}

seperti yang Anda lihat di atas, Anda harus memberikan id pengguna yang sebenarnya. di kelas Pengguna, Anda dapat menggunakan self::getRoleID() dan di luar kelas Pengguna, misalnya di pengontrol Anda dapat menggunakan \App\User::getRoleID()

Hindari Enum menggunakan ciri-ciri di Laravel atau Lumen

Jika Anda hanya memiliki satu atau dua enum, Anda sebaiknya menggunakan metode sebelumnya. sederhana dan mudah.

Jika tidak, dengan menggunakan suatu sifat, Anda dapat menghindari penulisan banyak pengakses & mutator yang fasih. itu menambah sedikit kerumitan tetapi membuatnya lebih fleksibel dan membuat model Anda lebih bersih dan lebih pendek.

<?phpnamespace App\Traits;use Illuminate\Support\Str;trait EnumTrait
{
    /**
     * Set a given attribute on the model.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return mixed
     */
    public function setAttribute($key, $value)
    {
        if ($enum = self::getEnum($key)) {
            $value = Str::singular($value);
            $id = array_search($value, constant("self::$enum"));
            if ($id) {
                $this->attributes[$key] = $id;
                return $this;
            }
        } else {
            
            return parent::setAttribute($key, $value);
        }
        
    }    /**
     * Get an attribute from the model.
     *
     * @param  string  $key
     * @return mixed
     */
    public function getAttribute($key)
    {
        if ($enum = self::getEnum($key)) {
            return constant("self::$enum")[$this->attributes[$key]];
        }
        
        $keyWithoutIdAtTheEnd = rtrim($key, '_id');
        if(self::getEnum($keyWithoutIdAtTheEnd)) {
            return $this->attributes[$keyWithoutIdAtTheEnd];
        }
        
        return parent::getAttribute($key);
    }    /**
     * Handle dynamic method calls into the model.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public static function __callStatic($method, $parameters)
    {
        $pattern = '/^get(([A-Z][a-z]+)+)I[dD]$/';
        if( preg_match($pattern, $method, $matches) ) {           $key = Str::snake($matches[1]);           if ($enum = self::getEnum($key)) {              $value = strtolower($parameters[0]);              $value = Str::singular($value);
    
              return array_search($value, constant("self::$enum") );           }
        }        return parent::__callStatic($method, $parameters);
    }    /**
     * Get the enum.
     *
     * @param  string  $key
     * @return enum
     */
    public static function getEnum($key)
    {
        return array_search($key, self::$enums);
    }
}

dan dalam modelnya:

use \App\Traits\EnumTrait;class User extends Model
{
   use EnumTrait;   /**
    * The attributes that are enum.
    *
    * @var array
    */
    protected static $enums = [
        'ROLES' => 'role'
    ];  /**
   * Users' roles
   * 
   * @var array
   */
   public const ROLES = [
      'admin'     => 1,
      'author'    => 2
   ];

}

Anda hanya perlu menghubungkan nama atribut ke array di $enums. sifat mengambil sisanya.

kesimpulan

Anda dapat melakukan ini untuk enum apa pun yang muncul di aplikasi Anda. seperti peran pengguna, status kamar hotel, dan sebagainya.

Semoga artikel ini bermanfaat dan jika ada yang kurang jelas dan belum mengerti silahkan tinggalkan pertanyaan anda di kolom komentar ya!