Определить псевдоним для первичного ключа в модели, которая расширена в laravel

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

или просто иметь $primaryKey = 'product_id' на модели Product?

Quezler 21.05.2018 10:58

и, чтобы опубликовать более определенный ответ, не могли бы вы показать пример кода того, как вы представляете, как вы будете обрабатывать данные, если бы гипотетически код за кулисами уже работал?

Quezler 21.05.2018 11:05

Вы думали о глобальных масштабах? laravel.com/docs/5.4/eloquent#query-scopes

Oluwatobi Samuel Omisakin 21.05.2018 11:12

@OluwatobiSamuelOmisakin, не могли бы вы объяснить больше в качестве ответа на примере?

A.B.Developer 21.05.2018 11:15

@ A.B.Developer Я использовал Scope.

Oluwatobi Samuel Omisakin 21.05.2018 12:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
5
541
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вместо использования $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.

A.B.Developer 21.05.2018 11:07

Ах, в таком случае проверьте мой другой ответ:

Quezler 21.05.2018 11:09
Ответ принят как подходящий

Чтобы превратить 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.

Другие вопросы по теме