想不出一种将长三元运算符从我的刀片视图移动到控制器的方法
Posted
技术标签:
【中文标题】想不出一种将长三元运算符从我的刀片视图移动到控制器的方法【英文标题】:Can't think of a way to move long ternary operator from my blade view to a controller 【发布时间】:2018-07-17 17:58:44 【问题描述】:三元运算符:
<div class='votingContainer'>
<a href='#' class='vote ( auth()->user()->votes()->whereImageId($image->id)->first() && auth()->user()->votes()->whereImageId($image->id)->first()->vote == 1 ) ? "liked" : "like" ' id='$image->id'></a>
<a href='#' class='vote ( auth()->user()->votes()->whereImageId($image->id)->first() && auth()->user()->votes()->whereImageId($image->id)->first()->vote == 0 ) ? "disliked" : "dislike" ' id='$image->id'></a>
</div>
这将执行以下操作 - 它检查当前经过身份验证的用户是否为当前图像投票,如果他已投票,则将 liked
类添加到 <a>
元素中,以防止用户再次喜欢它。如果他还没有投票,则将like
类添加到允许他投票的<a>
元素中。
第二个<a>
元素的逻辑或多或少相同,只是这次是为了不喜欢。
不幸的是,我不确定如何将长三元运算符从刀片视图移动到控制器。我有一个 PagesController.php,我在其中返回视图并传递图像:
public function index()
$images = Image::orderBy('created_at', 'desc')->get();
return view('home', ['images' => $images]);
我还有 ImagesController.php,其中有我的 uploadImage()
和 deleteImage()
函数。
是否有可能以某种方式将此逻辑从我的视图移至控制器,如果可以,我将非常感谢有关如何执行此操作的任何指导。
【问题讨论】:
投票是图像上的关系吗? 将逻辑移到图像模型中怎么样?你可以创建像 votedLiked() 和 votedDisliked() 这样的东西,你可以传入用户来分离依赖 @Devon 是的,我的图像和用户模型与投票有很多关系 将auth()->user()->votes()->whereImageId($image->id)->first()
分配给一个变量或一个函数,这样您就不必多次调用它。 ->first()
执行数据库查询,因此您当前在该页面上运行了 4 个额外的查询...这非常低效。
【参考方案1】:
我喜欢 khartnett 在模型中处理此问题的想法,但为了提高效率,特别是在处理许多图像时,您可以急切地从控制器加载投票关系,条件与当前用户匹配。
$images = Image::with(['votes' => function($q) $q->where('user_id', auth()->id()); ])
->orderBy('created_at', 'desc')
->get();
然后每个图像都会有一个该用户的投票集合:
$vote = $image->votes->first();
因此,虽然它不能完全解决您的问题,但最好的部分是它只需要 2 个查询而不是 n+1 个查询。
【讨论】:
【参考方案2】:您可以尝试迭代 $images
并将附加属性“类”传递给带有图像的数组,然后在刀片中执行以下操作:
<a href='#' class='vote $image->classlike ' id='$image->id'></a>
<a href='#' class='vote $image->classdislike ' id='$image->id'></a>
在控制器处:
$images = $images->map(function ($image)
$image['classlike'] = ( auth()->user()->votes()->whereImageId($image->id)->first() && auth()->user()->votes()->whereImageId($image->id)->first()->vote == 1 ) ? "liked" : "like";
$image['classdislike'] = ( auth()->user()->votes()->whereImageId($image->id)->first() && auth()->user()->votes()->whereImageId($image->id)->first()->vote == 0 ) ? "disliked" : "dislike";
return $image;
);
使用@Devon 方法,您可以以这种优化的方式进行:
$images = Image::with(['votes' => function($q)
$q->where('user_id', auth()->user()->id);
])
->orderBy('created_at', 'desc')
->get();
$images = $images->map(function ($image)
$image['classlike'] = ( $image->votes->first() && $image->votes->first()->vote == 1 ) ? "liked" : "like";
$image['classdislike'] = ( $image->votes->first() && $image->votes->first()->vote == 0 ) ? "disliked" : "dislike";
return $image;
);
return view('home', ['images' => $images]);
【讨论】:
所以在将 $images 传递给我的视图之前,我首先必须遍历它们,确定用户是否喜欢/不喜欢或根本没有投票,并将该信息添加到 $images数组,然后将其传递给我的视图? @Bobimaru 是的,看看例子 我不知道为什么,但我得到了“未定义的属性:Illuminate\Auth\AuthManager::$id”,因为“$q->where('user_id', auth()- >id);" @Bobimaru 他错过,尝试,更新:auth()->user()->id
是的,它是auth()->id()
,这是一个方法而不是一个属性,对不起以上是关于想不出一种将长三元运算符从我的刀片视图移动到控制器的方法的主要内容,如果未能解决你的问题,请参考以下文章