Laravel Eloquent $model->save() не сохраняется, но нет ошибки

При обновлении моей модели Post я запускаю:

$post->title = request('title');
$post->body = request('body');

$post->save();

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

Post модель:

class Post extends Model
{
    protected $fillable = [
        'type',
        'title',
        'body',
        'user_id',
    ];

   ....
}

Post контроллер:

public function store($id)
{
    $post = Post::findOrFail($id);

    // Request validation
    if ($post->type == 1) {
        // Post type has title
        $this->validate(request(), [
            'title' => 'required|min:15',
            'body' => 'required|min:19',
        ]);

        $post->title = request('title');
        $post->body = request('body');
    } else {
        $this->validate(request(), [
            'body' => 'required|min:19',
        ]);

        $post->body = request('body');
    }

    $post->save();

    return redirect('/');
}

Информация о бонусе

Выполнение dd($post->save()) возвращает true.

Бег

$post->save();

$fetchedPost = Post::find($post->id);
dd($fetchedPost);

показывает мне, что $fetchedPost — это тот же пост, что и раньше, без обновленных данных.


person Jacob    schedule 24.10.2017    source источник
comment
Вы уверены, что у вас есть поле body в модели POST?   -  person Moeen Basra    schedule 24.10.2017
comment
@MoeenBasra да, извините! Я подчистил другой код, чтобы сделать его более читабельным и релевантным (убрал ненужные части, такие как очистка кода, которую я уже проверил, и т. д.), и я забыл изменить эту переменную.   -  person Jacob    schedule 24.10.2017
comment
Что возвращает dd($post->save())?   -  person Ivanka Todorova    schedule 24.10.2017
comment
@IvankaTodorova dd($post->save()) возвращает true. Я добавил это в вопрос.   -  person Jacob    schedule 25.10.2017
comment
Я предполагаю, что laravel 5.5 изменит некоторую систему проверки. Я добавляю ответ, попробуйте это.   -  person Moeen Basra    schedule 25.10.2017
comment
Что dd($post->isDirty()) вернуть?   -  person Anderson Andrade    schedule 25.10.2017
comment
Вы на 100% уверены, что ищете правильную базу данных?   -  person ceejayoz    schedule 25.10.2017
comment
Я думаю, проблема в том, что вы не принимаете запрос, отправленный из формы в функции магазина. @jacob   -  person MalemScha    schedule 25.10.2017
comment
@AndersonAndrade вернул false ...... Я следил за этим SO-вопросом чтобы убедиться, что я делаю это правильно.   -  person Jacob    schedule 25.10.2017
comment
request должно быть $request?   -  person Lars Mertens    schedule 25.10.2017
comment
@ceejayoz да. Я провел тесты, чтобы проверить.   -  person Jacob    schedule 25.10.2017
comment
оба $request, введенные в функцию хранилища, или помощник запроса возвращают одно и то же. Поскольку запрос связан шаблоном singleton с контейнером.   -  person Moeen Basra    schedule 25.10.2017
comment
если проверка не является проблемой и здесь, ваши request('title') и/или request('body') должны быть идентичными?   -  person Lars Mertens    schedule 25.10.2017
comment
@LarsMertens только что провел этот тест: Исходное название: Это мое название. dd(request('title')): Это мой заголовок, и теперь он обновлен.   -  person Jacob    schedule 25.10.2017
comment
Как сюда входят типы постов? Если тип сообщения не равен 1, то вы не устанавливаете title, однако это поле required.   -  person kerrin    schedule 25.10.2017
comment
@kerrin, если тип сообщения не 1, то title не требуется   -  person Jacob    schedule 25.10.2017
comment
Пожалуйста, проверьте, установили ли вы мутатор в своем классе модели или в объекте модели нет идентификатора?   -  person Mahesh Yadav    schedule 10.08.2018
comment
Что сработало для меня, так это установка защищенного свойства $primaryKey в моей модели.   -  person taavs    schedule 04.10.2018
comment
Убедитесь, что ваша модель Post расширяет Illuminate\Database\Eloquent\Model. Я расширял Illuminate\Database\Eloquent\Relations\MorphPivot, и у меня была та же проблема, что и у вас.   -  person Kamal Khan    schedule 28.03.2019
comment
поместите остальную часть вашего кода, как вы нашли сообщение $? потому что там мы можем прийти к выводу, в зависимости от того, как поиск не может использовать сохранение.   -  person Mateus Gonçalves    schedule 17.04.2019


