When updating my Post model, I run:
$post->title = request('title');
$post->body = request('body');
$post->save();
This does not update my post. But it should according to the Laravel docs on updating Eloquent models. Why is my model not being updated?
I get no errors.
The post does not get updated in the db.
Besides not being updated in the db, nothing else seems odd. No errors. Behavior as normal.
Result of running this test to see if save succeeded was true.
This Laravel thread was no help
Post model:
class Post extends Model
{
protected $fillable = [
'type',
'title',
'body',
'user_id',
];
....
}
Post controller:
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('/');
}
Bonus info
Running dd($post->save()) returns true.
Running
$post->save();
$fetchedPost = Post::find($post->id);
dd($fetchedPost);
shows me that $fetchedPost is the same post as before without the updated data.
Check your database table if the 'id' column is in uppercase 'ID'. Changing it to lower case allowed my save() method to work.
I had the same and turned out to be because I was filtering the output columns without the primary key.
$rows = MyModel::where('...')->select('col2', 'col3')->get();
foreach($rows as $row){
$rows->viewed = 1;
$rows->save();
}
Fixed with
$rows = MyModel::where('...')->select('primary_key', 'col2', 'col3')->get();
Makes perfect sense on review, without the primary key available the update command will be on Null.
I had the same problem and changing the way I fetch the model solved it!
Was not saving even though everything was supposedly working just as you have mentioned:
$user = User::find($id)->first();
This is working:
$user = User::find($id);
You have to make sure that the instance that you are calling save() on has the attribute id
Since Laravel 5.5 laravel have change some validation mechanism I guess you need to try this way.
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('/');
}
Running dd() inside a DB::transaction will cause a rollback, and the data in database will not change.
The reason being, that transaction will only save the changes to the database at the very end. Ergo, the act of running "dump and die" will naturally cause the script to cease and no therefore no database changes.
Check your table if primary key is not id ("column name should be in small letters only") if you have set column name with different key then put code in your Model like this
protected $primaryKey = 'Id';
So this might be one of the possible solution in your case also if your column name contains capital letters.
Yes this worked for me fine,
You should have column names in small letter,
If you don't have then mention it in the model file, mainly for primaryKey by which your model will try to access database.
For use save () method to update or delete if the database has a primary key other than "id". need to declare the attribute primaryKey = "" in the model, it will work
Try this
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('/');
}
In my experience, if you select an Eloquent model from the db and the primary_key column is not part of the fetched columns, your $model->save() will return true but nothing is persisted to the database.
So, instead of doing \App\Users::where(...)->first(['email']), rather do \App\Users::where(...)->first(['id','email']), where id is the primary_key defined on the target table.
If the (sometimes micro-optimization) achieved by retrieving only a few columns is not really of importance to you, you can just fetch all columns by doing \App\Users::where(...)->first(), in which case you do not need to bother about the name of the primary_key column since all the columns will be fetched.
If you using transactions.
Do not forget call DB::commit();
It must look like this:
try{
DB::beginTransaction();
// Model changes
$model->save();
DB::commit();
}catch (\PDOException $e) {
DB::rollBack();
}
I have the same issue although there are try / catch block in controller#action() but there were no response, it just stops at $model->save(); there is no log entry either in apache error.log or laravel.log. I have just wrapped the save() with try / cactch as follows, that helped me to figure out the issue
try{
$model->save();
}
catch (\PDOException $e) {
echo $e->getMessage();
}
I have been experiencing the same issue and found a workaround. I found that I was unable to save() my model within a function called {{ generateUrl() }} on my home.blade.php template. What worked was moving the save() call to the controller that returns the home.blade.php template. (IE, save()ing before the view is returned, then only performing read operations within {{ generateUrl() }}.)
I was (and am) generating a state to put in a URL on page load:
<!--views/home.blade.php-->
Add Character
Below is what did not work.
// 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;
}
This was able to find() the User from the database, but it was unable to save() it back. No errors were produced. The function appeared to work properly... until I tried to read the User's state later, and found that it did not match the state in the URL.
Here is what did work.
Instead of trying to save() my User as the page was being assembled, I generated the state, save()d it, then rendered the page:
// routes/web.php
Route::get('/', 'HomeController#index');
Landing at the root directory sends you to the index() function of 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');
}
Then, when generating the URL, I did not have to save() the User, only read from it:
// 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;
}
This worked! The only difference (as far as I see) is that I'm save()ing the model before page assembly begins, as opposed to during page assembly.
I am working with laravel 5.5 to update entries. The problem is after changing the primary key 'id', which is elequoent default pk to 'project_id'. adding an item works fine but updating an item is not working properly. Here is the error I am getting.
Method save does not exist.
Here is my Model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
protected $primaryKey = 'project_id';
public function user()
{
return $this->belongsTo(User::class);
}
public function tasks()
{
return $this->hasMany(Task::class);
}
}
Here is my controller function.
public function editProject($id){
$project = Project::where('project_id', $id)->firstOrFail();
$data = ["project_info" => $project];
return view('projects.edit')->with($data);
}
public function updateProject(Request $request){
$data = $request->all();
$validator = Validator::make($data, [
'project_title' => 'required',
'project_description' => 'required',
'project_start_date' => 'required',
'project_end_date' => 'required',
'project_status' => 'required',
]);
$response = [];
if ($validator->fails()){
$response["errors"] = [$validator->messages()->first()];
$response["success"] = false;
return json_encode($response);
}
else{
$project = Project::where("project_id", $request->input('project_id'))->get();
$project->project_title = $request->project_title;
$project->user_id = Session::get('user_id');
$project->project_description = $request->project_description;
$project->project_start_date = $request->project_start_date;
$project->project_end_date = $request->project_end_date;
$project->project_status = $request->project_status;
$project->save();
return redirect('/listProjects');
}
}
Using get() returns a collection. Despite the fact you are passing in a 'unique' ID, the project_id, it will still return a collection - the collection will simply have one element in it.
Subsequently, your code will not work as you have experienced, or at least not without a few changes to make $project reference the first element in the collection.
It's a quick fix though, just change this:
$project = Project::where("project_id", $request->input('project_id'))->get();
to this:
$project = Project::where("project_id", $request->input('project_id'))->first();
By using first(), eloquent will return the first element that matches the query and actually return the element (as opposed to a collection with one element) and so you can directly edit and save it.
Here is the solution I found.
$project_id = $request->input('project_id');
$project = Project::find($project_id);
$project->save();
You can find it by id using
Project::find($id);
Or get the first element like James said:
$project = Project::where("project_id", $request->input('project_id'))->first();
Update Method:
public function update(UserUpdateRequest $request, Users $uzytkownik)
{
$this->authorize('update', $uzytkownik);
if ( $uzytkownik->update([
'birth' => $request->birth,
'sex' => $request->sex,
'about' => $request->about,
]) )
{
return 1;
}
return 0;
}
On update here in page 1 appears. Like it did the thing.
But in db nothing has changed.
$uzytkownik is proper user, and
This is the dd($uzytkownik);
And below dd($request->birth.'---'.$request->sex.'---'.$request->about); which shows proper inputs
Why it doesn't work properly?
As per the documentation
Mass Assignment
You may also use the create method to save a new model in a single line. The inserted model instance will be returned to you from the method. However, before doing so, you will need to specify either a fillable or guarded attribute on the model, as all Eloquent models protect against mass-assignment by default.
You need to make sure $fillable or $guarded is correctly set otherwise changes may not be persistant.
You can do what you want like this too:
public function update(UserUpdateRequest $request, Users $uzytkownik)
{
$this->authorize('update', $uzytkownik);
$uzytkownik->birth = $request->birth;
$uzytkownik->sex = $request->sex;
$uzytkownik->about = $request->about;
if ( $uzytkownik->save() )
{
return 1;
}
return 0;
}
I have been trying to save data from dynamic form in Laravel 5.3. But I cannot save it as array. The error shows
Argument 1 passed to Illuminate\Database\Grammar::parameterize() must be of the type array, string given...
Form:
<select class="form-control-sm" name="client_id[]">
<input type="text" class="form-control-sm" name="amount[]">
Model:
protected $fillable = ['client_id', 'amount'];
public function client()
{
return $this->belongsTo('App\Client');
}
Controller:
public function store(Request $request)
{
$count = Client::count();
$payment = Payment::create(['amount' => $request->amount,
'client_id' => $request->client_id,
]);
$payment->save();
return redirect()->action('PaymentController#index');
}
Please help on this. Thank you.
you are submitting form with array of text fields and select box, try
below
public function store(Request $request)
{
$count = Client::count();
foreach( $request->client_id as $key=>$val){
$payment = Payment::create(['amount' => $request->amount[$key],
'client_id' => $val,
]);
}
return redirect()->action('PaymentController#index');
}
Ty to create the record like this:
$payment = Payment::create($request->input);
And change you redirect action to this:
View::make('path/to/view/')
or just use just back(); just to test if it works
I'm currently using the below code to insert data in a table:
<?php
public function saveDetailsCompany()
{
$post = Input::All();
$data = new Company;
$data->nombre = $post['name'];
$data->direccion = $post['address'];
$data->telefono = $post['phone'];
$data->email = $post['email'];
$data->giro = $post['type'];
$data->fecha_registro = date("Y-m-d H:i:s");
$data->fecha_modificacion = date("Y-m-d H:i:s");
if ($data->save()) {
return Response::json(array('success' => true), 200);
}
}
I want to return the last ID inserted but I don't know how to get it.
Kind regards!
After save, $data->id should be the last id inserted.
$data->save();
$data->id;
Can be used like this.
return Response::json(array('success' => true, 'last_insert_id' => $data->id), 200);
For updated laravel version try this
return response()->json(array('success' => true, 'last_insert_id' => $data->id), 200);
xdazz is right in this case, but for the benefit of future visitors who might be using DB::statement or DB::insert, there is another way:
DB::getPdo()->lastInsertId();
If the table has an auto-incrementing id, use the insertGetId method to insert a record and then retrieve the ID:
$id = DB::table('users')->insertGetId([
'email' => 'john#example.com',
'votes' => 0
]);
Refer: https://laravel.com/docs/5.1/queries#inserts
For anyone who also likes how Jeffrey Way uses Model::create() in his Laracasts 5 tutorials, where he just sends the Request straight into the database without explicitly setting each field in the controller, and using the model's $fillable for mass assignment (very important, for anyone new and using this way): I read a lot of people using insertGetId() but unfortunately this does not respect the $fillable whitelist so you'll get errors with it trying to insert _token and anything that isn't a field in the database, end up setting things you want to filter, etc. That bummed me out, because I want to use mass assignment and overall write less code when possible. Fortunately Eloquent's create method just wraps the save method (what #xdazz cited above), so you can still pull the last created ID...
public function store() {
$input = Request::all();
$id = Company::create($input)->id;
return redirect('company/'.$id);
}
**** For Laravel ****
Firstly create an object, Then set attributes value for that object, Then save the object record, and then get the last inserted id. such as
$user = new User();
$user->name = 'John';
$user->save();
// Now Getting The Last inserted id
$insertedId = $user->id;
echo $insertedId ;
There are several ways to get the last inserted id. All are based on what method do you used when inserting. In your case you can get last Id like the following:
$data->save();
$data->id;
For others who need to know how can they get last inserted id if they use other insert methods here is how:
Using create() method
$book = Book::create(['name'=>'Laravel Warrior']);
$lastId = $book->id;
Using insertGetId()
$id = DB::table('books')->insertGetId( ['name' => 'Laravel warrior'] ); $lastId = $id;
Using lastInsertId() method
$lastId = DB::getPdo()->lastInsertId();
Reference https://easycodesolution.com/2020/08/22/last-inserted-id-in-laravel/
In laravel 5: you can do this:
use App\Http\Requests\UserStoreRequest;
class UserController extends Controller {
private $user;
public function __construct( User $user )
{
$this->user = $user;
}
public function store( UserStoreRequest $request )
{
$user= $this->user->create([
'name' => $request['name'],
'email' => $request['email'],
'password' => Hash::make($request['password'])
]);
$lastInsertedId= $user->id;
}
}
This worked for me in laravel 4.2
$id = User::insertGetId([
'username' => Input::get('username'),
'password' => Hash::make('password'),
'active' => 0
]);
Here's an example:
public static function saveTutorial(){
$data = Input::all();
$Tut = new Tutorial;
$Tut->title = $data['title'];
$Tut->tutorial = $data['tutorial'];
$Tut->save();
$LastInsertId = $Tut->id;
return Response::json(array('success' => true,'last_id'=>$LastInsertId), 200);
}
Use insertGetId to insert and get inserted id at the same time
From doc
If the table has an auto-incrementing id, use the insertGetId method
to insert a record and then retrieve the ID:
By Model
$id = Model::insertGetId(["name"=>"Niklesh","email"=>"myemail#gmail.com"]);
By DB
$id = DB::table('users')->insertGetId(["name"=>"Niklesh","email"=>"myemail#gmail.com"]);
For more details : https://laravel.com/docs/5.5/queries#inserts
For insert()
Example:
$data1 = array(
'company_id' => $company_id,
'branch_id' => $branch_id
);
$insert_id = CreditVoucher::insert($data1);
$id = DB::getPdo()->lastInsertId();
dd($id);
Here is how we can get last inserted id in Laravel 4
public function store()
{
$input = Input::all();
$validation = Validator::make($input, user::$rules);
if ($validation->passes())
{
$user= $this->user->create(array(
'name' => Input::get('name'),
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password')),
));
$lastInsertedId= $user->id; //get last inserted record's user id value
$userId= array('user_id'=>$lastInsertedId); //put this value equal to datatable column name where it will be saved
$user->update($userId); //update newly created record by storing the value of last inserted id
return Redirect::route('users.index');
}
return Redirect::route('users.create')->withInput()->withErrors($validation)->with('message', 'There were validation errors.');
}
Although this question is a bit dated. My quick and dirty solution would look like this:
$last_entry = Model::latest()->first();
But I guess it's vulnerable to race conditions on highly frequented databases.
After saving model, the initialized instance has the id:
$report = new Report();
$report->user_id = $request->user_id;
$report->patient_id = $request->patient_id;
$report->diseases_id = $request->modality;
$isReportCreated = $report->save();
return $report->id; // this will return the saved report id
You can easily fetch last inserted record Id
$user = User::create($userData);
$lastId = $user->value('id');
It's an awesome trick to fetch Id from the last inserted record in the DB.
After
$data->save()
$data->id will give you the inserted id,
Note: If your autoincrement column name is sno then you should use
$data->sno and not $data->id
After saving a record in database, you can access id by $data->id
return Response::json(['success' => true, 'last_insert_id' => $data->id], 200)
In Laravel 5.2 i would make it as clean as possible:
public function saveContact(Request $request, Contact $contact)
{
$create = $contact->create($request->all());
return response()->json($create->id, 201);
}
For Laravel, If you insert a new record and call $data->save() this function executes an INSERT query and returns the primary key value (i.e. id by default).
You can use following code:
if($data->save()) {
return Response::json(array('status' => 1, 'primary_id'=>$data->id), 200);
}
You can do this:
$result=app('db')->insert("INSERT INTO table...");
$lastInsertId=app('db')->getPdo()->lastInsertId();
$objPost = new Post;
$objPost->title = 'Title';
$objPost->description = 'Description';
$objPost->save();
$recId = $objPost->id; // If Id in table column name if other then id then user the other column name
return Response::json(['success' => true,'id' => $recId], 200);
For get last inserted id in database
You can use
$data = new YourModelName;
$data->name = 'Some Value';
$data->email = 'abc#mail.com';
$data->save();
$lastInsertedId = $data->id;
here $lastInsertedId will gives you last inserted auto increment id.
The shortest way is probably a call of the refresh() on the model:
public function create(array $data): MyModel
{
$myModel = new MyModel($dataArray);
$myModel->saveOrFail();
return $myModel->refresh();
}
You can also try like this:
public function storeAndLastInrestedId() {
$data = new ModelName();
$data->title = $request->title;
$data->save();
$last_insert_id = $data->id;
return $last_insert_id;
}
Here it is how it worked for me, family_id is the primary key with auto increment I am using Laravel7
public function store(Request $request){
$family = new Family();
$family->family_name = $request->get('FamilyName');
$family->family_no = $request->get('FamilyNo');
$family->save();
//family_id is the primary key and auto increment
return redirect('/family/detail/' . $family->family_id);
}
Also in the Model Family file which extends Model, should have the increment set to true otherwise the above $family-->family_id will return empty
public $incrementing = true;
Using Eloquent Model
$user = new Report();
$user->email= 'johndoe#example.com';
$user->save();
$lastId = $user->id;
Using Query Builder
$lastId = DB::table('reports')->insertGetId(['email' => 'johndoe#example.com']);
After Saving $data->save(). all data is pushed inside $data. As this is an object and the current row is just saved recently inside $data. so last insertId will be found inside $data->id.
Response code will be:
return Response::json(array('success' => true, 'last_insert_id' => $data->id), 200);
You can get last inserted id with same object you call save method;
$data->save();
$inserted_id = $data->id;
So you can simply write:
if ($data->save()) {
return Response::json(array('success' => true,'inserted_id'=>$data->id), 200);
}
public function store( UserStoreRequest $request ) {
$input = $request->all();
$user = User::create($input);
$userId=$user->id
}
Using Eloquent Model
use App\Company;
public function saveDetailsCompany(Request $request)
{
$createcompany=Company::create(['nombre'=>$request->input('name'),'direccion'=>$request->input('address'),'telefono'=>$request->input('phone'),'email'=>$request->input('emaile'),'giro'=>$request->input('type')]);
// Last Inserted Row ID
echo $createcompany->id;
}
Using Query Builder
$createcompany=DB::table('company')->create(['nombre'=>$request->input('name'),'direccion'=>$request->input('address'),'telefono'=>$request->input('phone'),'email'=>$request->input('emaile'),'giro'=>$request->input('type')]);
echo $createcompany->id;
For more methods to get Last Inserted Row id in Laravel : http://phpnotebook.com/95-laravel/127-3-methods-to-get-last-inserted-row-id-in-laravel