Laravel 9 Failing to update data in DB - php

I am building a blog using Laravel 9 and my update method for some unknown reason fails to update
My code Samples
Model
class Anime extends Model
{
use HasFactory;
protected $table = 'anime';
protected $primaryKey = 'id';
protected $fillable = ['anime_title','user_id','blog_title','description','slug','anime_image_profile'];
public function blogInformation() {
return $this->hasMany(BlogInfo::class);
}
public function getRouteKeyName()
{
return 'slug';
}
// protected $hidden = 'id';
}
Controller
public function update(ValidateAnimeBlogRequest $request, $id)
{
$request->validated();
/*Update the details in the database by ID*/
$update_data = Anime::findOrFail($id);
$update_data = new Anime;
$update_data->anime_title = $request->input('anime_title');
$update_data->blog_title = $request->input('blog_title');
$update_data->user_id = auth()->user()->id;
$update_data->description = $request->input('description');
$update_data->slug = Str::slug($request->input('blog_title'));
/*Check if the user also wanted to update the image*/
if($request->hasFile('anime_image_profile')) {
$path_to_images = 'images/anime_image_profile/' . $update_data->anime_image_profile;
if(File::exists($path_to_images)) {
File::delete($path_to_images);
}
$new_file_name = '9anime' . '-' . time() . '-' . $request->name . '.' . $request->anime_image_profile->extension();
$request->anime_image_profile->move(public_path('images/anime_image_profile'), $new_file_name);
$update_data->anime_image_profile = $new_file_name;
}
if($update_data->update()) {
redirect('/');
}
dd('Error');
}
ValidateAnimeBlogRequest
public function rules()
{
return [
'anime_title' => 'required | min:2', new nameRegex,
'blog_title' => ['required','min:5', new nameRegex],
'description' => ['required','min:1000'],
'premiered' => ['required'],
'genre' => ['required', new nameRegex],
'licensors' => ['required', new nameRegex],
'studio' => ['required', new nameRegex],
'anime_image_profile' => 'required | mimes:jpeg,jpg,png | max:5408'
];
}
My blade file
<form enctype="multipart/form-data" autocomplete="off" action="/blog/{{$anime['id']}}" method="POST">
#method('PUT')
#csrf
I set up a custom check just in case
if($update_data->update()) {
redirect('/');
}
dd('Error');
The output on my webpage from this is "Error" // app\Http\Controllers\AnimeController.php:156
And when I dd($update_data) I see that the data has been updated yet it does not get sent to the database.
I tried replacing $update_data->update() with $update_data->save() but that now creates new data in the DB instead of updating the existing one

You can keep it as the save() method. Just update the lines above where you are creating a new Anime() instance to only be created if the record cannot be found via $id from the line above.
public function update(ValidateAnimeBlogRequest $request, $id)
{
$request->validated();
/*Update the details in the database by ID*/
$update_data = Anime::findOrFail($id);
if(!$update_data) {
$update_data = new Anime;
}
$update_data->anime_title = $request->input('anime_title');
$update_data->blog_title = $request->input('blog_title');
$update_data->user_id = auth()->user()->id;
$update_data->description = $request->input('description');
$update_data->slug = Str::slug($request->input('blog_title'));
/*Check if the user also wanted to update the image*/
if($request->hasFile('anime_image_profile')) {
$path_to_images = 'images/anime_image_profile/' . $update_data->anime_image_profile;
if(File::exists($path_to_images)) {
File::delete($path_to_images);
}
$new_file_name = '9anime' . '-' . time() . '-' . $request->name . '.' . $request->anime_image_profile->extension();
$request->anime_image_profile->move(public_path('images/anime_image_profile'), $new_file_name);
$update_data->anime_image_profile = $new_file_name;
}
if($update_data->save()) {
redirect('/');
}
dd('Error');
}
This will create a new instance only if a record is not found and won't give a new db record

Related

Unable to update data by Eloquent in Laravel, phpunit

