Das Problem beim Löschen und Lesen der zugehörigen Entitäten besteht darin, dass dadurch alle Fremdschlüsseleinschränkungen aufgehoben werden, die Sie möglicherweise für diese untergeordneten Entitäten haben.
Eine bessere Lösung ist Laravel des HasMany
Beziehung gehören ein sync
Verfahren zu ändern:
<?php
namespace App\Model\Relations;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @link https://github.com/laravel/framework/blob/5.4/src/Illuminate/Database/Eloquent/Relations/HasMany.php
*/
class HasManySyncable extends HasMany
{
public function sync($data, $deleting = true)
{
$changes = [
'created' => [], 'deleted' => [], 'updated' => [],
];
$relatedKeyName = $this->related->getKeyName();
// First we need to attach any of the associated models that are not currently
// in the child entity table. We'll spin through the given IDs, checking to see
// if they exist in the array of current ones, and if not we will insert.
$current = $this->newQuery()->pluck(
$relatedKeyName
)->all();
// Separate the submitted data into "update" and "new"
$updateRows = [];
$newRows = [];
foreach ($data as $row) {
// We determine "updateable" rows as those whose $relatedKeyName (usually 'id') is set, not empty, and
// match a related row in the database.
if (isset($row[$relatedKeyName]) && !empty($row[$relatedKeyName]) && in_array($row[$relatedKeyName], $current)) {
$id = $row[$relatedKeyName];
$updateRows[$id] = $row;
} else {
$newRows[] = $row;
}
}
// Next, we'll determine the rows in the database that aren't in the "update" list.
// These rows will be scheduled for deletion. Again, we determine based on the relatedKeyName (typically 'id').
$updateIds = array_keys($updateRows);
$deleteIds = [];
foreach ($current as $currentId) {
if (!in_array($currentId, $updateIds)) {
$deleteIds[] = $currentId;
}
}
// Delete any non-matching rows
if ($deleting && count($deleteIds) > 0) {
$this->getRelated()->destroy($deleteIds);
$changes['deleted'] = $this->castKeys($deleteIds);
}
// Update the updatable rows
foreach ($updateRows as $id => $row) {
$this->getRelated()->where($relatedKeyName, $id)
->update($row);
}
$changes['updated'] = $this->castKeys($updateIds);
// Insert the new rows
$newIds = [];
foreach ($newRows as $row) {
$newModel = $this->create($row);
$newIds[] = $newModel->$relatedKeyName;
}
$changes['created'][] = $this->castKeys($newIds);
return $changes;
}
/**
* Cast the given keys to integers if they are numeric and string otherwise.
*
* @param array $keys
* @return array
*/
protected function castKeys(array $keys)
{
return (array) array_map(function ($v) {
return $this->castKey($v);
}, $keys);
}
/**
* Cast the given key to an integer if it is numeric.
*
* @param mixed $key
* @return mixed
*/
protected function castKey($key)
{
return is_numeric($key) ? (int) $key : (string) $key;
}
}
Sie können außer Kraft setzen Eloquent die Model
Klasse zu verwenden HasManySyncable
anstelle der Standard-HasMany
Beziehung:
<?php
namespace App\Model;
use App\Model\Relations\HasManySyncable;
use Illuminate\Database\Eloquent\Model;
abstract class MyBaseModel extends Model
{
/**
* Overrides the default Eloquent hasMany relationship to return a HasManySyncable.
*
* {@inheritDoc}
* @return \App\Model\Relations\HasManySyncable
*/
public function hasMany($related, $foreignKey = null, $localKey = null)
{
$instance = $this->newRelatedInstance($related);
$foreignKey = $foreignKey ?: $this->getForeignKey();
$localKey = $localKey ?: $this->getKeyName();
return new HasManySyncable(
$instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey
);
}
Gesetzt dass Ihr Post
Modell erweitert MyBaseModel
und hat eine links()
hasMany
r EZIEHUNG, können Sie so etwas wie tun:
$post->links()->sync([
[
'id' => 21,
'name' => "LinkedIn profile"
],
[
'id' => null,
'label' => "Personal website"
]
]);
alle Datensätze in dieser mehrdimensionalen Matrix, die ein id
hat, das das Kind Objekt-Tabelle übereinstimmt (links
) aktualisiert werden.Datensätze in der Tabelle, die in diesem Array nicht vorhanden sind, werden entfernt. Datensätze in dem Array, die nicht in der Tabelle vorhanden sind (eine nicht übereinstimmende id
oder eine id
von null) werden als "neue" Datensätze betrachtet und in die Datenbank eingefügt.
ah ok danke, also versuche ich mit dir gehen Weg – user2834172