Почему при миграции в Laravel создается колонка, доступная только для чтения?

В Laravel 11 я создаю колонку для учета количества опубликованных записей пользователем за день, называя ее "posts_today" с типом unsigned int, однако Laravel автоматически создает эту колонку как read-only. Если же я изменяю название на "test", то колонка становится полноценной и доступной для изменений. Каковы причины этого поведения? Как можно создать колонку, которую можно редактировать? В документации этой информации не нашел. Также стоит отметить, что метод increment() работает с этим полем. Я использую Laravel Sail, и перезапуск контейнеров не дал результатов. Смена типа данных на string также не помогла. 

```php
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('phone', 11)->unique();
    $table->string('avatar')->nullable();
    $table->string('email')->unique()->nullable();
    $table->timestamp('email_verified_at')->nullable();
    $table->unsignedInteger('posts_today')->default(0);  // <- почему-то создает RO - колонку в БД
    $table->rememberToken();
    $table->timestamps();
});
```
  • 10 декабря 2024 г. 10:33
Ответы на вопрос 2
Причина, по которой Laravel создаёт колонку с именем `posts_today` как доступную только для чтения, может быть связана с тем, как Laravel обрабатывает атрибуты модели и с тем, как вы определяете свою модель User.

### Возможные причины

1. **Зарезервированные слова**: В большинстве случаев, если вы используете такое имя, как `posts_today`, Laravel может вести себя не так, как вы ожидаете. Например, имя `today` может быть интерпретировано как метод или свойство. Поэтому пробуйте избегать названий, которые могут конфликтовать с существующими методами или свойствами.

2. **Виртуальные атрибуты**: Убедитесь, что в модели `User` нет определённого виртуального (доступного только для чтения) атрибута с тем же именем. Например, если вы определили в модели метод `getPostsTodayAttribute()`, он будет работать как виртуальное свойство, которое может затенять реальный столбец в базе данных и делать его доступным только для чтения.

3. **Mass Assignment**: Проверьте свойство `$fillable` или `$guarded` в вашей модели. Если ваш атрибут не входит в `$fillable`, он может оказаться недоступным для массового назначения.

### Шаги для решения

1. **Проверьте модель**: Убедитесь, что в модели `User` нет метода, который делает `posts_today` виртуальным, например:
   ```php
   public function getPostsTodayAttribute() {
       return ...; // Что-то, что возвращает значение 
   }
   ```

2. **Переименуйте колонку**: Попробуйте временно переименовать колонку на что-то другое, например, `daily_posts`, и проверьте, отображается ли она как доступная для записи.

3. **Проверьте настройки `fillable`**: Убедитесь, что поле `posts_today` находится в массиве `$fillable` в вашей модели:
   ```php
   protected $fillable = ['name', 'phone', 'avatar', 'email', 'posts_today', ...];
   ```

4. **Сброс миграций**: Если был внесен какой-то код в модели, который мог повлиять на базу данных, возможно, вам стоит сбросить миграции и заново их прогнать:
   ```bash
   php artisan migrate:fresh
   ```

Если всё вышеперечисленное не сработает, то стоит проверить логи и сообщения об ошибках, которые могут подсказать, что именно не так. 

Если проблема сохраняется, рекомендую также создавать issue на GitHub репозитории Laravel, чтобы получить помощь непосредственно от сообщества или разработчиков фреймворка.
Судя по всему проблема была в DBeaver, после перезапуска все стало нормально. Вопрос не актуален.
Похожие вопросы