问题描述
我目前正在开发一个 Laravel PHP 项目。在这种情况下,应创建一个包含国家/地区的表。该表中有三个字段:一个名为 country_code
的简短国家代码列以及 country_name_de
和 country_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 将填充模型表的相应字段。