I'm getting this error message when updating the data via the PUT method on Postman.
No query results for model [App\Models\Post].
Code
public function store(Request $request)
{
$post = $request->isMethod('put') ? Post::findOrFail
($request->post_id): new Post;
$post->id= $request->input('id');
$post->title= $request->input('title');
$post->body= $request->input('body');
if($post->save()){
return response($post);
}
}
Reference: https://github.com/Devgroup-Asia/lumenblog/blob/main/app/Http/Controllers/PostsController.php
The issue is due to this below code.
Post::findOrFail($request->post_id)
Post with $request->post_id doesnot found.
You may be missing to send post_id from form
So I'm a total newbie in laravel and I don't know if it can be done but I saw that in the controller I can display data of a specific 'id' with this in my api.php:
Route::get('books/{id}', 'App\Http\Controllers\BooksController#getBookById');
And this in my BookController.php :
public function getBookByAuthor($id) {
$book = Books::find($id);
if (is_null($book)){
return response()->json(['message' => 'Book Not Found.'], 404);
}
return response()->json($book::find($id), 200);
}
I'm using Angular for the front and I have a searchbar to search by 'title' of a book, so in my database I have a column 'title' and I want to fetch data by 'title' instead of 'id'.
Is it possible ? And if yes how ?
I'm thinking you're wanting to retrieve the book based on user input...? You can inject the request in your method. Also you don't need to explicitly handle 404 and response codes.
use Illuminate\Http\Request;
use App\Models\Book;
public function getBookByAuthor(Request $request): Response
{
$input = $request->validate([
'title' => 'required|alpha_dash' // validate
]);
return Book::where('title', 'like', "%{$input['title']}%")
->firstOrFail();
}
Validation docs
I want to save new post from form in my database , I have title and body in $request and want to save logged in user's id in the post. how can i handle it in model or validation?
Validator::make($request->all(), [
'title' => ['required'],
'body' => ['required'],
])->validate();
Post::create($request->all());
I can save it as below:
$post = new Flight;
$post->title = $request->title;
$post->body = $request->body;
$post->user_id = $request->user()->id;
$post->save();
but I want better way.
user_id is not nullable in DB
Here's a sample code that I always use.
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
...
public function store(Request $request)
{
// take only fields that have been validated.
// instead of inserting all the request body
$validated = $request->validate([
'title' => 'required',
'body' => 'required'
]);
// use FormRequest if want seperate validation and its much cleaner
// something like this
// store(StorePostRequest $request)
// $validated = $request->validated();
// instead of declaring use Auth
// u can just use $request->user();
$post = $request->user()->post()->create($validated);
// or if you dont have the relation inside the user model
$post = Post::create(['user_id' => auth()->id()] + $validated);
return new JsonResponse($post, Response::HTTP_CREATED);
}
Include Authentication Facade in Controller header use Auth;
than you can use
$post->user_id = Auth::id();
you can use both Auth::user()->id or Auth::id(). Thanks
You can use form request validation to extract validation login from the controller (see documentation).
I'd suggest to use $request->validated() method instead of $request->all() to make sure that only expected fields are passed to the model.
Also, you can use a auth()->id() helper method to get logged in user's ID.
So, the controller function could be as follows:
Post::create(array_merge($request->validated(), ['user_id' => auth()->id()]));
I'm creating a blog post from a form using Laravel, and passing the title and body through to the create method in the PostsController.
The slug has to be unique, so although the following works, it fails when I use a duplicate title.
I intended on appending the $post->id to the slug, so this-is-the-post-title would become this-is-the-post-title-12
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use Session;
use Carbon\Carbon;
class PostController extends Controller
{
public function store(Request $request) {
$this->validate($request, [
'title' => 'required|max:255',
'body' => 'required'
]);
$post = new Post;
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->slug = str_slug($request->input('title'), '-');
$post->save();
Session::flash('success', 'The blog post was successfully saved!');
return redirect()->route('posts.show', $post->id);
}
My initial thought was to concatenate $post->id to the end of the slug, but it doesn't work.
I'm assuming that this is because the id isn't assigned until the save()?
Is there a way to get the id that is going to be used?
I thought of just returning the number of rows in the db, and adding one, but that would fail if two people posted at the same time.
(I'm fairly new to Laravel and taught myself PHP, so this may be glaringly obvious/simple, but any help is appreciated.)
Save first then update later:
$post = \DB::transaction(function() use($request) {
$post = new Post;
$post->title = $request->input('title');
$post->body = $request->input('body');
$post->slug = uniqid(); //to avoid unique column conflict, it will be overwritten
$post->save();
$post->slug = str_slug($request->input('title').' '.$post->id, '-');
$post->save();
return $post;
});
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.