Laravel — установка атрибута publish_at

В моем приложении есть публикуемые объявления с моделью Announcement, вот схема:

Schema::create('announcements', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('message');
    $table->text('message_details');
    $table->string('author');
    $table->string('status');
    $table->timestamp('published_at')->nullable();
    $table->timestamps();
});

У меня также есть AnnouncementObserver, чтобы наблюдать за изменениями модели.

Я подумал, что для установки published_at я мог бы использовать событие updated следующим образом:

/**
 * Handle the announcement "updated" event.
 *
 * @param  \App\Announcement  $announcement
 * @return void
 */
public function updated(Announcement $announcement)
{
    $changes = $announcement->getChanges();

    if ($changes['status'] === 'published') {
        $announcement->published_at = Carbon::now();
    }

    Log::notice("An announcement was updated: {$announcement->title} by: " . auth()->user()->full_name);
}

Однако это не обновилось published_at. Я не делал этого при обновлении, потому что не видел способа определить, действительно ли изменилось значение.

Я усложняю здесь?

Из отзывов

/**
 * Handle the announcement "creating" event.
 *
 * @param  \App\Article  $announcement
 * @return void
 */
public function updating(Announcement $announcement)
{
    if ($announcement->isDirty(['status'])) {
        $new_status = $announcement->getDirty('status');

        if ($new_status == 'published') {
            dd('weng');
        }
    }
}

Однако это не совсем работает...

Основываясь на данных ответах, вот что у меня получилось...

/**
 * Handle the announcement "creating" event.
 *
 * @param  \App\Announcement  $announcement
 * @return void
 */
public function updating(Announcement $announcement)
{
    // Set published_at when published
    if ($announcement->isDirty('status') && $announcement->status === 'published') {
        $announcement->published_at = now();
    }

    // Set published_at to null when unpublished
    if ($announcement->isDirty('status') && $announcement->status !== 'published') {
        $announcement->published_at = null;
    }
}

Таким образом, при изменении статуса публикации published_at становится NULL.

Вы хотите, чтобы дата менялась каждый раз, когда производится обновление, если status === «опубликовано» или только в первый раз?

Rwd 29.07.2019 15:19

Просто примечание: наличие статуса опубликовано немного избыточно, если у вас уже есть поле publish_at. Просто проверьте, не пусто ли поле publish_at, если вы хотите запрашивать только опубликованные объявления.

Bram Verstraten 29.07.2019 15:28

@BramVerstraten Если у OP больше двух статусов.

Rwd 29.07.2019 15:34

Привет, ребята, раньше у меня было просто опубликованное поле с 3 статусами и я использовал updated_at, но пользователь спросил, что это может быть в порядке, когда они были впервые опубликованы, а не обновлены.

Jesse Orange 29.07.2019 15:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
4
713
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Что вы можете сделать, так это изменить его обратно на updating и проверить, было ли изменено объявление с помощью $announcement->isDirty(). Этот метод вернет значение true, если один или несколько атрибутов объекта изменились с тех пор, как его атрибуты были извлечены из базы данных.

можно ли сделать if ($announcement->isDirty('status') === 'value')?

Jesse Orange 29.07.2019 15:24

Вы можете использовать его следующим образом: if ( $announcement->isDirty(['message_details','status']) ) Это проверяет, изменился ли один из двух заданных атрибутов, и если это так, он возвращает true. Строка ('status'), как вы, также возможна и проверяет один измененный атрибут. (Документация)

Douwe de Haan 29.07.2019 15:28

Учитывая это, можете ли вы проверить, что грязный атрибут является заданным значением?

Jesse Orange 29.07.2019 15:37

@JesseOrange, если это должно быть status, вы можете сделать это: if ( $announcement->isDirty( 'status' ) && $announcement->status === 'the_value_you_want' ).

Douwe de Haan 29.07.2019 15:39
Ответ принят как подходящий

Причина, по которой published_at не обновилась, заключается в том, что вы не вызвали save() модель.

При этом было бы лучше, если бы вы применили это изменение в методе updating() своего AnnouncementObserver. Вы можете сделать это, используя метод isDirty(), а затем проверив значение самого экземпляра:

public function updating(Announcement $announcement)
{
    if ($announcement->isDirty('status') && announcement->status === 'published') {
        $announcement->published_at = now();
    }
}

Поскольку событие updating запускается после save()/updated(), но до фактического сохранения данных, вам не нужно вызывать save() самостоятельно.

Итак, я слишком усложнял, просто было немного неправильно пытаться сделать это в контроллере.

Jesse Orange 29.07.2019 15:42

@JesseOrange Нет, это пойдет в твой класс AnnouncementObserver .

Rwd 29.07.2019 15:43

О, да, я знаю, я просто объяснял свои доводы в пользу использования Observer. Я также не понимал, что вы можете получить доступ к грязным, как к обычному массиву...

Jesse Orange 29.07.2019 15:45

@JesseOrange Да, можешь. Я обновил код, чтобы сделать его проще, поэтому вам на самом деле не нужно проверять массив, вы просто проверяете, не является ли значение грязным, а затем проверяете, что это за значение.

Rwd 29.07.2019 15:47

Чтобы гарантировать, что был обновлен статус, вы также добавили бы isDirty('status')?

Jesse Orange 29.07.2019 15:47

@JesseOrange Да, это была оплошность с моей стороны, ха-ха.

Rwd 29.07.2019 15:58

Честно говоря, я никогда не думал о том, как работает грязный метод, но, глядя на него, теперь все понятно, почему существует массив с именем original.

Jesse Orange 29.07.2019 16:25

@JesseOrange Это ответило на ваш вопрос или вам все еще нужна помощь в решении проблемы?

Rwd 29.07.2019 17:17

Другие вопросы по теме