Skip to content

Commit cd65df5

Browse files
committedJul 22, 2024
add HasDynamicRelations trait
1 parent fe2110f commit cd65df5

File tree

4 files changed

+168
-0
lines changed

4 files changed

+168
-0
lines changed
 

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ This package includes different parts that I will mention in order:
3535
- [Console Tools](https://github.com/jobmetric/laravel-package-core/blob/master/docs/console-tools.md)
3636
- [Helper Functions](https://github.com/jobmetric/laravel-package-core/blob/master/docs/helper.md)
3737
- [Boolean Status](https://github.com/jobmetric/laravel-package-core/blob/master/docs/boolean-status.md)
38+
- [Has Dynamic Relations](https://github.com/jobmetric/laravel-package-core/blob/master/docs/has-dynamic-relations.md)
3839

3940
## License
4041

‎docs/boolean-status.md

+2
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ $users = User::active()->get();
2121
```php
2222
$users = User::inactive()->get();
2323
```
24+
25+
- [Has Dynamic Relations](https://github.com/jobmetric/laravel-package-core/blob/master/docs/has-dynamic-relations.md)

‎docs/has-dynamic-relations.md

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
[Back To README.md](https://github.com/jobmetric/laravel-package-core/blob/master/README.md)
2+
3+
# Introduction to Has Dynamic Relations Trait
4+
5+
`HasDynamicRelations` allows you to define polymorphic relations dynamically and flexibly. This `Trait` helps you manage different relationships between models without directly changing the package code and enables users to define the required relationships in their applications.
6+
7+
## Usage
8+
9+
This is a simple example
10+
11+
Consider the Tag class, which has a taggable field, and now consider the following examples
12+
13+
```php
14+
namespace App\Models;
15+
16+
use Illuminate\Database\Eloquent\Model;
17+
use Jobmetric\PackageCore\HasDynamicRelations;
18+
19+
class Tag extends Model
20+
{
21+
use HasDynamicRelations;
22+
}
23+
```
24+
25+
### Define Relationships in Other Models
26+
27+
To define dynamic relationships in other models, you need to set up the desired relationships dynamically when the models boot.
28+
29+
#### Example: `Post` Model
30+
31+
```php
32+
namespace App\Models;
33+
34+
use Illuminate\Database\Eloquent\Model;
35+
use App\Models\Tag;
36+
37+
class Post extends Model
38+
{
39+
protected static function boot()
40+
{
41+
parent::boot();
42+
43+
Tag::addDynamicRelation('posts', function ($model) {
44+
return $model ? $model->morphedByMany(Post::class, 'taggable') : (new Post)->morphedByMany(Tag::class, 'taggable');
45+
});
46+
}
47+
48+
public function tags()
49+
{
50+
return $this->morphToMany(Tag::class, 'taggable');
51+
}
52+
}
53+
```
54+
55+
#### Example: `Product` Model
56+
57+
```php
58+
namespace App\Models;
59+
60+
use Illuminate\Database\Eloquent\Model;
61+
use App\Models\Tag;
62+
63+
class Product extends Model
64+
{
65+
protected static function boot()
66+
{
67+
parent::boot();
68+
69+
Tag::addDynamicRelation('products', function ($model) {
70+
return $model ? $model->morphedByMany(Product::class, 'taggable') : (new Product)->morphedByMany(Tag::class, 'taggable');
71+
});
72+
}
73+
74+
public function tags()
75+
{
76+
return $this->morphToMany(Tag::class, 'taggable');
77+
}
78+
}
79+
```
80+
81+
### Usage in Controllers and Other Places
82+
83+
Now you can use these dynamic relationships in your application:
84+
85+
```php
86+
// Getting all tags with posts
87+
$tags = Tag::with('posts')->get();
88+
89+
// Getting all tags with products
90+
$tags = Tag::with('products')->get();
91+
92+
// Adding a tag to a post
93+
$post = Post::find(1);
94+
$tag = Tag::find(1);
95+
$post->tags()->attach($tag);
96+
97+
// Adding a tag to a product
98+
$product = Product::find(1);
99+
$product->tags()->attach($tag);
100+
101+
// Getting posts related to a tag
102+
$posts = $tag->posts;
103+
104+
// Getting products related to a tag
105+
$products = $tag->products;
106+
```
107+
108+
### Conclusion
109+
110+
Using `HasDynamicRelations` and the methods described above, you can define polymorphic relationships between models dynamically. This approach ensures that your package remains flexible and usable across different projects without requiring frequent changes to the package code.

‎src/HasDynamicRelations.php

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace JobMetric\PackageCore;
4+
5+
trait HasDynamicRelations
6+
{
7+
protected static array $dynamicRelations = [];
8+
9+
/**
10+
* Add dynamic relation
11+
*
12+
* @param $name
13+
* @param $callback
14+
*
15+
* @return void
16+
*/
17+
public static function addDynamicRelation($name, $callback): void
18+
{
19+
static::$dynamicRelations[$name] = $callback;
20+
}
21+
22+
/**
23+
* Get dynamic relation
24+
*
25+
* @param $method
26+
* @param $parameters
27+
*
28+
* @return mixed
29+
*/
30+
public function __call($method, $parameters)
31+
{
32+
if (isset(static::$dynamicRelations[$method])) {
33+
return call_user_func_array(static::$dynamicRelations[$method], [$this, $parameters]);
34+
}
35+
36+
return parent::__call($method, $parameters);
37+
}
38+
39+
/**
40+
* Get dynamic relation
41+
*
42+
* @param $method
43+
* @param $parameters
44+
*
45+
* @return mixed
46+
*/
47+
public static function __callStatic($method, $parameters)
48+
{
49+
if (isset(static::$dynamicRelations[$method])) {
50+
return call_user_func_array(static::$dynamicRelations[$method], [null, $parameters]);
51+
}
52+
53+
return parent::__callStatic($method, $parameters);
54+
}
55+
}

0 commit comments

Comments
 (0)
Please sign in to comment.