The Method
model is a container of conditions (triggers) and actions.
Method
has multiple Condition
Condition
has multiple Action
We can have different types of Condition
, for instance:
0
and 500
USD10
and 100
poundsAnd we can have different types of Action
, for instance:
5
email@email.com
We are creating a table for each type of condition
and a table for each type of action
. That way we don't end up with a table full of columns to encompass each possible scenario.
The problem is: how to create this Polymorphic Relationship?
Starting with Conditions
…
My database looks like:
id | condition_id | condition_type | method_id |
---|---|---|---|
1001 | 5005 | App\Model\ConditionTypeOrderAmount | 1 |
1002 | 6006 | App\Model\ConditionTypeOrderWeight | 1 |
id | min_amount | max_amount |
---|---|---|
5005 | 0 | 500 |
id | min_weight | max_weight |
---|---|---|
6006 | 10 | 100 |
id | action_id | action_type | condition_id |
---|---|---|---|
8008 | 2002 | App\Models\ActionTypeCallSupervisor | 1001 |
8009 | 2002 | App\Models\ActionTypeCallSupervisor | 1002 |
id | supervisor_id | call_anytime |
---|---|---|
2002 | 5 | 1 |
I could partially achieve what I need using belongsToMany
and wherePivot
in Method
, like:
class Method extends Model
{
public function orderAmountConditions()
{
return $this
->belongsToMany(
ConditionTypeOrderAmount::class,
'conditions',
'method_id',
'condition_id',
)->wherePivot(
'condition_type',
ConditionTypeOrderAmount::class
);
}
public function orderWeightConditions()
{
return $this
->belongsToMany(
ConditionTypeOrderWeight::class,
'conditions',
'method_id',
'condition_id',
)->wherePivot(
'condition_type',
ConditionTypeOrderWeight::class
);
}
}
But in that scenario conditions
table was used just as a pivot table and I had a single function for every type of condition. Not ideal.
So I tried to use Polymorphic Relationships, but than thing got confusing…
What I tried:
Both ConditionTypeOrderAmount
and ConditionTypeOrderWeight
have the same conditions()
relationship:
class ConditionTypeOrderAmount extends Model
{
public function conditions()
{
return $this->morphMany(
Condition::class,
'conditions'
);
}
}
And Condition
has:
class Condition extends MorphPivot
{
public function conditionable()
{
return $this->morphMany(
Condition::class,
'conditions',
'condition_id',
);
}
}
But no results are found. I already read Laravel docs several times and watched a lot of YouTube videos, but I can't figure Polymorphic relationships.
Expected response would be something like:
{
"method": {
"id": 1,
"conditions": [
{
"id": 1001,
"type": "App\Models\ConditionalTypeOrderAmount",
"min_amount": 0,
"max_amount": 500,
"actions": [
{
"id": 8008,
"type": "App\Models\ActionTypeCallSupervisor",
"supervisor_id": 5,
"call_anytime": 1,
}
]
},
{
"id": 1002,
"type": "App\Models\ConditionalTypeOrderWeight",
"min_weight": 10,
"max_weight": 100,
"actions": [
{
"id": 8009,
"type": "App\Models\ActionTypeCallSupervisor",
"supervisor_id": 5,
"call_anytime": 1,
}
]
}
]
}
}
In Condition
model (extends Model):
public function conditionable()
{
return $this->morphTo();
}
public function method()
{
return $this->belongsTo(
Method::class
);
}
public function actions()
{
return $this->hasMany(
Action::class
);
}
In ConditionType....
models (extends Model):
public function conditions()
{
return $this->morphMany(
Condition::class,
'conditionable',
);
}
In Method
model (extends Model):
public function conditions()
{
return $this->hasMany(
Condition::class
);
}
In Action
model (extends Model):
public function actionable()
{
return $this->morphTo();
}
public function condition()
{
return $this->belongsTo(
Condition::class
);
}
In ActionType....
models (extends Model):
public function actions()
{
return $this->morphMany(
Action::class,
'actionable',
);
}