Reputation: 981
How to create Eloquent model with relationship?
I have:
Person table
id
firstname
lastname
Employee table
id
person_id
position
I want to do something like this:
Employee::create([
'firstname' => 'Jack',
'lastname' => 'London',
'position' => 'writer'
])
I know, that can create two model and then associate their. But may be there is a way do this more beautiful?
Upvotes: 27
Views: 65165
Reputation: 2690
I'd suggest you create a static method that creates the instance and related models. Many times you not only create a model, but you may have to populate it with some additional data and having a single createModel()
method is a best practice.
In my case:
public static function createCompany($data) : Company {
$company = new Company($data);
$company->save();
$company->settings()->create();
// TODO Configure settings according to $data
$company->blog()->create();
// TODO: Create demo blog post
// TODO: Create default admin user.
// TODO: Etc.
}
All these details can be abstracted from the controller, in which I only call:
$company = Company::createCompany($request->all());
Upvotes: 3
Reputation: 4705
First, you have to create relation in your Person model
class Person extends Model
{
protected $fillable = ['firstname', 'lastname'];
public function employee()
{
return $this->hasOne('App\Employee');
}
}
After that in your controller you can do:
$person = Person::create($personData);
$person->employee()->create($employeeData);
As @Alexey Mezenin mentioned you can use:
$person = Person::create(request()->all());
$person->employee()->create(request()->all());
Also inverse would be:
class Employee extends Model
{
protected $fillable = ['position'];
public function person()
{
return $this->belongsTo('App\Person');
}
}
Upvotes: 34
Reputation: 163748
You still need to create person first, so if you're looking for readable and consize solution, you can do is this:
$data = [
'firstname' => 'Jack',
'lastname' => 'London',
'position' => 'writer'
];
$person = Person::create($data);
$person->employee()->create($data);
Upvotes: 11