Whenever I run this request POST 0.0.0.0:80/api/clients/1/details?preferred_day=wednesday&preferred_time=08:00:00&goals=get better!
in Postman, I get:
SQLSTATE[HY000]: General error: 1364 Field 'client_id' doesn't have a default value (SQL: insert into `client_details` (`preferred_day`, `preferred_time`, `goals`, `updated_at`, `created_at`) values (wednesday, 08:00:00, get better!, 2022-05-01 14:31:51, 2022-05-01 14:31:51))
From my understanding, the ClientDetail
model should be defined as below. Notice the relationship and the fact that client_id
is fillable.
class ClientDetail extends Model
{
use HasFactory;
protected $guarded = ['id'];
protected $fillable = ['client_id','preferred_day','preferred_time','goals'];
public function client() {
return $this->belongsTo(Client::class,'client_id');
}
}
I have written the Client model as below. Notice that I have the inverse relationship defined as per the docs.
class Client extends Model
{
use HasFactory;
protected $guarded = ['id'];
protected $fillable = ['first_name','middle_name','last_name','email','phone_number','address','unit','postal_code','province','city','country'];
public function detail() {
return $this->hasOne(ClientDetail::class);
}
public function concerns() {
return $this->belongsToMany(Concern::class);
}
}
Finally the migration is defined as below:
public function up()
{
Schema::create('client_details', function (Blueprint $table) {
$table->id();
$table->foreignId('client_id')->constrained();
$table->string('preferred_day')->default('wednesday');
$table->time('preferred_time')->useCurrent();
$table->longText('goals');
$table->timestamps();
});
}
This is functioning as expected because when I look at DB, I see the following (notice how the foreign key references client.id
):
I have run dd on the request and I get the result below.
The only thing I can see is that the binding of routes is not working properly. I have included them below. Any assistance troubleshooting this would be appreciated.
EDIT - Added store function as requested
ClientDetailController.php
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
$validator = Validator::make($request->all(), [
'preferred_day' => [
'required',
Rule::in('wednesday','friday'),
],
'preferred_time' => 'required|date_format:h:i:s',
'goals' => 'required|min:10',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
$validated = $validator->validated();
$detail = ClientDetail::create($validated);
return new ClientDetailResource($detail);
}
CodePudding user response:
Your issue is relying within this line:
$detail = ClientDetail::create($validated);
Explanation:
You are creating Client Details without a Client themselves, in order words you must populate client_id
with a proper value:
You have to options: just before the wrong line mentioned abobe:
- NOT RECOMMENDED, hard code the client_id just so you can test this. by doing this line
$validated['client_id'] = 1
where 1 is example. - Do it properly by adding getting a client then create/store their details.
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Client $client, Request $request)
{
$validator = Validator::make($request->all(), [
'preferred_day' => [
'required',
Rule::in('wednesday','friday'),
],
'preferred_time' => 'required|date_format:h:i:s',
'goals' => 'required|min:10',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
$validated = $validator->validated();
// $client var is type-hinted in the function signature above
$client->detail()->create($validated);
$detail = ClientDetail::create();
return new ClientDetailResource($detail);
}