Home > Enterprise >  Laravel: Foreign id does not have default value
Laravel: Foreign id does not have default value

Time:05-03

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): enter image description here

I have run dd on the request and I get the result below. enter image description here

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.

enter image description here

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:

  1. 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.
  2. 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);
    }

  • Related