Laravel – many-to-many where the many-to-many table is (part-) polymorph

I have a table called bonus. A user can get a bonus (it’s like an reward) for certain actions. Well, the bonus can be assigned to many users and many users can get the same bonus. So it’s a many to many relation between user and bonus.

This is no problem so far. But users can get the same bonus for different actions. So let’s say there is a bonus for voting on a picture. Well, one user could vote on one picture and another one could vote on another picture which I’d like to save in the many-to-many table.

Furthermore there could be a bonus for writing a comment which is clearly another table than picture votes.

The problem here is that I would need to save the polymorphic type in the bonus table and the ID in the many-to-many table.

I think this should be the best way but how would I realize it with laravel? I think this is not a normal use case. But still I’d like to use it as other relations in laravel so that I could fetch a user and get his bonuses with the correct polymorphic relation.

Do you have any ideas?


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You are probably going to have to develop your own relationship classes.


public function answers()
    $instance = new Response();
    return new QuestionAnswerRelation($instance->newQuery(),$this);

use IlluminateDatabaseEloquentBuilder;
use IlluminateDatabaseEloquentCollection;
use IlluminateDatabaseEloquentRelationsRelation;
use PivotalSurveyModelsAnswer;
use PivotalSurveyModelsCollectionsAnswerCollection;
use PivotalSurveyModelsQuestionInterface;
use PivotalSurveyModelsSurveyInterface;

class QuestionAnswerRelation extends Relation

     * Create a new relation instance.
     * @param  IlluminateDatabaseEloquentBuilder  $query
     * @param  IlluminateDatabaseEloquentModel  $parent
     * @return void
    public function __construct(Builder $query, QuestionInterface $parent)
        $table = $query->getModel()->getTable();
        $this->query = $query
                DB::raw($parent->sid.'X'.$parent->gid.'X'.$parent->qid . ' AS value'),

        $this->query = $query;
        $this->parent = $parent;
        $this->related = $query->getModel();

    public function addEagerConstraints(array $models)

    public function initRelation(array $models, $relation)


    public function addConstraints()


    public function match(array $models, Collection $results, $relation)


    public function getResults()
        $results = $this->query->get();
        $answerCollection = new AnswerCollection();

        foreach($results as $result)
            $answer = new Answer($result->toArray());
            $answer->question = $this->parent;

        return $answerCollection;

In this case we are using Lime Survey which creates a unique table (note the $instance->setSid() changes the table name) for each of its surveys and a unique column for each of its answer -> question values. ( note $parent->sid.’X’.$parent->gid.’X’.$parent->qid. ‘AS value’)

Where sid = survey_id, gid = group_id(I think) and qid = question_id

Its was quite irritating.

Note how I reference values from the parent to further develop the query.
You should be able to follow a similar route to achieve whatever your heart desires and still maintain the feasibility to use Eloquent.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x