Nic*_*ank 7 php polymorphism laravel laravel-5
我有一个相当简单的应用程序,用户可以报告其他用户的评论和食谱.我使用多态关系来存储报告.哪个工作正常; 但是,我现在正试图让用户犯下的罪行.
获取用户报告不是问题,这可以直接使用,user->reports()但我非常希望获得其他人报告所述用户的报告.我可以使用hasManyThrough关系或查询来实现这一点,但一次只能在一个模型上使用.
恩.
public function offenses() {
return $this->hasManyThrough('Recipe', 'Reports');
}
Run Code Online (Sandbox Code Playgroud)
要么
->with('user.recipe.reports')
Run Code Online (Sandbox Code Playgroud)
问题是我的可报告对象不仅仅是食谱,它可能是注释,图像等.因此,不必使用多个函数,逻辑方法是以某种方式解析hasManyThrough各种参数之间的关系.
理论上看起来像这样:
public function offenses() {
return $this->hasManyThrough(['Recipe', 'RecipeComments'], 'Reports');
}
Run Code Online (Sandbox Code Playgroud)
这有可能吗?有一些没有文档的语法?如果不是,有任何聪明的解决方法/黑客?
可接受的解决方案是在我的报告表上添加另一列并且只添加这样的offender_id吗?
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('App\User');
}
}
Run Code Online (Sandbox Code Playgroud)
食谱模型
class Recipe extends Model {
public function user() {
return $this->belongsTo('App\User');
}
public function reports() {
return $this->morphMany('App\Report', 'reportable');
}
}
Run Code Online (Sandbox Code Playgroud)
评论模型
class RecipeComment extends Model {
public function user() {
return $this->belongsTo('App\User');
}
public function reports() {
return $this->morphMany('App\Report', 'reportable');
}
}
Run Code Online (Sandbox Code Playgroud)
使用您当前的模型,您可以通过以下代码接收用户报告的所有模型:
$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]);
Run Code Online (Sandbox Code Playgroud)
这充其量是混乱的,因为:
最好的解决方案,正如您上面所想的:
在表中添加一offender_id列report。
它更干净,遵循 DRY 原则。
典型案例场景
获取用户的所有食谱评论报告
Report::where('offender_id','=',Auth::check()->id)
->where('reportable_type','=','RecipeComment')
->get();
Run Code Online (Sandbox Code Playgroud)
按用户类型统计犯罪次数
Report::where('offender_id','=',Auth::check()->id)
->grouBy('reportable_type')
->select(Db::raw('count(*)'),'reportable_type')
->get();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2954 次 |
| 最近记录: |