PhpUnit - Expected Status 200 But Received 500 - laravel

I have users table with hasMany educational backgrounds & educational awards. Then that educational backgrounds hasMany educational awards
Here's my Testcase when user uploads image my endpoint receives it
public function testuploadUsersImageEducationalAwards()
{
Storage::fake('public');
$photo = UploadedFile::fake()->create('photo.png')->size(25000);
$data = [
'photo' => $photo,
'award' => $this->faker->word,
'educational_background_id' => EducationalBackground::factory()->create()->id
];
$this->withoutExceptionHandling();
$response = $this->sendPostRequestToEndpoint($data, 200);
$data['file_name'] = $response['file_name'];
unset($data['photo']);
$response->assertJson($data)
->assertJsonStructure([
'id',
'award',
'photo',
'educational_background_id',
'created_at',
'updated_at',
]);
$this->assertDatabaseHas('users.educational_awards', $data);
}
Here's my endpoint with assert status 200
private function sendPostRequestToEndpoint(array $data, $status)
{
return $this->json("POST", '/api/users/educational-award/upload-picture', $data)->assertStatus($status);
}
UPDATE
Here's my EducationalBackgroundFactory
class EducationalBackgroundFactory extends Factory
{
protected $model = EducationalBackground::class;
public function definition()
{
return [
'user_id' => User::factory()->create()->id,
'studies_type' => $this->faker->randomElement([EducationalBackground::BASIC, EducationalBackground::SECONDARY, EducationalBackground::UNDERGRADUATE, EducationalBackground::GRADUATESCHOOL]),
'year' => Carbon::now()->format("Y"),
'course' => $this->faker->word,
];
}
}
Here's my EducationalBackground model
class EducationalBackground extends Model
{
use HasFactory;
const BASIC = "basic";
const SECONDARY = "secondary";
const UNDERGRADUATE = "undergrad";
const GRADUATESCHOOL = "grad";
protected $table = 'users.educational_backgrounds';
protected $fillable = [
'user_id',
'studies_type',
'year',
'course',
];
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function educationalAwards()
{
return $this->hasMany("App\Models\Users\EducationalAward", "educational_background_id");
}
}
Here's my migration
public function up()
{
Schema::create('users.educational_backgrounds', function(Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->enum('studies_type', ['basic', 'secondary', 'undergrad', 'grad']);
$table->integer('year');
$table->string('course')->nullable();
$table->timestamps();
});
}
Here's my controller code
public function uploadUsersImageEducationalAwards(UserImageRequest $request, EducationalBackground $educational_background)
{
$uploaded_image = $request->photo->store('users/educational_awards');
$file_type = $request->photo->getClientOriginalExtension();
$file = EducationalAward::create([
'educational_background_id' => $educational_background->id,
'award' => $request->award,
'photo' => $uploaded_image,
]);
return response()->json($file, 200);
}
But this gives me 500 status which i found a way to log error in details. Here's an image for more clarity

remove unset function before sending response.

Related

Laravel 8: Undefined index

