我有一个像这样的
Stuff
模型:
class Stuff extends Model
{
protected $primaryKey = 'stuff_id';
protected $fillable = ['stuff_id' , 'title' , 'desc'];
protected $dates = ['deleted_at'];
}
另一方面,有一个
Product
模型是从 Stuff
模型扩展而来的,如下所示:
class Product extends Stuff
{
protected $fillable = ['quantity' , 'picture'];
}
正如你所看到的,因为
Product
是从 Stuff
扩展而来的,并且 Stuff
的主键是 stuff_id
,任何我想调用 Product
实例并需要打印它的 id 的地方都应该使用 $product->stuff_id
虽然我想使用一个更清晰的名称,例如 $product->product_id
。
有什么方法可以在子模型中定义别名主键,在数据库上运行查询时解释为后端的
stuff_id
。
要将
product_id
变成 stuff_id
的别名:
...
$product->product_id // resolves to $product->stuff_id
...
public function getProductIdAttribute(): int
{
return $this->stuff_id;
}
...
您可以覆盖从该变量读取的函数,而不是使用
$primaryKey
。
在您的
Stuff
模型中,尝试添加以下内容:
/**
* Get the primary key for the model.
*
* @return string
*/
public function getKeyName(): string
{
return [
Stuff::class => 'stuff_id',
Product::class => 'product_id',
][get_class($this)];
}
作为参考,默认行为:(
Illuminate/Database/Eloquent/Model.php
)
/**
* Get the primary key for the model.
*
* @return string
*/
public function getKeyName()
{
return $this->primaryKey;
}
使用全局范围:
//Say ProductScope.php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Schema;
class ProductScope implements Scope
{
protected $model_name;
public function __construct($model_name)
{
$this->model_name = $model_name;
}
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$attr = Schema::getColumnListing($this->model_name);
$attr_ = array_map(function ($item){
return $item === 'stuff_id' ? $item.' as product_id' : $item;
}, $attr);
$builder->select($attr_);
}
}
然后在产品型号中:
use App\Scopes\ProductScope;
class Product extends Stuff
{
protected $table = 'stuffs';
protected $primaryKey = 'stuff_id';
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope(new ProductScope('stuffs'));
}
}
这会将
stuff_id
替换为 product_id