Используя фреймворк Laravel Eloquents HasManyThrough связи с множественными отношений через полиморфизм
я получил довольно простое приложение, где пользователь может сообщать другим пользователям комментарии и рецепты. Я использую полиморфное отношение для хранения отчетов. Который отлично работает; однако теперь я пытаюсь получить преступления, которые сделал пользователь.
получение отчетов пользователей не является проблемой, это можно сделать непосредственно с помощью user->reports()
но я очень хотел бы получить отчеты, в которых другие люди сообщили об этом пользователю. Я могу заставить это работать, используя либо hasManyThrough
связь или запросы Но только по одной модели за раз.
ex.
public function offenses() {
return $this->hasManyThrough('Recipe', 'Reports');
}
или
->with('user.recipe.reports')
проблема в том, что мой объект reportable-это не просто рецепты, это могут быть комментарии, изображения и т. д. Поэтому вместо того, чтобы использовать несколько функций, логическим способом было бы проанализировать связь между различными параметрами hasmanythrough.
теоретически выглядит так:
public function offenses() {
return $this->hasManyThrough(['Recipe', 'RecipeComments'], 'Reports');
}
возможно ли это каким-либо образом? С некоторыми недокументированный синтаксис? Если нет, есть ли умные обходные пути / хаки?
возможное решение?
приемлемым решением было бы добавить еще один столбец в мою таблицу отчетов и добавить только offender_id, как это?
идентификатор | функция user_id | Offender_id / Reportable_type / Reportable_id
это означало бы, что я мог бы просто сделать отношение на моей пользовательской модели, которая соединяет преступления через этот столбец. Но это считается избыточные? Так как у меня уже есть преступник через репортажную модель?
модели
Полиморфные Модели
class Report extends Model {
public function reportable() {
return $this->morphTo();
}
public function User() {
return $this->belongsTo('AppUser');
}
}
Модель Рецепт
class Recipe extends Model {
public function user() {
return $this->belongsTo('AppUser');
}
public function reports() {
return $this->morphMany('AppReport', 'reportable');
}
}
Комментарий Модель
class RecipeComment extends Model {
public function user() {
return $this->belongsTo('AppUser');
}
public function reports() {
return $this->morphMany('AppReport', 'reportable');
}
}
1 ответов
используя текущую модель, вы можете получить все сообщенные модели для пользователя по следующему коду:
$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]);
это лажа, в лучшем случае, потому что:
- мы не можем сортировать результаты, учитывая, что мы используем два отдельных запросов к БД.
- если у вас есть другие модели, которые имеют отношения доклад, просто представьте себе хаос.
лучшим решением, как вы поняли выше:
добавить на report
таблица.
он чище и следует сухому принципу.
Типичные Сценарии
получить все отчеты комментарий рецепт для пользователя
Report::where('offender_id','=',Auth::check()->id)
->where('reportable_type','=','RecipeComment')
->get();
подсчет правонарушения по типу для пользователя
Report::where('offender_id','=',Auth::check()->id)
->grouBy('reportable_type')
->select(Db::raw('count(*)'),'reportable_type')
->get();