Ответы (11)


Проверьте таблицу базы данных, если столбец «id» указан в верхнем регистре «ID». Изменение его на нижний регистр позволило моему методу save() работать.

person Asuquo Bartholomew Ikechukwu    schedule 10.12.2018
comment
Вам не нужно его менять. Вы можете просто определить имя первичного ключа в своей модели, добавив protected $primaryKey = 'Id'; к вашей модели. это в случае, если первичный ключ - это идентификатор, а не идентификатор - person Junior; 30.12.2018
comment
Это была моя проблема, я работаю над существующей базой данных, и идентификаторы называются не идентификаторами или идентификаторами, а совершенно другой вещью. Что делает это трудным для обнаружения, так это то, что я использую `protected $primaryKey = 'myid'; ` И он отлично работает для запросов, но если это не точное совпадение, он не будет сохранен, идентификатор моей таблицы был в верхнем регистре, изменил его и вуаля, проблема решена, ваш комментарий открыл мне глаза. - person Gary; 30.04.2019
comment
Проклятый MSSQL НЕ ЧУВСТВИТЕЛЬЕН К РЕГИСТРУ! Найдите модель, но Eloquent не может правильно сохранить. - person Marcos Regis; 12.05.2020
comment
вместо изменения из db изменить значение из protected $primaryKey = 'Id'; модели - person TarangP; 19.10.2020

У меня было то же самое и оказалось, потому что я фильтровал выходные столбцы без первичного ключа.

$rows = MyModel::where('...')->select('col2', 'col3')->get();
foreach($rows as $row){
    $rows->viewed = 1;
    $rows->save();
}

Исправлено с

$rows = MyModel::where('...')->select('primary_key', 'col2', 'col3')->get();

Имеет смысл при просмотре, без доступного первичного ключа команда обновления будет иметь значение Null.

person Mark Walker    schedule 15.05.2019
comment
Это было причиной проблемы и для меня. Благодарю вас! - person Michael Horn; 09.10.2019
comment
Это меня тоже достало. Обязательно включите первичный ключ в модель, чтобы обновить ее с помощью save(). Никогда этого не знал. - person HartleySan; 02.09.2020

Поскольку в Laravel 5.5 laravel изменился некоторый механизм проверки, я думаю, вам нужно попробовать этот способ.

public function store(Request $request, $id)
{
    $post = Post::findOrFail($id);

    $validatedData = [];

    // Request validation
    if ($post->type == 1) {
        // Post type has title
        $validatedData = $request->validate([
          'title' => 'required|min:15',
          'body' => 'required|min:19',
      ]);
    } else {
      $validatedData = $request->validate([
        'body' => 'required|min:19',
    ]);
    }

    $post->update($validatedData);

    return redirect('/');
}
person Moeen Basra    schedule 24.10.2017
comment
можете ли вы пройти дамп $validatedData непосредственно перед $post->update(); - person Moeen Basra; 25.10.2017

У меня была та же проблема, и изменение способа получения модели решило ее!

Не сохранялось, хотя вроде бы все работало, как вы упомянули:

$user = User::find($id)->first(); 

Это работает:

$user = User::find($id);
person Bardiya Bakhshandeh    schedule 26.06.2018
comment
помня, что функционально использовать метод find вместе с сохранением, но с некоторыми другими сохранение не работает... также помня, что find использует только primaryKey - person Mateus Gonçalves; 17.04.2019

Запуск dd() внутри DB::transaction вызовет откат, и данные в базе данных не изменятся.

Причина в том, что эта транзакция сохранит изменения в базе данных только в самом конце. Следовательно, действие «сбросить и умереть» естественным образом приведет к остановке сценария и, следовательно, к изменению базы данных.

person Գեղայր-GEXAYR    schedule 16.01.2020

Вы должны убедиться, что экземпляр, который вы вызываете save(), имеет атрибут id

person Vampire    schedule 23.04.2020
comment
В показанном коде он выполняет $post = Post::findOrFail($id);, поэтому у него должен быть установлен идентификатор - person Miguel G. Flores; 23.04.2020

