0

I am trying to save a long form data to database. Till now i am getting the form value from request object and setting it to database model. This works perfectly fine. But I want to know if there is another way to initialise the model efficiently without need to set each value. My model has one to one relation.

I have been doing like this. But i don't think this is the right way to do

//Student details
            $studentDetail->student_first_name = $request->input('studentFirstName');
            $studentDetail->student_last_name = $request->input('studentLastName');
            $studentDetail->student_phone_number = $request->input('studentPhoneNumber');
            $studentDetail->student_date_of_birth = $request->input('studentDOB');
            $studentDetail->student_email = $request->input('studentEmail');
            $studentDetail->save();

            $studentAddress = new Address();
            $studentAddress->address_1 = $request->input('studentAddress1');
            $studentAddress->address_2 = $request->input('studentAddress2');
            $studentAddress->city = $request->input('studentCity');
            $studentAddress->state = $request->input('studentState');
            $studentAddress->country = $request->input('studentCountry');
            $studentAddress->post_code = $request->input('studentPostCode');
            $studentDetail->addresses()->save($studentAddress);

            $visaDetails = new Visa();
            $visaDetails->passport_number = $request->input("visaPassportNumber");
            $visaDetails->visa_number = $request->input("visaVisaNumber");
            $visaDetails->visa_class = $request->input("visaVisaClass");
            $visaDetails->visa_grant_date = $request->input("visaVisaGrantDate");
            $visaDetails->visa_expiry_date = $request->input("visaVisaExpiryDate");
            $studentDetail->visaDetails()->save($visaDetails);
//
            $instituteDetails = new Institute();
            $instituteDetails->institute_name = $request->input("instituteName");
            $instituteDetails->institute_location = $request->input("instituteLocation");
            $instituteDetails->institute_phone1 = $request->input("institutePhone1");
            $instituteDetails->institute_phone2 = $request->input("institutePhone2");
            $instituteDetails->institute_email = $request->input("instituteEmail");

//            dd($instituteDetails->courses);
            $courseDetails = new Course();
            $courseDetails->course_level = $request->input("courseLevel");
            $courseDetails->course_name = $request->input("courseName");
            $courseDetails->course_fee = $request->input("courseFee");
            $courseDetails->course_concession_fee = $request->input("courseConcessionFee");
            $courseDetails->course_duration = $request->input("courseDuration");
            $courseDetails->course_commencement_date = $request->input("courseCommencementDate");
            $studentDetail->instituteDetails()->save($instituteDetails);
            $instituteDetails->courses()->save($courseDetails);

Any idea on making this process faster??

1
  • You can check this and this to get an idea. Commented Jun 22, 2018 at 22:37

1 Answer 1

1

Simply set create your models using mass assignment, so:

So in your model StudentDetail:

    class StudentDetail{

        protected $fillable = [
            'student_first_name',
            'student_last_name',
            'student_phone_number',
            'student_date_of_birth',
            'student_email',
        ];
        //...
        //... rest of your model
    }

Then tweak your HTML inputs to have in their names the user array like so for example:

<input type="text" id="foo" name="student[student_first_name]">
<input type="text" id="foo" name="student[student_last_name]">
.....

Tip: for validation, you have to treat it with dot notation, so your rule could be:

'student.student_first_name' => 'required|humanName|string|max:255',

Now simply do the following in your controller:

$studentDetail = StudentDetail::create($request->input('student'));

Now you made do the same for your address and other models.

The GIST: After mass assignment enabled for your models you could end up having ONLY the following couple lines of code doing it all for you and it's way more fun and full of dynamism ;) IMHO!

$relatedModels = ['Address', 'Visa', 'Institute', 'Course'];
    foreach ($relatedModels as $relatedModel) {
        $relatedModelClass = 'App\\'.$relatedModel; //adjust the namespace of your models here.
        $ormRelatedModel = $relatedModelClass::create(strtolower($request->input($relatedModel)));
        $studentDetail->{strtolower(str_plural($relatedModel)) . 'Details'}()->save($ormRelatedModel);
    }

please note that in this case your relations names should be changed a bit like addresses function within your StudentDetail class/model should be changed to addressesDetails or just remove the .'Details' from my sample code above and remove it from your other relations names, i.e: change instituteDetails() to institute(). and make the relation names plural please!

I just tested it and it's working, Cheers!

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you mohammad for your answer. I a bit confused on setting one to one relation through this method. The create method sets the value directly to database. I could not attach models to each other.
You are welcome :) , and actually that I wrote you is a comprehensive solution. just please set your models/HTML to have inputs as the example. and believe me, it will buy you plenty of time ;)
to help you for the relation itself, forexanple UserDetails + Address, you should have address_id in your UserDetails tabe, I guess it's user_details then in the model UserDetails you should have, public function addresses(){ return $this->belongTo(Address::class);} please note the name of this functino should be singular! I broke the convention here just so it could fit the dynamism I have added above ;) Good luck bro!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.