https://github.com/celinederoland/eloquent-polymorphic-model
Extend eloquent facilities to map one class Hierarchy branch to one table in database
https://github.com/celinederoland/eloquent-polymorphic-model
eloquent-orm-models polymorphism
Last synced: 5 months ago
JSON representation
Extend eloquent facilities to map one class Hierarchy branch to one table in database
- Host: GitHub
- URL: https://github.com/celinederoland/eloquent-polymorphic-model
- Owner: celinederoland
- Created: 2018-10-20T04:47:32.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-10-21T01:36:47.000Z (over 7 years ago)
- Last Synced: 2024-12-01T01:29:18.271Z (over 1 year ago)
- Topics: eloquent-orm-models, polymorphism
- Language: PHP
- Size: 39.1 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Eloquent extension for polymorphic models
Extend eloquent facilities to map one class Hierarchy branch to one table in database.
## Purpose
If you have one table on database (let say a `Person` table with fields `person_id`, `name` and `gender`) and you want to map it with your class hierarchy (let say a parent class `Person` and 2 childs `Man extends Person` and `Woman extends Person`), then you can use this package to make the mapping automatically.
## Configure class mapping
### Retrieving instances from the parent class
In parent class, define the Model as usual :
```php
class Person extends Model {
protected $table = 'Person';
protected $primaryKey = 'person_id';
}
```
Define empty children classes :
```
class Man extends Person {}
class Woman extends Person {}
```
In parent class use the `EloquentPolymorphism\PolymorphicParent` helper
You must define how database results will be bound with your class hierarchy (in my example it depends on the `gender` field value)
```php
protected function instanceFactory($attributes) {
if (!array_key_exists('gender', $attributes)) {
return static::class;
}
switch ($attributes['gender']) {
case self::TYPE_WOMAN:
return Woman::class;
case self::TYPE_MAN:
return Man::class;
}
return static::class;
}
```
With that you can retrieve a collection of Men and Women :
```php
$persons = Person::all(); //an eloquent collection, containing instances of `Man` and instances of `Woman`
```
### Retrieving instances from children classes
Now we must define constraints in child classes (otherwise `Man::all()` would also retrieve a collection of men and women).
For that in children classes you have to use the trait `EloquentPolymorphism\PolymorphicChild` and define the `polymorphismScope` constraint ;
```php
class Man extends Person {
* This scope will be added to all requests to make sure not retrieving other child.
*
* @param Builder $query
*/
protected function polymorphismScope(Builder $query) {
$query->where('gender', 'm');
}
}
```
Now if you write `Man::all()` or any more complex query on `Man` model it will result on a collection of `Man` instances, corresponding to the table entries which represent men.
Optionally, you can overwrite the name of the scope you just defined in `Man` class adding this code either in parent or child class :
```php
protected function polymorphismScopeIdentifier() {
return 'polymorphism_scope_identifier';
}
```
## Updating/Creating model :
### default attributes
It is strongly recommended to define default attributes values in children classes.
In our example it would be comfortable to write :
```php
$woman = new Woman(['name' => 'Sandra']);
$woman->save();
```
without having to set her gender.
For this purpose, you must overwrite method `setChildDefaultAttributes` in children classes
```php
public function setChildDefaultAttributes() {
$this->gender = 'f';
}
```
### verifications on save method call
The trait `PolymorphicParent` prevents unnatural update/create on children like as example :
```php
$man = new Man();
$man->gender = 'f';
$man->save(); //returns false, entry is not saved
```
This is done by checking that the conditions defined in `instanceFactory` method would effectively retrieve an instance of `Man`.
You can overwrite this behaviour by implementing the method `checkHierarchyConstraintsBeforeSaving`
```php
class Man extends Person {
/**
* @return bool
*/
protected function checkHierarchyConstraintsBeforeSaving() {
//Your logic : return true if it's correct to consider this instance as beeing a man, false otherwise
}
}
```
## Complex queries, relations, etc.
You can use all other functionality of Eloquent models like usual. In particular, you can define relations and complex queries as needed.
# Contribute
Fork the project in your github account. Init gitflow
```bash
git flow init
git flow feature start feature-name develop
```
Composer install
````bash
sh composer.sh install
````
Test
```bash
docker-compose up testunit
```
Code
```bash
git push
```
Create a merge request from you're release branch to develop