Last active
December 20, 2015 08:29
-
-
Save kapv89/6100725 to your computer and use it in GitHub Desktop.
Single Table inheritance model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use Illuminate\Database\Eloquent; | |
use Illuminate\Database\Eloquent\Builder; | |
abstract class AbstractEloquent extends Eloquent\Model { | |
protected $isSuperType = false; // set true if super-class model | |
protected $isSubType = false; // set true in inherited models | |
protected $typeField = 'type'; //override as needed, only set on the super-class model | |
/** | |
* Provide an attributes to object map | |
* | |
* @return Model | |
*/ | |
public function mapData(array $attributes) | |
{ | |
if(! $this->isSuperType) | |
{ | |
return $this->newInstance(); | |
} | |
else | |
{ | |
if(! isset($attributes[$this->typeField])) | |
{ | |
throw new \DomainException($this->typeField . ' not present in the records of a Super Model'); | |
} | |
else | |
{ | |
$class = $attributes[$this->typeField]; | |
return new $class; | |
} | |
} | |
} | |
/** | |
* Create a new model instance requested by the builder. | |
* | |
* @param array $attributes | |
* @return Illuminate\Database\Eloquent\Model | |
*/ | |
public function newFromBuilder($attributes = array()) | |
{ | |
$m = $this->mapData((array) $attributes)->newInstance(array(), true); | |
$m->setRawAttributes((array) $attributes); | |
return $m; | |
} | |
/** | |
* Get a new query builder for the model's table. | |
* | |
* @return Reposed\Builder | |
*/ | |
public function newRawQuery() | |
{ | |
$builder = new Builder($this->newBaseQueryBuilder()); | |
// Once we have the query builders, we will set the model instances | |
// so the builder can easily access any information it may need | |
// from the model while it is constructing and executing various | |
// queries against it. | |
$builder->setModel($this)->with($this->with); | |
return $builder; | |
} | |
/** | |
* Get a new query builder for the model. | |
* set any type of scope you want on this builder in a child class, and it'll | |
* keep applying the scope on any read-queries on this model | |
* | |
* @return Reposed\Builder | |
*/ | |
public function newQuery($excludeDeleted = true) | |
{ | |
$builder = $this->newRawQuery(); | |
if ($excludeDeleted and $this->softDelete) | |
{ | |
$builder->whereNull($this->getQualifiedDeletedAtColumn()); | |
} | |
return $builder; | |
} | |
/** | |
* Save the model to the database. | |
* | |
* @return bool | |
*/ | |
public function save(array $options = array()) | |
{ | |
if($this->isSubType) | |
{ | |
$this->attributes[$this->typeField] = get_class($this); | |
} | |
$query = $this->newRawQuery(); | |
// If the "saving" event returns false we'll bail out of the save | |
// and return false, indicating that the save failed. | |
// This gives an opportunities to listeners to cancel save operations | |
// if validations fail or whatever. | |
if ($this->fireModelEvent('saving') === false) | |
{ | |
return false; | |
} | |
// If the model already exists in the database we can just update | |
// our record that is already in this database using the current IDs | |
// in this "where" clause to only update this model. | |
// Otherwise, we'll just insert them. | |
if ($this->exists) | |
{ | |
$saved = $this->performUpdate($query); | |
} | |
// If the model is brand new, we'll insert it into our database | |
// and set the ID attribute on the model to the value of the newly | |
// inserted row's ID which is typically an auto-increment value | |
// managed by the database. | |
else | |
{ | |
$saved = $this->performInsert($query); | |
$this->exists = $saved; | |
} | |
if ($saved) $this->finishSave($options); | |
return $saved; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment