J'ai dans ma base de données une table avec deux clés primaires (id et language_id) et je dois la mettre dans mes modèles. PrimaryKey par défaut dans Models (Model.php dans Laravel 5) est id et je souhaite que les primaryKeys soient id et id_language. J'ai essayé de le mettre avec des tableaux ou une chaîne avec ',' mais cela ne fonctionne pas. Il me dit que le tableau n'a pas pu être converti en chaîne.
S'il vous plaît aider.
Merci!
Tu ne peux pas. Eloquent ne supporte pas les clés primaires composites.
J'ai écrit ce trait simple PHP pour adapter Eloquent à la gestion des clés composites:
<?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);
}
}
Placez-le dans un répertoire Traits
sous votre répertoire de modèle principal, puis vous pouvez ajouter une simple ligne à la première place de tout modèle de clé composite:
class MyModel extends Eloquent {
use Traits\HasCompositePrimaryKey; // *** THIS!!! ***
/**
* The primary key of the table.
*
* @var string
*/
protected $primaryKey = array('key1', 'key2');
...
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);
}
Je maintiens maintenant cela dans le cadre d'un paquet open-source appelé LaravelTreats .
Il semble que cela ait changé, puisque celui-ci fonctionne avec au moins Laravel 5.1:
$table->primary(['key1', 'key2']);
Je viens d'exécuter la migration et ce que je vois dans la base de données correspond à ce que j'ai mis dans le code ci-dessus (bien sûr, les champs de nom ci-dessus sont juste à des fins de présentation).
Update: cela est vrai pour les migrations, mais dès que vous voulez insérer via eloquent, cela ne fonctionne pas avec les clés composites et ne le fera jamais (dernière entrée):
Dans les migrations vous pouvez simplement définir les clés primaires composites d'une table sous la forme @ erick-suarez et @sba, dans votre bloc Schema::create
ou Schema::table
, écrivez $table->primary(['key1', 'key2']);
Dans le modèle Eloquent qui représente cette table, vous ne pouvez pas utiliser directement cette clé composite avec les méthodes Eloquent, par ex. find($key)
ni save($data)
mais vous pouvez toujours récupérer l'instance de modèle à des fins d'affichage à l'aide de
$modelObject = ModelName->where(['key1' => $key1, 'key2' => $key2])->first();
Et si vous souhaitez mettre à jour un enregistrement dans cette table, vous pouvez utiliser les méthodes QueryBuilder
comme ceci:
ModelName->where(['key1' => $key1, 'key2' => $key2])->update($data);
Où $data
est le tableau associatif de données avec lequel vous souhaitez mettre à jour votre modèle, alors so ['attribute1' => 'value1', ..]
.
Remarque: Vous pouvez toujours utiliser les relations Eloquent en toute sécurité pour les récupérer avec ces modèles, car elles sont couramment utilisées en tant que tableaux croisés dynamiques rompant les structures de relation plusieurs à plusieurs.
https://laravel.com/docs/5.3/migrations#columns
Oui tu peux.
je partage mon code de migration:
<?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');
}
}
Essayez de regarder cette documentation pour insérer plusieurs relations avec CK.
https://laravel.com/docs/5.2/eloquent-relationships#inserting-many-to-many-relationships
Edit: quelques infos supplémentaires
Comme vous pouvez le constater dans la documentation, les fonctions d'attachement et de détachement créent les liens nécessaires dans la table intermédiaire CK. Donc vous n'avez pas à les créer vous-même;)
Dans votre cas, ce serait model->languages()->attach(language_id)
Veuillez visiter ces deux liens ci-dessous, ces solutions ont résolu mon problème de clé primaire composite ou multi-colonne -
Voici mon fichier de migration, cela a résolu mon problème de gestion des clés dans la migration .. Vous aurez peut-être besoin de mettre à jour la classe de modèle ultérieurement, si vous obtenez une erreur de type offset illégale ou quelque chose du genre. La solution est ici - ici
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAccountSessionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('account_sessions', function (Blueprint $table) {
$table->string('session', 64);//creates a string column, that can use in primary key. don't let it exceeds 797 bytes
$table->integer('account_id')->unsigned();//unsigned integer column
$table->timestamps();
$table->primary(['session', 'account_id']);//added the primary keys
$table->foreign('account_id')->references('id')->on('accounts');//foreign key
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('account_sessions');
}
}
vous pouvez essayer d'utiliser le module suivant
https://github.com/maksimru/composite-primary-keys
ajoutez simplement le trait HasCompositePrimaryKey à votre modèle et spécifiez la valeur du tableau comme clé primaire
J'espère que ça aide
Schema::create('vw_term_relationships', function (Blueprint $table) {
$table->bigInteger('object_id')->unsigned()->default('0');
$table->bigInteger('term_taxonomy_id')->unique()->unsigned()->default('0');
$table->integer('term_order')->default('0');
$table->primary(['object_id', 'term_taxonomy_id']);
});