I'm working on a questionnaire project and I ran into an error saying:
Undefined index: exams
This happened when I was trying to store responses to my database.
Here is my controller code:
public function store(Math $math)
{
$data = request()->validate([
'responses.*.answer_id' => 'required',
'responses.*.question_id' => 'required'
]);
$exam = $math->exams()->create($data['exams']);
$exam->examanswers()->createMany($data['examanswers']);
return 'Thank You';
}
Here is my exam model:
{
use HasFactory;
protected $fillable = ['exam'];
public function math()
{
return $this->belongsTo(Math::class);
}
public function examanswers()
{
return $this->hasMany(ExamAnswer::class);
}
}
question model:
{
use HasFactory;
protected $fillable = ['question'];
public function math()
{
return $this->belongsTo(Math::class);
}
public function answers()
{
return $this->hasMany(Answer::class);
}
}
Math model:
{
use HasFactory;
protected $fillable = [
'user_id', 'title', 'purpose', 'exam'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function questions()
{
return $this->hasMany(Question::class);
}
public function exams()
{
return $this->hasMany(Exam::class);
}
}
Please help me look into it.
request()->validate(RULES) will return an array with all the existing rules' indexes. It will not return all data present, just what it is in the rules and present.
Read how $request->validate() works.
For example:
If you send home = 'Address', name = 'John' and email = 123, but your rules are:
$data = $request->validate([
'home' => 'required',
'name' => 'required',
]);
Then, if you want to use $data you would have (dd($data)):
$data['home']: Address
$data['name']: John
But email = 123 would not be present in $data.

Cant persist data to the database? (Laravel)

I'm new to Laravel. My data doesn't seem to get to the database. Here's my Controller code:
public function store(Request $request)
{
$rules = [
'first_name' => 'required|string|min:3|max:255',
'last_name' => 'required|string|min:3|max:255',
'gender' => 'required|string|min:3|max:255',
'qualifications' => 'required|string|min:3|max:255'
];
$validator = FacadesValidator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect('/home')
->withInput()
->withErrors($validator);
} else{
$data = $request->input();
try {
$crud = new CRUD;
$crud->first_name = $request->get('first_name');
$crud->last_name = $request->get('last_name');
$crud->gender = $request->get('gender');
$crud->qualifications = $request->get('qualifications');
$crud->save();
return redirect('/home')->with('status',"Insert successfully");
} catch (\Throwable $th) {
return redirect('/home')->with('failed',"Insert Failed");
}
}
}
And my Model:
protected $table = '$user';
protected $fillable = [
'first_name', 'last_name', 'gender', 'qualifications'
];
public $timestamps = true;
And my route(Web.php):
Route::post('/store', [App\Http\Controllers\CRUDController::class, 'store'])->name('insert');
Here is my migration for the users table:
Schema::create('user', function(Blueprint $table) {
$table->bigIncrements('id');
$table->string('first_name');
$table->string('last_name');
$table->string('gender');
$table->string('qualifications');
$table->timestamps();
});
You should fix your table name in your model, since your table is called user:
protected $table = "user";
Also, you can use mass assignment to fill your models:
$crud = CRUD::create($request->validated());
It should fix your problem.

Laravel update hasMany relationship

