определить псевдоним для первичного ключа в модели, которая расширена в laravel - PullRequest
0 голосов
/ 21 мая 2018

У меня есть 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 в серверной части при выполнении запросов к базе данных.

Ответы [ 3 ]

0 голосов
/ 21 мая 2018

Чтобы превратить product_id в псевдоним stuff_id:

...
$product->product_id // resolves to $product->stuff_id
...
public function getProductIdAttribute(): int
{
    return $this->stuff_id;
}
...
0 голосов
/ 21 мая 2018

Использование 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

0 голосов
/ 21 мая 2018

Вместо использования $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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...