如何确保列名在 Laravel 中相等?

问题描述

我目前正在开发一个 Laravel PHP 项目。在这种情况下,应创建一个包含国家/地区的表。该表中有三个字段:一个名为 country_code 的简短国家代码列以及 country_name_decountry_code_en 列中的德语和英语国家名称。 这导致以下模型类:

<?PHP

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

/**
 * Class Country
 * @package App\Models
 * @mixin \Illuminate\Database\Eloquent\Builder
 */
final class Country extends Model
{
    use HasFactory;

    protected $table = 'countries';

    protected $primaryKey = 'country_code';
    protected $keyType = 'string';
    public $incrementing = false;
    public $timestamps = false;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    public $fillable = [
        'country_code','country_name_de','country_name_en',];


    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
    ];

    public static function getCountryCodeColumnName(): string
    {
        return 'country_code';
    }

    public static function getGermanCountryNameColumnName(): string
    {
        return 'country_name_de';
    }

    public static function getEnglishCountryNameColumnName(): string
    {
        return 'country_name_en';
    }

    public static function getTableName(): string
    {
        return 'countries';
    }


}

此外,还有一个播种器将所需的值写入数据库。播种机当然需要列名来插入数据。目前我在播种机中使用这种方法

public function run()
{
    // Load CSV-file country_codes.csv
    if (($handle = fopen(storage_path('app/country_codes.csv'),'r')) !== FALSE) {
        while (($data = fgetcsv($handle)) !== FALSE) {
            $country = array(
                Country::getCountryCodeColumnName()         => $data[0],Country::getGermanCountryNameColumnName()   => $data[1],Country::getEnglishCountryNameColumnName()  => $data[2],);
            Country::create($country);
        }
    }
    fclose($handle);
}

使用“常量”/getter 来确保在引用表的特定列的任何类中没有错字是一种很好的风格吗?是否可以将这种样式也用于迁移,或者是否有任何问题?

解决方法

您的迁移不应依赖于任何 Model 引用。

实际上,如果您在模型中设置了 $fillable,则不需要使用 getter,因为 Eloquent 会为您做到这一点。 为确保正确性,您可以通过以下方式验证您的表是否具有必需的列:

$columns = Schema::getColumnListing('countries'); 
// check if $columns have all your required column

以不同的方式,您可以这样做:

while (($data = fgetcsv($handle)) !== FALSE) {
  $country = new Country();
  $country->setCountryCode = $data[0];
  $country->setCountryNameDe = $data[0];
  $country->setCountryNameEn = $data[1];
  $country->save();
}

这样,您的模型中就不需要那些样板方法了,eloquent 将填充模型表的相应字段。