php - Come posso inserire le chiavi composite nei modelli in Laravel 5?




web composite-primary-key (8)

Ho nel mio DataBase una tabella con due chiavi primarie (id e language_id) e ho bisogno di metterlo nei miei modelli. La primaryKey predefinita in Models (Model.php in Laravel 5) è id, e voglio che primaryKeys sia id e id_language. Ho provato a metterlo con matrici o una stringa con ',' ma non funziona. Mi dice che l'array non può essere convertito in String.

Per favore aiuto.

Grazie!


Answers

Sembra che sia cambiato, dal momento che questo funziona con almeno Laravel 5.1:

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

Ho appena eseguito la migrazione e quello che vedo nel database si adatta a ciò che ho inserito nel codice sopra (ovviamente i campi del nome sopra sono solo a scopo di presentazione).

Aggiornamento : questo vale per le migrazioni, ma non appena si desidera inserire tramite eloquente non funziona con le chiavi composite e non lo farà mai (ultima voce):

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




Ecco il mio file di migrazione, ha risolto il mio problema di gestione delle chiavi durante la migrazione. Potresti aver bisogno di aggiornare la classe del modello in un secondo momento, se ottieni errore di tipo di offset illegale o qualcosa del genere. La soluzione è qui - here

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

Ho scritto questo semplice tratto PHP per adattare Eloquent alla gestione delle chiavi composite:

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

Collocalo in una directory di Traits directory del tuo modello principale, quindi puoi aggiungere una semplice copertina nella parte superiore di qualsiasi modello di chiave composta:

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

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

    ...

aggiunto da jessedp:
Questo ha funzionato meravigliosamente per me fino a quando non volevo usare Model :: find ... quindi il seguente è un codice (che potrebbe probabilmente essere migliore) che può essere aggiunto al tratto hasCompositePrimaryKey sopra:

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

Aggiornamento 2016-11-17

Ora lo sto mantenendo come parte di un pacchetto open-source chiamato LaravelTreats .



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

Si Puoi.

condivido il mio codice di migrazione:

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

}

==è usato per controllare l'uguaglianza senza considerare il tipo di dati variabile

===è usato per controllare l'uguaglianza sia per il valore della variabile * che per il tipo di dati

Esempio

$a = 5

  1. if ($a == 5) - valuterà il vero

  2. if ($a == '5') - valuterà a vero, perché mentre confrontando questo valore php internamente converti quel valore stringa in numero intero e poi confronti entrambi i valori

  3. if ($a === 5) - valuterà il vero

  4. if ($a === '5') - valuterà a false, perché il valore è 5, ma questo valore 5 non è un numero intero.





php laravel web model composite-primary-key