I am developing an application using Laravel, Eloquent as ORM, phpunit for unit testing. But i am not able to update data in database. Though there is no exception, warning or error. If the object of the model class checked in laravel, before update and after update, it is showing that data has been changed in the model class but when checking the database, found that data is not being changed.
Model Class
class Post extends Model
{
protected $table = "posts";
protected $fillable = [
'id',
'user_id',
'title',
'description',
'total_needed',
'total_collected',
'total_expanse',
'start_date',
'end_date',
'active',
'updated_at',
'created_at',
];
}//class
Repository Code
class Post_Repo_Impl implements Post_Repo_I
{
public function update(Post $postUpdate)
{
$raedOld = false;
$updateStatus = false;
try {
$psot_id = $postUpdate->id;
$postOrgin = Post::find($psot_id);
$raedOld = true;
} catch (Exception $e) {
error_log("Post Update : failed to read existig post.");
}
if ($raedOld) {
try {
//line 1
echo "\n" . $postOrgin->title . "\n";
$this->setPostValues($postOrgin, $postUpdate)->update();
//line 2
echo "\n" . $postOrgin->title . "\n";
$updateStatus = true;
} catch (Exception $e) {
error_log("Post Update : Failed to save updated post." . "\n\n" . $e);
}
}
return $updateStatus;
} //update
}
Line 1 and Line 2, not printing same value. Line 2 printing the changed value.
Unit Test code
class RepoPost extends TestCase
{
public function testMain()
{
echo "\n >----------- Test Main : ---------> \n";
$this->postUpdate();
} //mother test
public function postUpdate()
{
$postDummyUpdate = new Post();
$postDummyUpdate->id = '2';
$postDummyUpdate->user_id = 'Tst';
$postDummyUpdate->title = 'Post Updated Repo Test........';
$postDummyUpdate->description = 'UnitTesting of URLs';
$postDummyUpdate->total_needed = '2000';
$postDummyUpdate->total_collected = '1000';
$postDummyUpdate->total_expanse = '500';
$postDummyUpdate->start_date = '22-09-2019';
$postDummyUpdate->end_date = '22-10-2019';
$postDummyUpdate->active = '1';
$postDummyUpdate->updated_at = '2019-09-24';
$postDummyUpdate->created_at = '2019-09-22';
echo '\n----PostUpdate----\n';
$postRepoSave = $this->getRepoPostImpl();
dd($postRepoSave->update($postDummyUpdate));
if ($postRepoSave == false) {
error_log("\n\nTest : Data Save Failed.");
} else {
error_log("Saved Post ID : " . $postRepoSave);
}
}
public function getRepoPostImpl()
{
return new Post_Repo_Impl();
}
}
In the test code it is returning true.

Having a problem with a pivot table on Laravel

