Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an Eloquent Object with relation included

I'm pretty much new to opps and laravel both So, to insert the values into my users and profiles table which hav OneToOne relationship, Here is how my store() method looks like

public function store(Requests\StoreNewUser $request)
{
    // crate an objct of user model
        $user = new \App\User;
        // now request and assign validated input to array of column names in user table
        $user->first_name = $request->input('first_name');
        $user->last_name = $request->input('last_name');
        $user->email = $request->input('email');
        $user->password = $request->input('password');
        /* want to assign request input to profile table's columns in one go 
        */
        $user->profile()->user_id = $user->id; // foreign key in profiles table
        $user->profile()->mobile_no = $request->input('mobile'); 
        dd($user); // nothing related to profile is returned
}

I'm creating the new record, hence dd() never returns anything related to profile table.

Is this Because the $user object is not including relationship by default? If yes Can i create the $user object which includes the associated relations in User Model ?

Or do i have to create two separate objects of each table and save() the data
But then what is the significance of push() method ?

EDIT 1 P.S. yes, the relationships are already defined in User & Profile model

like image 781
echoashu Avatar asked Jun 11 '15 18:06

echoashu


3 Answers

You may try something like the following. At first save the parent model like this:

$user = new \App\User;
$user->first_name = $request->input('first_name');
// ...

$user->save();

Then create and save the related model using something like this:

$profile = new \App\Profile(['mobile_no' => $request->input('mobile')]);
$user->profile()->save($profile);

Also make sure you have created the profile method in User model:

public function profile()
{
    return $this->hasOne('App\Profile');
}
like image 128
The Alpha Avatar answered Oct 10 '22 12:10

The Alpha


The clean way to do it now would be having on your User Class file:

public function profile()
{
    return $this->hasOne(App\Profile::class);
}

and in your User Controller, the following store method:

public function store(Requests\StoreNewUser $request)
{
    $user = App\User::create(
        $request->only(
            [
                'first_name',
                'last_name',
                'email'
            ]
        )
    );

    $user->password = Illuminate\Support\Facades\Hash::make($request->password);
    //or $user->password = bcrypt($request->password);

    $user->profile()->create(
        [
            'mobile_no' =>  $request->mobile;
        ]
    );

    dd($user);
}

I didn know if u were saving plain text password to you database or using a mutator on password attribute, anyhow the suggested above is a good practice I think

like image 31
diegochaves Avatar answered Oct 10 '22 10:10

diegochaves


I thought i'd update this answer and make it applicable to Laravel 5 onwards. I'll use @The Alpha answer as a basis.

$profile = new \App\Profile(['mobile_no' => $request->input('mobile')]);
$user->profile()->associate($profile); // You can no longer call 'save' here
$user->profile()->save();

The reason for this is you can no longer call save on the belongsTo relation (or any other), this now returns an instance of Illuminate\Database\Query\Builder.

like image 23
Matt Avatar answered Oct 10 '22 12:10

Matt