Using Laravel Eloquents HasMany After a Multiple Relationship Through Polymorphism

I got a fairly simple application in which the user can report other user comments and recipes. I use a polymorphic relation to store reports. Which works well; however, now I'm trying to get the wrongdoing that the user made.

Getting user reports is not a problem, it can be done directly using user->reports() , but I would really like to receive reports in which other people have reported this to the user. I can get this to work using either the hasManyThrough relation or queries, but only one model at a time.

ex.

 public function offenses() { return $this->hasManyThrough('Recipe', 'Reports'); } 

or

 ->with('user.recipe.reports') 

The problem is that my reporting object is not just recipes, it can be comments, images, etc. Therefore, instead of using several functions, the logical way would be to sort out the relationship between hasManyThrough various parameters.

Theoretically, it looks like this:

 public function offenses() { return $this->hasManyThrough(['Recipe', 'RecipeComments'], 'Reports'); } 

Is it possible? With some undocumented syntax? If there are no smart workarounds / hacks?

Possible Solution?

Was it an acceptable solution to add another column to my report table and add addender_id the only way?

ID | User_id | Offender_id | Reportable_type | Reportable_id

This would mean that I could simply establish an attitude towards my user model, which links crimes through this column. But can this be considered redundant? Since I already have a criminal through the reporting model?


Models

Polymorphic Model

 class Report extends Model { public function reportable() { return $this->morphTo(); } public function User() { return $this->belongsTo('App\User'); } } 

Recipe Model

 class Recipe extends Model { public function user() { return $this->belongsTo('App\User'); } public function reports() { return $this->morphMany('App\Report', 'reportable'); } } 

Comment Model

 class RecipeComment extends Model { public function user() { return $this->belongsTo('App\User'); } public function reports() { return $this->morphMany('App\Report', 'reportable'); } } 
+7
polymorphism php laravel laravel-5
source share
1 answer

Using your current model, you can get all the presented models for the user using the following code:

 $recipeCommentReport = RecipeComment::whereHas('reports',function($q){ return $q->where('user_id','=',Auth::user()->id) }); $recipeReport = Recipe::whereHas('reports',function($q){ return $q->where('user_id','=',Auth::user()->id) }); //Get all reports into one $reports = $recipeReport->merge([$recipeCommentReport]); 

In fact, this is random because:

  • We cannot sort the results given that we are using two separate db queries.
  • If you have other models that have relationships with reports, just imagine chaos.

The best solution , as you understood above:

Add the offender_id column to the report table.

It is cleaner and follows the DRY principle.

Typical Case Scenarios

Get all user recipe comment reports for user

 Report::where('offender_id','=',Auth::check()->id) ->where('reportable_type','=','RecipeComment') ->get(); 

Affect by type for user

 Report::where('offender_id','=',Auth::check()->id) ->grouBy('reportable_type') ->select(Db::raw('count(*)'),'reportable_type') ->get(); 
+2
source share

All Articles