Creating an Eloquent Object with relation included
Asked Answered
W

4

11

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

Whitehouse answered 11/6, 2015 at 18:23 Comment(0)
S
19

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');
}
Seamaid answered 11/6, 2015 at 18:38 Comment(5)
yes the method do exist already with the relationship. So that said, I'll have to create two objects from User and Profile respectively but what exactly $user->profile()->save($profile); signifies? how different from $profile->save()Whitehouse
It also attaches the profile with the User model so you don't have to provide the user.id(foreign key) when creating the Profile manually.Seamaid
done. and what abt saving the data in one go, i.e. if multiple users are being created by multiple individual requests at the same time on server, will they be executed in set? and not mingle up? U may consider, i have a create user form and of some my staff operators are submitting this concurrently.Whitehouse
Yes, they'll be saved without any clash.Seamaid
followup question is white listing ($fillable[]) mobile_no and other non volatile info fields for MassAssignment ok ? I'love ur way cz i'm lazy :-DWhitehouse
H
4

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.

Horrify answered 6/4, 2017 at 15:25 Comment(0)
A
2

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

Azazel answered 19/1, 2019 at 20:4 Comment(0)
F
0

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 ?

Yes you should create the relationship, they're not included by default.

In your User model you'd want to do something like this:

public function profile()
{
    return $this->hasOne('App\Profile'); // or whatever your namespace is
}

This would also require you to have a Profile model created.

This would definitely answer your questions regarding inserting related models: http://laravel.com/docs/5.1/eloquent-relationships#inserting-related-models

As The Alpha mentioned, and you also eluded to, I think you need to save your user model first then you can add via relationship.

Freya answered 11/6, 2015 at 18:30 Comment(1)
That's already there, i forgot to mention, indeed both hasOne and belongsTo are defined in User and Profile model respectivelyWhitehouse

© 2022 - 2024 — McMap. All rights reserved.