Учитывая, что вы хотите сделать это только на одной модели, сравнивая строки current
и previous
в этой таблице, вот как я бы решил это:
<?php
class History extends Model
{
public function hasIndescrepencies(): bool
{
$current = $this->query()->orderBy('updated_at', 'DESC')->first();
$previous = null;
if ($current) {
$previous = $this->query()->orderBy('updated_at', 'DESC')->where('id', '!=', $current->id)->first();
}
if ($current && $previous) {
$current = $current->toArray();
$previous = $previous->toArray();
$ignoreColumns = array_flip(['id', 'created_at', 'updated_at']);
$currentDataKeys = array_filter(array_keys($current), function($key) use($ignoreColumns) {
return !array_key_exists($key, $ignoreColumns);
});
$currentData = [];
foreach ($currentDataKeys as $currentDataKey) {
$currentData[$currentDataKey] = $current[$currentDataKey];
}
$previousDataKeys = array_filter(array_keys($previous), function($key) use($ignoreColumns) {
return !array_key_exists($key, $ignoreColumns);
});
$previousData = [];
foreach ($previousDataKeys as $previousDataKey) {
$previousData[$previousDataKey] = $previous[$previousDataKey];
}
return !empty(array_diff($currentData, $previousData))
}
return false;
}
}
Объяснение:
- Вы загружаете самую последнюю обновленную строку, а затем предыдущая строка выбирается так же, как текущая, без учета идентификатора текущей строки.
- Если первая и вторая строки существуют, то вы продолжаете делатьчек.эта таблица может начинаться только с одной строки или вообще без строк.
- Затем получить пару значений ключ => для текущей и предыдущей строки (исключая определенные столбцы, такие как id, creation_at & updated_at- потому что они будут другими, даже если базовые данные строки могли не измениться)
- Затем сравните массив diff и посмотрите, существует ли что-то
Вот как я это подтвердилработает с использованием чистого массива php:
$current = [
'id' => 1,
'name' => 'bob',
'age' => 21,
'created_at' => '2019-01-01 00:00:00',
'updated_at' => '2019-01-02 00:00:00',
];
$previous = [
'id' => 2,
'name' => 'bob',
'age' => 20,
'created_at' => '2019-01-03 00:00:00',
'updated_at' => '2019-01-04 00:00:00',
];
$ignoreColumns = array_flip(['id', 'created_at', 'updated_at']);
$currentDataKeys = array_filter(array_keys($current), function($key) use($ignoreColumns) {
return !array_key_exists($key, $ignoreColumns);
});
$currentData = [];
foreach ($currentDataKeys as $currentDataKey) {
$currentData[$currentDataKey] = $current[$currentDataKey];
}
$previousDataKeys = array_filter(array_keys($previous), function($key) use($ignoreColumns) {
return !array_key_exists($key, $ignoreColumns);
});
$previousData = [];
foreach ($previousDataKeys as $previousDataKey) {
$previousData[$previousDataKey] = $previous[$previousDataKey];
}
var_dump(array_diff($currentData, $previousData));
Результат var_dump должен выглядеть примерно так:
array(1) {
["age"]=>
int(21)
}
Это правильно, поскольку единственное, что отличается от текущего и предыдущего, былозначение ключа возраста.
Надеюсь, это поможет.