代码之家  ›  专栏  ›  技术社区  ›  Ahmad Badpey

为在Laravel中扩展的模型中的主键定义别名

  •  0
  • Ahmad Badpey  · 技术社区  · 7 年前

    我有一个 Stuff 模型如下:

    class Stuff extends Model
    {
        protected $primaryKey = 'stuff_id';
        protected $fillable   = ['stuff_id' , 'title' , 'desc'];
        protected $dates = ['deleted_at'];
    }
    

    另一方面,有一个 Product 模型扩展自 东西 模型如下:

    class Product extends Stuff 
    {
        protected $fillable   = ['quantity' , 'picture'];
    }
    

    如你所见,因为 产品 扩展自 东西 和的主键 东西 stuff_id ,任何我想打电话给 产品 实例和需要打印的ID应使用 $product->stuff_id 我想用一个更清楚的名字 $product->product_id .

    是否有任何方法可以在解释为 物品编号 在数据库上运行查询时在后端。

    3 回复  |  直到 7 年前
        1
  •  2
  •   Quezler    7 年前

    转向 product_id 化名为 stuff_id :

    ...
    $product->product_id // resolves to $product->stuff_id
    ...
    public function getProductIdAttribute(): int
    {
        return $this->stuff_id;
    }
    ...
    
        2
  •  1
  •   Quezler    7 年前

    而不是使用 $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;
    }
    
        3
  •  1
  •   Oluwatobi Samuel Omisakin    7 年前

    使用全局范围:

    //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

    推荐文章