I just read more documentation and issues for this problem to resolve that , but nothing work for me, i have 2 table wit this models:
class Month extends Model
{
protected $guarded = ['id'];
public function lessons()
{
return $this->hasMany(Lesson::class);
}
}
class Lesson extends Model
{
protected $guarded = ['id'];
public function months()
{
return $this->belongsTo(Month::class);
}
}
I can save some data with relation ship with this sample code and that work fine:
$month = Month::find(1);
$lesson = new Lesson();
$lesson->title = $request->title;
$lesson->content = $request->content;
$lesson->file_url = $uploadedFilePath;
$lesson->filename = $filename;
$lesson->time = $request->time;
$month = $month->lessons()->save($lesson);
now I try to update some lesson fields with this code:
$lesson = Lesson::find($id);
$lesson->update([
'title' => $request->title,
'content' => $request->content,
'file_url' => $uploadedFilePath,
'filename' => $filename,
'time' => $request->time
]);
$month = Month::find($request->months['0']);
$lesson = Lesson::find($lesson->id);
$lesson->months()->associate($month)->save();
in that I try to change month_id column on Lesson table in database with for example $month->id value, how can I do that?
UPDATED:
class Lesson extends Model
{
protected $guarded = ['id'];
public function month()
{
return $this->belongsTo(Month::class);
}
}
Controller:
$lesson->update([
'title' => $request->title,
'content' => $request->content,
'file_url' => $uploadedFilePath,
'filename' => $filename,
'time' => $request->time
]);
$month = Month::find($request->months['0']);
$lesson = Lesson::find($lesson->id);
$lesson->month()->associate($month)->save();
$lesson->update(['month_id' => $month->id]);
Migrations:
Schema::create('months', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('description');
$table->string('price');
$table->timestamps();
});
Schema::create('lessons', function (Blueprint $table) {
$table->increments('id');
$table->integer('month_id')->unsigned();
$table->string('title');
$table->longText('content');
$table->string('file_url');
$table->string('filename');
$table->string('time', 50);
$table->foreign('month_id')->references('id')->on('months')->onDelete('cascade');
$table->timestamps();
});
Firstly, the name of method months() should be renamed to month because it's returning single month not multiple months.
Secondly, If your Lesson has a field called month_id then its far simpler than you are thinking about. We can just change these two lines:
$lesson = Lesson::find($lesson->id);
$lesson->months()->associate($month)->save();
To the following line:
$lesson->update(['month_id' => $month->id);
It should update the month_id of your $lesson to the $month->id

Laravel returns zero for the primary key value

I am having a problem in this laravel insertion code. Whenever a new company is created, I get the output as Company created but with company_name as 0. I don't know why this happens. My code is
Controller:
public function store(Request $request)
{
$Company = new Company([
'company_name' => $request->input('company_name'),
'head'=>$request->input('head'),
'Email'=>$request->input('email'),
'address'=>$request->input('address'),
'phno'=>$request->input('phno'),
'contact_person'=>$request->input('contact_person')
]);
if ($Company->save()) {
$response = [
'msg' => 'Company Created',
'Company' => $Company
];
return response()->json($response, 201);
}
$response = [
'msg' => 'An Error Occurred',
];
return response()->json($response, 502);
}
My Model code is:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
//
protected $table = 'companies';
public $timestamps = false;
protected $primaryKey = 'company_name';
protected $fillable = ['company_name','head','contact_person','phno','email','address'];
}
Input:
{
"company_name":"cachii1",
"head":"sankar",
"email":"sankar#gmail.com",
"address":"chennai",
"phno":"123",
"contact_person":"sankar"
}
output:
{
"msg": "Company Created",
"Company": {
"company_name": 0,
"head": "sankar",
"address": "chennai",
"phno": "123",
"contact_person": "sankar"
}
}
The Database Schema is
The Database Schema is
The Database Schema is
public function up()
{
Schema::create('companies', function (Blueprint $table) {
// $table->increments('company_id');
$table->string('company_name');
$table->primary('company_name');
$table->string('head');
$table->string('contact_person');
$table->bigInteger('phno');
$table->string('email');
$table->text('address');
});
By default, Laravel expects your model primary key to be auto incrementing. From what you've posted, it looks like that's not the case with your example.
Add this to your model definition:
public $incrementing = false;

Laravel 5.4 Eloquent not Saving certain fields

I have been working on logging all user activities in Model events... But for some reason, the records are stored in the user_action table but the action_model field. This is my code.
User Action Class
`
class UserAction extends Model
{
use SoftDeletes;
protected $table = 'user_actions';
/**
*
*/
protected $fillable = [
'user_id','action', ' action_model', 'action_id'
];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
}
`
UserActionObervable
class UserActionObserver
{
public function saved($model)
{
$type = $model->getTable();
// dd($type); when dump the value exists
if ($model->wasRecentlyCreated == true) {
// Data was just created
$action = 'created';
} else {
// Data was updated
$action = 'updated';
}
if (Sentinel::check()) {
UserAction::create([
'user_id' => Sentinel::getUser()->id,
'action' => $action,
'action_model' => 'model', //I tried to pass in constant
'action_id' => $model->id
]);
}
}
public function deleting($model)
{
if (Sentinel::check()) {
UserAction::create([
'user_id' => Sentinel::getUser()->id,
'action' => 'deleted',
'action_model' => $model->getTable(),
'action_id' => $model->id
]);
}
}
}
This is the schema
Schema::create('user_actions', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable();
$table->string('action'); // created / updated / deleted
$table->string('action_model');
$table->integer('action_id')->nullable();
$table->timestamps();
$table->engine = 'InnoDB';
$table->foreign('user_id')->references('id')
->on('users')->onDelete('cascade');
});
protected $fillable = [
'user_id','action', ' action_model', 'action_id'
];
Try to remove the space before action_model. The field in $fillable doesn't match the key you're passing into the create() method.

Resources