Search code examples
phplaravellaravel-8

laravel 8 store request with foreign key user_id not working


I would like to store the corresponding logged in user when adding a new School data. What I'm trying to do is store the logged in user_id in the schools table, in order to know on who added the school data. I have a users table already, which will establish the relation in the schools table.

My goal is when an admin is logged in, he/she can see all of the School records, otherwise if it's a user, then only fetch the records he/she added. The problem is that I can't figure out on when and where to insert the user_id data during the store request as I'm getting an error "user id field is required". Here's what I've tried so far:

Migration:

class CreateSchoolsTable extends Migration
{
public function up()
    {
        Schema::create('schools', function (Blueprint $table) {
            $table->id();
            $table->string('school_name');
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->timestamps();
        });
    }
}

School Model:

class School extends Model
{
    use HasFactory;

    protected $fillable = ['school_name', 'user_id'];


    public function User() {
        return $this->belongsTo(User::class);
    }

}

Store Request:

class StoreSchoolRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'school_name' => 'required|string|max:255',
            'user_id' => 'required|exists:users,id'
        ];
    }
}

Controller:

class SchoolController extends Controller
{
    public function store(StoreSchoolRequest $request) {
        $school_data = $request->validated();
        $user_id = \Auth::user()->id;
        $school_data['user_id'] = $user_id;

        School::create($school_data );

        return Redirect::route('schools.index');
    }
}

Any inputs will be of big help! Thanks.


Solution

  • Laravel has elegant way to bind authenticated user_id. Remove user_id from request class and chaining method. Also setup relationship from User model to School Model

    Form Request Class

    class StoreSchoolRequest extends FormRequest
    {
        public function rules(): array
        {
            return [
                'school_name' => 'required|string|max:255',
            ];
        }
    }
    

    User Model

    protected $fillable = ['school_name', 'user_id'];
    ...
    // new line
    public function schools() {
       return $this->hasMany(School::class);
    }
    

    Your Controller

    class SchoolController extends Controller
    {
        public function store(StoreSchoolRequest $request) {
            auth()->user()->schools()->create($request->validated());
            return Redirect::route('schools.index');
        }
    }
    

    UPDATE ANSWER

    Since user_id value is school name (based on image link from comment), probably there's something wrong either in User or School model. Here the quick fix

    Your Controller

    class SchoolController extends Controller
    {
        public function store(StoreSchoolRequest $request) {
            auth()->user()->schools()->create(
                array_merge(
                    $request->validated(), 
                    ['user_id' => auth()->id()]
                )
             );
            return Redirect::route('schools.index');
        }
    }