Jak Mogę umieścić klucze kompozytowe w modelach w Laravel 5?
Mam w bazie danych tabelę z dwoma kluczami podstawowymi (id i language_id) i muszę umieścić ją w moich modelach. Domyślny klucz podstawowy w modelach (Model.php w Laravel 5) jest id, i chcę, aby primaryKeys były id i id_language. Próbowałem umieścić go z tablicami lub ciągiem znaków z',', ale to nie działa. Mówi mi, że tablica nie może być przekonwertowana w łańcuchu.
Proszę O Pomoc.
Dzięki!
8 answers
Nie możesz. Eloquent nie obsługuje złożonych kluczy podstawowych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-14 19:23:43
Napisałem ten prosty PHP aby przystosować się do obsługi kluczy złożonych:
<?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);
}
}
Umieść go w katalogu Traits
pod głównym katalogiem modelu, a następnie możesz dodać prostą jednowierszową do dowolnego modelu klucza kompozytowego:
class MyModel extends Eloquent {
use Traits\HasCompositePrimaryKey; // *** THIS!!! ***
/**
* The primary key of the table.
*
* @var string
*/
protected $primaryKey = array('key1', 'key2');
...
dodany przez jessedp:
To działało wspaniale dla mnie, dopóki nie chciałem użyć Model:: find ... tak więc poniżej znajduje się jakiś kod (który prawdopodobnie byłby lepszy), który można dodać do Cechy hasCompositePrimaryKey powyżej:
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);
}
Aktualizacja 2016-11-17
Zachowuję to jako część pakietu open-source o nazwie LaravelTreats .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-10 17:41:15
Wygląda na to, że się zmieniło, ponieważ ten działa z co najmniej Laravel 5.1:
$table->primary(['key1', 'key2']);
Właśnie uruchamiam migrację i to, co widzę w bazie danych, pasuje do tego, co umieściłem w powyższym kodzie (oczywiście pola nazwy powyżej są tylko dla celów prezentacji).
Update: dotyczy to migracji, ale jak tylko chcesz wstawić za pomocą eloquent, nie działa z kluczami kompozytowymi i nigdy nie będzie działać (last wpis): {]}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-26 11:20:02
W migracjach możesz po prostu zdefiniować złożone klucze podstawowe dla tabeli jako @erick-suarez i @ SBA said, w Schema::create
lub Schema::table
zapis blokowy $table->primary(['key1', 'key2']);
W modelu elokwentnym reprezentującym tę tabelę nie można bezpośrednio użyć klucza złożonego za pomocą elokwentnych metod, np. find($key)
ani save($data)
, ale nadal można pobrać instancję modelu do przeglądania za pomocą
$modelObject = ModelName->where(['key1' => $key1, 'key2' => $key2])->first();
I jeśli chcesz zaktualizować rekord w tej tabeli, możesz użyć metod QueryBuilder
, takich jak to:
ModelName->where(['key1' => $key1, 'key2' => $key2])->update($data);
Gdzie $data
jest tablicą asocjacyjną danych, którą chcesz zaktualizować swój model tak ['attribute1' => 'value1', ..]
.
Uwaga: możesz nadal bezpiecznie używać elokwentnych relacji do pobierania z takimi modelami, ponieważ są one powszechnie używane jako tabele przestawne, które przełamują wiele do wielu struktur relacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-04 22:47:57
Spróbuj spojrzeć na tę dokumentację, aby wstawić wiele do wielu relacji z CK
Https://laravel.com/docs/5.2/eloquent-relationships#inserting-many-to-many-relationships
Edit: jakieś dodatkowe info
Jak widać w dokumentacji, funkcje dołączania i odłączania tworzą łącza potrzebne w tabeli pośredniej CK. Więc nie musisz ich tworzyć samodzielnie;)
W Twoim przypadku byłoby to model->languages()->attach(language_id)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-15 03:12:26
Https://laravel.com/docs/5.3/migrations#columns
Tak, możesz.Udostępniam mój kod migracji:
<?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');
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-22 18:29:51
Oto mój plik migracji, który rozwiązał mój problem zarządzania kluczami w migracji.. Może być konieczne zaktualizowanie klasy modelu później, jeśli uzyskasz nielegalny błąd typu offset lub coś w tym stylu. Rozwiązanie jest tutaj - Tutaj
<?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');
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-05 03:56:25
Proszę odwiedzić te dwa linki poniżej, te rozwiązanie rozwiązało mój klucz kompozytowy lub wielokolumnowy problem z kluczem podstawowym -
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-05 04:00:32