wake-up-neo.net

Wie kann ich zusammengesetzte Schlüssel in Modelle in Laravel 5 einfügen?

Ich habe in meiner Datenbank eine Tabelle mit zwei Primärschlüsseln (id und language_id) und muss sie in meine Modelle einfügen. Der Standard-Primärschlüssel in Models (Model.php in Laravel 5) ist id, und ich möchte, dass die Primärschlüssel id und id_language sind. Ich habe es mit Arrays oder einem String mit ',' versucht, aber es funktioniert nicht. Es sagt mir, dass das Array nicht in String konvertiert werden konnte.

Bitte helfen.

Vielen Dank!

33
Sergioh Lonet

Du kannst nicht Eloquent unterstützt keine zusammengesetzten Primärschlüssel.

Hier ist eine Github-Frage dazu.

26
lukasgeiter

Ich habe dieses einfache PHP - Merkmal geschrieben, um Eloquent an die Verarbeitung von zusammengesetzten Schlüsseln anzupassen:

<?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);
    }
}

Platzieren Sie diese in einem Traits-Verzeichnis unter Ihrem Hauptmodellverzeichnis. Dann können Sie einen einfachen Einzeiler oben in jedes Composite-Key-Modell hinzufügen:

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

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

    ...


hinzugefügt von jessedp:
Dies funktionierte wunderbar für mich, bis ich Model :: find verwenden wollte. Das Folgende ist ein Code (der möglicherweise besser sein könnte), der der oben genannten Eigenschaft hasCompositePrimaryKey hinzugefügt werden kann: 

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);
}

Update 2016-11-17

Ich halte dies jetzt als Teil eines Open-Source-Pakets mit dem Namen LaravelTreats .

64
mopo922

Es scheint sich geändert zu haben, da dieser mit mindestens Laravel 5.1 arbeitet:

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

Ich führe gerade die Migration aus und das, was ich in der Datenbank sehe, passt zu dem, was ich oben in den Code eingebe (natürlich sind die Namensfelder oben nur für Präsentationszwecke).

Update: Dies gilt für Migrationen, aber sobald Sie über eloquent einfügen möchten, funktioniert es nicht mit zusammengesetzten Schlüsseln und wird dies niemals tun (letzter Eintrag):

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

12
sba

Bei Migrationen können Sie einfach zusammengesetzte Primärschlüssel für eine Tabelle definieren, wie @ erick-suarez und @sba in Ihrem Schema::create- oder Schema::table-Block schreiben $table->primary(['key1', 'key2']);.

Im Eloquent-Modell , das diese Tabelle darstellt, können Sie diesen zusammengesetzten Schlüssel nicht direkt mit Eloquent-Methoden verwenden, z. find($key) oder save($data), Sie können die Modellinstanz jedoch weiterhin zur Anzeige abrufen

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

Und wenn Sie einen Datensatz in dieser Tabelle aktualisieren möchten, können Sie QueryBuilder-Methoden wie folgt verwenden:

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

Dabei ist $data das datenassoziative Array, mit dem Sie Ihr Modell aktualisieren möchten, wie ['attribute1' => 'value1', ..].


Hinweis: Sie können Eloquent-Beziehungen immer noch sicher zum Abrufen mit solchen Modellen verwenden, da sie häufig als Pivot-Tabellen verwendet werden, die viele-zu-viele-Beziehungsstrukturen aufbrechen.

5

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

Ja du kannst.

ich teile meinen Migrationscode:

    <?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');
    }

}
2
Erick Suarez

Schauen Sie sich diese Dokumentation an, um viele oder viele Beziehungen zu CK einzufügen

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

Edit: einige zusätzliche Informationen 
Wie Sie in der Dokumentation sehen, erstellen die Funktionen zum Anhängen und Trennen die in der CK-Zwischentabelle benötigten Verknüpfungen. Sie müssen sie also nicht selbst erstellen;)

In Ihrem Fall wäre es model->languages()->attach(language_id)

1
Reyske

Bitte besuchen Sie diese beiden Links unten. Diese Lösung hat mein Problem mit dem zusammengesetzten Schlüssel oder mehrspaltigen Primärschlüssel gelöst. 

  1. Datenbank mit zusammengesetzten Schlüsseln erstellen

  2. Fehler beim ungültigen Offset-Typ

0
Sadidul Islam

Hier ist meine Migrationsdatei, sie hat mein Problem mit der Schlüsselverwaltung in der Migration gelöst ... __ Sie müssen die Modellklasse später aktualisieren, wenn ein ungültiger Offset-Fehler oder ähnliches angezeigt wird. Die Lösung ist hier - hier

<?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');
    }
}
0
Sadidul Islam

sie können versuchen, folgendes Modul zu verwenden 

https://github.com/maksimru/composite-primary-keys

fügen Sie einfach HasCompositePrimaryKey-Eigenschaft zu Ihrem Modell hinzu und geben Sie den Array-Wert als Primärschlüssel an

0

Ich hoffe das hilft 

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']);
        });

 enter image description here

0
ViperTecPro