У меня модель 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 и где нужно распечатать его идентификатор, следует использовать $product->stuff_id, в то время как я хочу использовать более четкое имя для этого, например $product->product_id.
Есть ли способ определить первичный ключ псевдонима в дочерней модели, который интерпретируется в stuff_id в бэкэнде при выполнении запросов к базе данных.
и, чтобы опубликовать более определенный ответ, не могли бы вы показать пример кода того, как вы представляете, как вы будете обрабатывать данные, если бы гипотетически код за кулисами уже работал?
Вы думали о глобальных масштабах? laravel.com/docs/5.4/eloquent#query-scopes
@OluwatobiSamuelOmisakin, не могли бы вы объяснить больше в качестве ответа на примере?
@ A.B.Developer Я использовал Scope.






Вместо использования $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;
}
Обратите внимание, что поля product_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;
}
...
Использование Global Scope:
//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.
или просто иметь
$primaryKey = 'product_id'на модели Product?