一尘不染

如何在Laravel 5中将组合键放在模型中?

php

我的数据库中有一个带有两个主键(id和language_id)的表,需要将其放入模型中。模型中的默认primaryKey(Laravel
5中的Model.php)是id,我希望primaryKeys将是id和id_language。我尝试将其与数组或带’,’的字符串放在一起,但不起作用。它说我无法将数组转换为String。

请帮忙。

谢谢!


阅读 298

收藏
2020-05-26

共1个答案

一尘不染

我写了这个简单的PHP特性,以使Eloquent能够处理复合键:

<?php

namespace App\Model\Traits; // *** Adjust this to match your model namespace! ***

use Illuminate\Database\Eloquent\Builder;

trait HasCompositePrimaryKey
{
    /**
     * Get the value indicating whether the IDs are incrementing.
     *
     * @return bool
     */
    public function getIncrementing()
    {
        return false;
    }

    /**
     * Set the keys for a save update query.
     *
     * @param  \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    protected function setKeysForSaveQuery(Builder $query)
    {
        foreach ($this->getKeyName() as $key) {
            // UPDATE: Added isset() per devflow's comment.
            if (isset($this->$key))
                $query->where($key, '=', $this->$key);
            else
                throw new Exception(__METHOD__ . 'Missing part of the primary key: ' . $key);
        }

        return $query;
    }

    // UPDATE: From jessedp. See his edit, below.
    /**
     * Execute a query for a single record by ID.
     *
     * @param  array  $ids Array of keys, like [column => value].
     * @param  array  $columns
     * @return mixed|static
     */
    public static function find($ids, $columns = ['*'])
    {
        $me = new self;
        $query = $me->newQuery();
        foreach ($me->getKeyName() as $key) {
            $query->where($key, '=', $ids[$key]);
        }
        return $query->first($columns);
    }
}

将其放置在Traits主模型目录下的目录中,然后可以在任何复合键模型的顶部添加一个简单的单线:

class MyModel extends Eloquent {
    use Traits\HasCompositePrimaryKey; // *** THIS!!! ***

    /**
     * The primary key of the table.
     * 
     * @var string
     */
    protected $primaryKey = array('key1', 'key2');

    ...

由jessedp补充:
在我想使用Model :: find之前,这对我一直很有效,因此以下是一些可以添加到上述hasCompositePrimaryKey特性中的代码(可能会更好):

protected static function find($id, $columns = ['*'])
{
    $me = new self;
    $query = $me->newQuery();
    $i=0;

    foreach ($me->getKeyName() as $key) {
        $query->where($key, '=', $id[$i]);
        $i++;
    }

    return $query->first($columns);
}
2020-05-26