Попробуйте это

public function store($id,Request $request)
{
    $post = Post::findOrFail($id);

    // Request validation
    if ($post->type == 1) {
        // Post type has title
         $request->validate([
            'title' => 'required|min:15',
            'body' => 'required|min:19',
        ]);
        $post->update([
              'title' => request('title');
              'body' => request('body');
             ]);
    } else {
         $request->validate([
            'body' => 'required|min:19',
        ]);

        $post->update([
              'body' => request('body');
             ]);
    }

    return redirect('/');
}
person MalemScha    schedule 24.10.2017

По моему опыту, если вы выберете модель Eloquent из базы данных, а столбец primary_key не является частью выбранных столбцов, ваш $model->save() вернет true, но ничего не будет сохранено в базе данных.

Таким образом, вместо \App\Users::where(...)->first(['email']) лучше выполнить \App\Users::where(...)->first(['id','email']), где id — это primary_key, определенное в целевой таблице.

Если (иногда микрооптимизация), достигаемая путем извлечения только нескольких столбцов, на самом деле не важна для вас, вы можете просто получить все столбцы, выполнив \App\Users::where(...)->first(), и в этом случае вам не нужно беспокоиться об имени столбца primary_key, поскольку будут загружены все столбцы.

person Damilola Olowookere    schedule 23.05.2019

Проверьте свою таблицу, если первичный ключ не является идентификатором (имя столбца должно быть только строчными буквами), если вы установили имя столбца с другим ключом, а затем поместите код в свою модель следующим образом.

protected $primaryKey   = 'Id';

person Sk Bindas    schedule 16.04.2021

Для использования метода save() для обновления или удаления, если в базе данных есть первичный ключ, отличный от id. нужно объявить атрибут primaryKey = в модели, он будет работать

person Khương Nguyễn    schedule 16.04.2021

Я столкнулся с той же проблемой и нашел обходной путь. Я обнаружил, что не могу save() создать свою модель в функции с именем {{ generateUrl() }} в моем шаблоне home.blade.php. Что сработало, так это перемещение вызова save() в контроллер, который return является шаблоном home.blade.php. (IE, save()ing до того, как представление будет returned, а затем выполнять операции чтения только в пределах {{ generateUrl() }}.)

Я генерировал (и создаю) state для ввода URL-адреса при загрузке страницы:

<!--views/home.blade.php-->

<a href="{{ EveAuth::generateUrl() }}">Add Character</a>

Ниже показано, что не сработало.

// Providers/EveAuth.php

function generateUrl()
{
    $authedUser = auth()->user();
    if (!$authedUser) {
        return "#";
    }
    $user = User::find($authedUser->id);
    $user->state = str_random(16);
    $user->save();

    $baseUrl = 'https://login.eveonline.com/oauth/authorize?state=';

    return $baseUrl . $user->state;
}

Это удалось find() User из базы данных, но не удалось save() вернуть обратно. Никаких ошибок не выдавалось. Функция работала правильно... пока позже я не попытался прочитать state User и не обнаружил, что она не соответствует state в URL-адресе.

Вот что сработало.

Вместо того, чтобы пытаться save() создать User во время сборки страницы, я сгенерировал state, save()d, а затем отрендерил страницу:

// routes/web.php

Route::get('/', 'HomeController@index');

Приземление в корневом каталоге отправляет вас к функции index() HomeController.php:

// Controllers/HomeController.php

public function index()
{
    $authedUser = auth()->user();
    if ($authedUser) {
        $user = User::find($authedUser->id);
        $user->state = str_random(16);
        $user->save();
    }
    return view('home');
}

Затем при создании URL-адреса мне не нужно было save() User, а только читать из него:

// Providers/EveAuth.php

function generateUrl()
{
    $authedUser = auth()->user();
    $user = User::find($authedUser->id);

    $baseUrl = 'https://login.eveonline.com/oauth/authorize?state=';

    return $baseUrl . $user->state;
}

Это сработало! Единственная разница (насколько я вижу) заключается в том, что я save()составляю модель до начала сборки страницы, а не во время сборки страницы.

person Cameron Hudson    schedule 21.07.2018