Как создать сложные модели Eloquent с историей аудита, сохраняемой автоматически - PullRequest
0 голосов
/ 27 сентября 2018

Я создаю приложение, которое импортирует данные с различных платформ электронной коммерции, включая Shopify.Эти данные могут измениться, когда администратор обновит заказ.Приложение всегда должно иметь актуальную запись, а также историю аудита, чтобы увидеть, что изменилось и когда.Я использую Laravel Auditing для записи изменений.

В идеале, мой код должен отвечать только за:

  1. Заполнение объектов модели PHP данными (порядок, адреса, элементы)
  2. Связывание моделей друг с другом (добавление элементов / адресов в порядок)

Тогда я бы хотел красноречиво справиться с тяжелой работой из:

Проверка существующей записи для любой из этих моделей Вставка новой, если нет, или обновление , если да Сохранение истории аудита того, что изменилось

Например, если сам заказ не изменился, но изменился адрес, когда я позвонил $order->save()следует обновить адрес и сохранить историю аудита.

Один из вариантов может состоять в том, чтобы проверить, существует ли Address или OrderItem в БД до заполнения модели данными.Это не идеально, потому что:

  1. Класс, заполняющий модель, должен отвечать только за заполнение ее данными: не должно заботиться, существует ли запись уже или нет, так как это сломало бы Принцип одиночной ответственности .
  2. Класс, заполняющий модели Address, должен знать, для какой модели Order предназначен адрес.Это также нарушает SRP.
  3. Я также хотел бы избежать использования отдельных функций для createNewOrder() и updateExistingOrder(), чтобы избежать дублирования кода.

Вот что у меня так далеко:

Когда приложение видит заказ в первый раз, оно заполняет модели, а затем вставляет записи INSERT для этих объектов, например:

$order = SalesOrder::firstOrNew([
    'store_id' => $orderData['store_id'],
    'external_id' => $orderData['external_id']
]);

$order->save();
$order->salesOrderAddresses()->save($billingAddress);

if(@$shippingAddress) {
    $order->salesOrderAddresses()->save($shippingAddress);
}

$order->salesOrderItems()->saveMany($items);

У меня есть история аудита, работающая для самого заказа.Эта часть работает нормально, но было бы здорово, если бы я мог сначала создать всю модель заказа, а затем вызвать один save(), чтобы Eloquent интеллектуально сохранял все изменения в базе данных.

В классе SalesOrderУ меня есть следующие отношения:

public function salesOrderAddresses() {
    return $this->hasMany(SalesOrderAddress::class,'order_id');
}
public function salesOrderItems() {
    return $this->hasMany(SalesOrderItem::class,'order_id');
}

Иерархия такая:

SalesOrder = [
    Addresses [
        Address (billing),
        Address (shipping)
    ],
    Items = [
        [
            sku: abc,
            qty: 123
        ],
        [
            sku: xyz,
            qty: 321
        ]
    ]
]

Во всяком случае, я, вероятно, подхожу к этому совершенно неверным путем.Надеюсь, некоторые опытные разработчики Eloquent и Laravel могут предложить лучший способ справиться с этим.

...