I have a solution to this problem, and I sure hope that laravel offers a more elegant solution...so if anyone knows, please let me know..
<?php
class Person extends Eloquent
{
public $timestamps = false;
public function agent()
{
return $this->hasOne('Agent');
}
public function client()
{
return $this->hasOne('Client');
}
public function employee()
{
return $this->hasOne('Employee');
}
}
Then you can create a base class:
<?php
class PersonModel extends Eloquent
{
protected $appends = array('firstname', 'lastname', 'phone');
// make sure this relationship is always eager loaded
protected $with = array('person');
public function person()
{
return $this->belongsTo('Person');
}
public function getFirstnameAttribute()
{
return $this->person->firstname;
}
public function setFirstnameAttribute($firstname)
{
$this->person->firstname = $firstname;
}
public function getLastnameAttribute()
{
return $this->person->lastname;
}
public function setLastnameAttribute($lastname)
{
$this->person->lastname = $lastname;
}
public function getPhoneAttribute()
{
return $this->person->phone;
}
public function setPhoneAttribute($phone)
{
$this->person->phone = $phone;
}
public function save(array $options = array())
{
parent::save($options);
$this->person->save($options);
}
}
Then your subclasses:
<?php
class Agent extends PersonModel
{
public $timestamps = false;
}
Then you can run:
$agent = Agent::find(1);
$agent->firstname = "Jim";
$agent->save();
And that will update the firstname in the Person table to Jim.
Also, your schemas will look like:
Schema::create('people', function(Blueprint $table) {
$table->increments('id');
$table->string('firstname');
$table->string('lastname');
$table->string('phone');
});
Schema::create('agents', function(Blueprint $table) {
$table->increments('id');
$table->string('license');
$table->integer('person_id')->unsigned();
$table->foreign('person_id')->references('id')->on('people');
});
Schema::create('clients', function(Blueprint $table) {
$table->increments('id');
$table->integer('medical_record_num');
$table->integer('person_id')->unsigned();
$table->foreign('person_id')->references('id')->on('people');
});
Schema::create('employees', function(Blueprint $table) {
$table->increments('id');
$table->datetime('start_date');
$table->string('department');
$table->integer('person_id')->unsigned();
$table->foreign('person_id')->references('id')->on('people');
});
This method is admittedly not the most elegant solution and comes with some performance drawbacks, however, this is probably the most scalable solution and will have solid database architecture, and you can refer to your Employees as employees, agents as agents, etc. If this is the business need then obviously that is the number 1 priority.
I really like @netorious solution but there is also something called Single Table Inheritance
@ShawnMcCool made a post about it http://laravel.io/forum/02-17-2014-eloquent-single-table-inheritance
I've implemented it in my own project as well, I have a Product that has many Option. Price is a child (sub class) of Option as well as Discount. Without the need of a Price or Discount tabel I can still use Price::all() and etc
@zenry that seems to be a nice way of doing it as well... I'm going to check that out later. I'd be interested in the pros/cons of these two solutions.
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community