Saving related records in laravel
Asked Answered
E

4

55

I have users, and users belong to a dealership.

Upon user registration, I'm trying to save a new user, and a new dealership.

User database has a dealership_id column, which I want to be populated with the ID of the newly created dealership.

This is my current code in the UserController store method.

public function store()
{
    $user = new User();
    $user->email = Input::get('email');
    $user->password = Input::get('password');


    $dealership = new Dealership();
    $dealership->name = Input::get('dealership_name');

    $user->push();
    return "User Saved";

}

Trying to use $user->push(); User data gets updated, but dealership is not created or updated.

Ellipticity answered 22/4, 2014 at 19:41 Comment(2)
Which part of the code get's the dealership ID?Dessert
Sorry, it would be helpful if I included code from my models too I suppose, haha. laravel.io/bin/N7PmEllipticity
S
81

Eloquent's push() saves the model and its relationships, but first you have to tell what you want to be involved in the relationsship.

Since your user-model/table holds the id of the dealership, I assume that a user can belong to only one dealership, so the relationship should look like this:

User Model:

public function dealership()
{
  return $this->belongsTo('Dealership');
}

Dealership Model:

public function users()
{
  return $this->hasMany('User');
}

To save a User from the Dealership perspective, you do this:

$dealership->users()->save($user);

To associate a dealership with a user, you do this:

$user->dealership()->associate($dealership);
$user->save();
Spoilt answered 22/4, 2014 at 19:54 Comment(5)
Thanks! I feel like this got me closer...I've tried using the example to associate a dealership with a user and get this error "Illuminate \ Database \ QueryException SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'dealership_id' cannot be null (SQL: insert into users (email, password, dealership_id, updated_at, created_at) values ([email protected], y$mItUgj2h4JiMi666a3DHROHahjZuRDcgqCaMVDaO..TpurSMVJnWG, , 2014-04-22 19:59:56, 2014-04-22 19:59:56))"Ellipticity
So, I know that means I need to get the dealership_id into the users table, not sure how to do that. I don't have a foreign-key reference set up on my migration for the users table, could adding a foreign-key rule automagically fix this? Thanks again!Ellipticity
@SteveBalistreri I guess you'll have to save() the new dealership first before associating it :) new Dealership() creates an object, but does not save it yet, so it has no ID. You have to call the save-method manually. Alternatively you can do it with create(): Dealership::create(array('name' => Input::get('dealership_name'))); this automatically saves the newly created object so it has an ID to associate with.Spoilt
Downvoting silently for no effing reason 6 months after the answer was posted? Yeah, way to go, random stranger!Spoilt
can you please describe me what do you mean by $user->dealership()->associate($dealership); $user->save();Mozzetta
S
9

Please check this answer to see the difference of push() and save()

You will need to define correctly your models relationships as per documentation If this is done correctly, it should work . This is what push() does :

/**
 * Save the model and all of its relationships.
 *
 * @return bool
 */

    public function push()
    {
        if ( ! $this->save()) return false;

        // To sync all of the relationships to the database, we will simply spin through
        // the relationships and save each model via this "push" method, which allows
        // us to recurse into all of these nested relations for the model instance.

        foreach ($this->relations as $models)
        {
            foreach (Collection::make($models) as $model)
            {
                if ( ! $model->push()) return false;
            }
        }

        return true;
    }

In your case, you have a one (dealership) belongs to many (users)

In your Users model :

class Users extends Eloquent {

    public function dealership()
    {
        return $this->belongsTo('Dealership');

    }

}

In the example above, Eloquent will look for a dealership_id column on the users table. In your Dealership Model :

class Dealership extends Eloquent {

    public function users()
    {
        return $this->hasMany('User');
    }

}

In your store function :

 public function store()
    {
        $user = new User();
        $user->email = Input::get('email');
        $user->password = Input::get('password');


        $user->dealership = new Dealership();
        $user->dealership->name = Input::get('dealership_name');

        $user->push();
        return "User Saved";

    }  

Learn here more about eloquent relationships

Also please take a look at my answer here

Swop answered 22/4, 2014 at 19:48 Comment(3)
Thanks, I think I've got my eloquent relationships set up correctly. I made a paste here link. Users table does have a 'dealership_id' column. Still doesn't seem to be creating the dealership, and associating the dealership id with the user.Ellipticity
Updated, please take a look at my answer here : #23183894 . What i think, and from examples, it turns out that first you need to save the base model ( i.e.) the user, and the use push() to updateSwop
Yes, push() does not work with new records. See this issue: github.com/laravel/framework/issues/4641 And considering that push() is not documented much, it seems safer to use save().Grecism
E
1

By using push on the User model, Laravel is basically recursively calling save on all the related models (which, in this case, is none, since you haven't associated any other models to it yet).

Therefore, in order to accomplish what you're trying to do, you can do first create the user then associate the dealership with it by doing the following:

$user = new User();
$user->email = Input::get('email');
$user->password = Input::get('password');
$user->save();

$dealership = new Dealership();
$dealership->name = Input::get('dealership_name');

$user->dealerships()->save($dealership);
return "User Saved";

However, prior to doing this, you must ensure your User and Dealership models have their relationships set up correctly:

User Model:

public function dealership()
{
     return $this->belongsTo('Dealership');
}

Dealership Model:

public function users()
{
    return $this->hasMany('User');
}
Envelop answered 22/4, 2014 at 19:51 Comment(3)
what about if saving related data / insert new related record with push() instead of save(), is it possible ?Lifeline
push() does not work with new records. See this issue: github.com/laravel/framework/issues/4641 And considering that push() is not documented much, it seems safer to use save().Grecism
U have errors in relations in your answer. According to model, U don't have method dealerships, because User belongsTo DealershipFourcycle
R
1

This is how I manage to do it.

In your controller: (Laravel 5)

use Auth;

$dealership->user = Auth::user()->ref_user->staff_id;
Round answered 22/1, 2019 at 2:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.