Reputation: 2235
Very simple question: Laravel eloquent docs specify that the morphTo function defines a polymorphic, inverse one-to-one or many relationship. Is there anyway (laravel forks maybe ?) to create a polymorphic, non-inverse one-to-one or many relationship, Without doing it myself and diving in Laravel's Eloquent relationships code ?
To be clear: I want to do something like:
class Answer extends Eloquent {
protected $fillable = array('answer_id', 'answer_type');
public function answers() {
return $this->straightMorphTo('answer_id', 'answer_type', 'id');
}
}
class AnswerFirst extends Eloquent {
protected $fillable = array('id', 'text');
public function answers() {
return $this->belongsTo('Answer');
}
}
class AnswerSecond extends Eloquent {
protected $fillable = array('id', 'number');
public function answers() {
return $this->belongsTo('Answer');
}
}
//
// Answer
// ------------------------------------
// answer_id | answer_type |
// ------------------------------------
// 1 | AnswerFirst |
// 2 | AnswerSecond |
// ------------------------------------
//
// AnswerFirst
// ------------------------------------
// id | text |
// ------------------------------------
// 1 | 1rst part |
// 1 | 2nd part |
// ------------------------------------
//
// AnswerSecond
// ------------------------------------
// id | number |
// ------------------------------------
// 2 | 1 |
// 2 | 2 |
// ------------------------------------
//
And then, Answer::with('answers')->find(2) should return
{
id:'2',
answer_type:'AnswerSecond',
answers: [
{id:'2',number:'1'},
{id:'2',number:'2'},
]
}
Upvotes: 1
Views: 2170
Reputation: 2235
Actually I found a solution by digging into the Laravel Eloquent classes and coding it myself.
Two ways of doing this, either create a new relationship or just 'patch' the MorphTo relationship to allow the instance that will be morphed to have multiple parents.
Either way, the solution comes just by replacing the MorphTo (or your relation copied from MorphTo) matchToMorphParents function by
protected function matchToMorphParents($type, Collection $results)
{
$resultsMap = array();
foreach ($results as $result)
{
if (isset($this->dictionary[$type][$result->getKey()]))
{
foreach ($this->dictionary[$type][$result->getKey()] as $model)
{
$resultsMap[$model->{$this->foreignKey}]['model'] = $model;
if (!array_key_exists('results', $resultsMap[$model->{$this->foreignKey}])) {
$resultsMap[$model->{$this->foreignKey}]['results'] = array();
}
array_push($resultsMap[$model->{$this->foreignKey}]['results'], $result);
}
}
}
foreach ($resultsMap as $map)
{
if (sizeof($map['results']) === 1) {
$map['model']->setRelation($this->relation, $map['results'][0]);
} else {
$map['model']->setRelation($this->relation, new Collection($map['results']));
}
}
}
You can find the diff here
Upvotes: 1