I have a form with two pivot tables. One of them works just fine but I can't seem to be making the second one work despite them being quite similar. The one not working is for an image table called 'photos' and the form upload in called 'releases'. I called the pivot table 'photo_releases' with the 'photo_id' and a 'release_id' field.
DB Pivot Table
here is the release Modal
class Release extends Model
{
public function photos()
{
return $this->belongsToMany('App\Photo', 'photo_releases', 'release_id', 'photo_id');
}
}
and the photo modal
class Photo extends Model
{
public function releases()
{
return $this->belongsToMany('App\Release', 'photo_releases', 'photo_id', 'release_id');
}
}
and the ReleaseController
public function store(ReleasesCreateRequest $request)
{
$input = $request->all();
$user = Auth::user();
if ($file = $request->file('photo_01')) {
$file_name = preg_replace("/[^a-zA-Z0-9.]/", "", $file->getClientOriginalName());
$name = time() . 'photo_01' . $file_name;
$file->move('images', $name);
$input['photo_01'] = $name;
$photo = new Photo();
$photo->url = $input['photo_01'];
$photo->save();
}
$release = Release::create($request->except('release_id'));
dd($request->except('release_id'), $request->get('photo_id', []), $request->get('artiste_id', []));
$release->photos()->attach($request->get('photo_id', []));
$release->artistes()->attach($request->get('artiste_id', []));
return redirect('/admin06000/releases');
}
There is two pivot tables being used in this function. the one using
"$release->artistes()->attach($request->get('artiste_id', []));"
is working correctly but the photos is not. The url is being logged in the correct DB and the image is uploading fine, but the pivot table is not being updated. If anyone could help it would be greatly appriciated.
try This if you need some select in relation ship change
with('photos')
to
with(['photos'=>function($query){$query->where(....)->get();}])...
use Image;
use Illuminate\Support\Facades\Input;
...
public function store(ReleasesCreateRequest $request)
{
$input = $request->all();
$user = Auth::user();
if ($file = $request->file('photo_01'))
{
$image= Input::file('photo_01');
$name = time().'photo_01'.'.'.$image->getClientOriginalExtension();
$path=public_path('/YourPath/'.$name);
Image::make($image->getRealPath())->save($path);
$photo = new Photo();
$photo->url = '/YourPath/'.$name;
$photo->save();
}
$release = Release::create
([
'release_field'=>$amount,
'release_field2'=>$amount2,
....
]);
$release->with('photos')->with(artistes)->get();
}```

Laravel - Update dynamic fields in relationship table

I have two tables Cars and Features, where Cars and Features have one to many relations.
Cars table has ID, Name columns. Features tables has ID, CarID, Name, Feat Image.
When I update the details, Cars table updated Features table is not updated.
Cars.php
public function features() {
return $this->hasMany(Features::class, 'cars_id');
}
Features.php
public function feat()
{
return $this->belongsTo(Cars::class, 'cars_id');
}
Controller.php
Update Method
public function update(Request $request, $id)
{
$requestData = $request->all();
$cars = Cars::findOrFail($id);
$features = Features::with(['feat'])->where('cars_id', $cars->id)->get();
if($cars->update($requestData))
{
if ($request->hasFile('feat_img'))
{
$file = $request->file('feat_img');
$rules = array('file' => 'required|mimes:png,gif,jpeg');
$validator = \Illuminate\Support\Facades\Validator::make(array('file'=> $file), $rules);
if($validator->passes())
{
$name = $request->name;
for ($i=0; $i < count(request('name')); ++$i)
{
$features->name = request('name')[$i];
$feat_img_name = uniqid() . '.' . $images[$i]->getClientOriginalExtension();
$images[$i]->move(public_path('/images/'), $feat_img_name);
$features->feat_img = '/images/'.$feat_img_name;
}
}
}
$cars->features()->update($features);
session()->flash('message', 'Product updated successfully.');
return redirect('/');
}
Store Method
public function store(Request $request, Cars $cars)
{
$cars= new Cars;
$cars->name= request('name');
$cars->image= $image;
if($cars->save())
{
$features= [];
$images = $request->file('feat_img');
$name = $request->name;
for ($i=0; $i < count(request('name')); ++$i)
{
$features= new Features;
$features->name = request('name')[$i];
$feat_img_name = uniqid() . '.' . $images[$i]->getClientOriginalExtension();
$images[$i]->move(public_path('/images/'), $feat_img_name);
$features->feat_img = '/images/'.$feat_img_name;
$cars->features()->save($features);
}
session()->flash('message','Product successfully added.');
return redirect ('/');
}
}
Use update like this :
$features=Features::findOrFail(id);
$features->field=$value;
$features->save();
Hope this works.

Laravel 5 Validation in controller

I have 2 methods in my Controller and I need to validate it but I don't know how.
1st method which should allow all image extensions:
public function testing(Request $request) {
if($request->hasFile('img')) {
$image = Input::file('img');
$filename = time() . '.' . $image->getClientOriginalExtension();
$path = public_path('images/' . $filename);
Image::make($image->getRealPath())->resize(200, 200)->save($path);
$file = $request->file('img');
return ['url' => url('images/' . $filename)];
}
}
2nd method which should only allow 1 word and if there is space, trim it into 1 word:
public function postDB(Request $request) {
$newName = $request->input('newName');
$websites = new Website();
$websites->name = $newName;
$websites->save();
return redirect('template')->with('status', 'Website has been saved successfully!');
}
First write new Request for your data
php artisan make:request ImageRequest
Than write in ImageRequest:
public function authorize()
{
return true;
}
public function rules()
{
return [
'img' => 'file|image',
]
}
If you want to customize error messages:
public function messages()
{
return [
'img.image' => 'Some custom message ...',
];
}
Last inject request to your method (don`t forget about use App\Http\Requests):
public function testing(Requests\ImageRequest $request) {
//for retrieving validation errors use:
$imgErrors = $errors->first('img');
}
More information about Form Request Validation
Or you can use Validator facade (don`t forget about use Validator):
$validator = Validator::make(
$image, [
'img' => 'file|image',
]
);
More information about A Note On Optional Fields

How to make Laravel controller store file upload with a relationship

I am trying to store an uploaded file with a relationship to an Employee model. I am unable to retrieve the employee id after uploading the file to save it to the DB table as a foreign key.
Routes:
Route::resource('employees', 'EmployeesController');
Route::post('documents', 'DocumentsController#createdocument')
So I am on a URL that says http://localhost/public/employees/8 when I hit upload it redirects to http://localhost/public/documents and the file does upload but shows error when writing to DB.
Here is my code. How can I do it?
public function createdocument(Request $request, Employee $id)
{
$file = $request->file('file');
$allowedFileTypes = config('app.allowedFileTypes');
$maxFileSize = config('app.maxFileSize');
$rules = [
'file' => 'required|mimes:'.$allowedFileTypes.'|max:'.$maxFileSize
];
$this->validate($request, $rules);
$time = time(); // Generates a random string of 20 characters
$filename = ($time.'_'.($file->getClientOriginalName())); // Prepend the filename with
$destinationPath = config('app.fileDestinationPath').'/'.$filename;
$uploaded = Storage::put($destinationPath, file_get_contents($file->getRealPath()));
if($uploaded){
$employee = Employee::find($id);
$empdoc = new EmpDocuments();
$empdoc->name = $filename;
$empdoc->employee_id = $employee->id;
$empdoc->save();
}
return redirect('employees');
}
These are my models.
Employee.php
public function EmpDocuments()
{
return $this->hasMany('App\EmpDocuments');
}
public function createdocument(){
return $this->EmpDocuments()->create([
'name' => $filename,
'employee_id' => $id,
]);
}
EmpDocuments.php
public function Employee()
{
return $this->belongsTo('App\Employee');
}
With the above models and controller I am now getting error
General error: 1364 Field 'employee_id' doesn't have a default value (SQL: insert into empdocuments.
How do I capture the employee_id?
Managed to fix it, in case someone has similar problem. Ensure you pass the id with the route action for it to be capture in the next request.
Here is the final controller.
public function update(Request $request, $id)
{
$file = $request->file('file');
$allowedFileTypes = config('app.allowedFileTypes');
$maxFileSize = config('app.maxFileSize');
$rules = [
'file' => 'required|mimes:'.$allowedFileTypes.'|max:'.$maxFileSize
];
$this->validate($request, $rules);
$time = time(); // Generates a random string of 20 characters
$filename = ($time.'_'.($file->getClientOriginalName())); // Prepend the filename with
$destinationPath = config('app.fileDestinationPath').'/'.$filename;
$uploaded = Storage::put($destinationPath, file_get_contents($file->getRealPath()));
if($uploaded){
$employee = Employee::find($id);
$empdoc = new EmpDocuments();
$empdoc->name = $filename;
$employee->empdocuments()->save($empdoc);
return redirect('employees/' . $id . '#documents')->with('message','Document has been uploaded');
}
}
Do you have a relationship between Employee and EmpDocuments ??
If I am understanding well EmpDocuments belongsTO Employees right??
I'm trying to help but I need to understand, one employee can have many documents right?? but each document belongs to just one employee right??
If is like that you should make a relationship in your employee model,
` public function employeeDocuments(){
return $this->hasMany(EmpDocuments::class);
}`
Then in the same model
`public function createEmployeeDocuments(){
return $this->employeeDocuments()->create([
'your_db_fields' =>your file,
'your_db_fields' => your other some data,
]);
}`
The id will be inserted automatically
I hope I helped you!!
https://laravel.com/docs/5.3/eloquent-relationships
Are your fillable empty???
To use the Eloquent create method you need to set you fillable array to mass assignment. Try this, if is still not working tell me and I will try to do my best.
protected $fillable = [ 'employee_id', 'Your_db_field', 'Your_db_field', 'per_page', 'Your_db_field', 'Your_db_field' ];

Categories