Как я могу поместить составные клавиши в модели в Laravel 5?

У меня в моей базе данных есть таблица с двумя первичными ключами (id и language_id), и мне нужно поместить ее в мои модели. По умолчанию primaryKey в Models (Model.php в Laravel 5) является id, и я хочу, чтобы primaryKeys были id и id_language. Я попытался поместить его с массивами или String с помощью «,», но это не сработает. Он говорит мне, что массив не может быть преобразован в String.

Пожалуйста помоги.

Благодаря!

Solutions Collecting From Web of "Как я могу поместить составные клавиши в модели в Laravel 5?"

Вы не можете. Eloquent не поддерживает составные первичные ключи.

Вот вопрос Github об этом.

Я написал эту простую черту 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(); } 

Обновление 2016-11-17

Я поддерживаю это как часть пакета с открытым исходным кодом LaravelTreats .

Кажется, он изменился, так как этот работает, по крайней мере, с Laravel 5.1:

 $table->primary(['key1', 'key2']); 

Я просто запускаю миграцию, и то, что я вижу в базе данных, соответствует тому, что я ввел в код выше (конечно, поля имени выше приведены только для целей презентации).

Обновление : это верно для миграций, но как только вы хотите вставить через красноречивый, он не работает с составными ключами и никогда не будет делать (последняя запись):

https://github.com/laravel/framework/issues/5517

В миграциях вы можете просто определить составные первичные ключи для таблицы как @ erick-suarez и @sba, в вашем блоке Schema::create или Schema::table напишите $table->primary(['key1', 'key2']);

В модели Eloquent, которая представляет эту таблицу, вы не можете напрямую использовать этот составной ключ с методами Eloquent, например find($key) или save($data) но вы все равно можете получить экземпляр модели для просмотра, используя

 $modelObject = ModelName->where(['key1' => $key1, 'key2' => $key2])->first(); 

И если вы хотите обновить запись в этой таблице, вы можете использовать методы QueryBuilder следующим образом:

 ModelName->where(['key1' => $key1, 'key2' => $key2])->update($data); 

Где $data – ассоциативный массив данных, который вы хотите обновить свою модель так ['attribute1' => 'value1', ..] .


Примечание. Вы можете использовать безопасные отношения для поиска с такими моделями, поскольку они обычно используются в качестве сводных таблиц, которые разбивают структуры отношений «ко многим ко многим».

Попробуйте просмотреть эту документацию для вставки многих из многих отношений с CK

https://laravel.com/docs/5.2/eloquent-relationships#inserting-many-to-many-relationships

Изменить: дополнительная информация
Как вы можете видеть в документации, функции attach и detach создают ссылки, необходимые в промежуточной таблице CK. Поэтому вам не нужно создавать их сами;)

В вашем случае это будет model->languages()->attach(language_id)

https://laravel.com/docs/5.3/migrations#columns

Да ты можешь.

Я делюсь своим кодом миграции:

  <?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class RegistroEmpresa extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('registro_empresa', function(Blueprint $table) { $table->string('licencia',24); $table->string('rut',12); $table->string('nombre_empresa'); $table->string('direccion'); $table->string('comuna_Estado'); $table->string('ciudad'); $table->string('pais'); $table->string('fono'); $table->string('email'); $table->string('paginaweb'); $table->string('descripcion_tienda'); $table->string('monedauso'); $table->timestamps(); $table->primary(['licencia', 'rut']); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('registro_empresa'); } }