[英]In laravel how to pass extra data to mutators and accessors
我想要做的是将每篇文章的评论附加到文章对象,但问题是我每次都需要请求不同数量的评论。
出于某种原因,我需要为此使用修改器,因为有时我请求 50 篇文章,但我不想遍历结果并附加评论。
那么是否可以执行以下操作以及如何传递额外参数。
这是模型:
class Article extends Model
{
protected $appends = ['user', 'comments', 'media'];
public function getCommentsAttribute($data, $maxNumberOfComments = 0)
{
// I need to set maxNumberOfComments
return $this->comments()->paginate($maxNumberOfComments);
}
}
这是控制器:
class PostsController extends Controller
{
public function index()
{
//This will automatically append the comments to each article but I
//have no control over the number of comments
$posts = Post::user()->paginate(10);
return $posts;
}
}
我不想做的是:
class PostsController extends Controller
{
public function index()
{
$articles = Post::user()->all();
$number = 5;
User::find(1)->articles()->map(function(Article $article) {
$article['comments'] = $article->getCommnets($number);
return $article;
});
return Response::json($articles);
}
}
有没有更好的方法来做到这一点? 因为我经常使用它并且它接缝不正确。
从 Laravel 源代码来看,不——不可能向这个神奇的访问器方法传递额外的参数。
最简单的解决方案是在您的类中添加另一个额外的方法来接受您希望的任何参数——并且您可以使用该方法而不是魔法属性。
例如。 只需将您的getCommentsAttribute()
重命名为getComments()
并在您的视图中触发->getComments()
而不是->comments
,您就可以开始了。
这个问题已经有一段时间了,但也许有人也会需要它。
这是我的方式
{
/**
* @var string|null
*/
protected ?string $filter = null;
/**
* @return UserSettings[]|null
*/
public function getSettingsAttribute(): ?array
{
return services()->tenants()->settings($this)->getAll();
}
/**
* @return FeatureProperty[]|null
*/
public function getFeaturePropertiesAttribute(): ?array
{
return services()->tenants()->featureProperty($this)->getListByIds($this->filter);
}
/**
* @param string|null $filter
* @return Tenant
*/
public function filter(string $filter = null): Model
{
$this->filter = $filter;
return $this;
}
Accessor 正在使用一些服务来获取值。 服务接受参数,在我的例子中是字符串,将与featureProperty->name
进行比较
当你在 filter 方法中返回$this时,魔法就会发生。
调用访问器的常规方法是:
$model->feature_properties
扩展方式:
$model->filter('name')->feature_properties
由于过滤器参数可以为空,我们可以有这样的访问器:
$filter = null
$model->filter($filter)->feature_properties
如果你想多玩一点,你可以考虑覆盖模型 getAttribute 或魔术 __call 方法,以类似于 Laravel 作用域的方式实现过滤器
我只是在模型上设置了一个公共属性。 在访问点,我将该属性更新为我想要的值。 然后,在属性方法中,我从该属性中读取所需的参数。 所以,把所有这些放在一起,
// Model.php
public $arg1= true;
public function getAmazingAttribute () {
if ($this->arg1 === false)
$this->relation()->where('col', 5);
else $this->relation()->where('col', 15);
}
// ModelController.php
$instance->arg1 = false;
$instance->append('amazing');
我知道这是一个老问题,但还有另一种选择,但可能不是最好的:
$articles = Post::user()->all();
$number = 5;
$articles->map(function($a) use($number){
$a->commentsLimit = $number;
return $a;
});
然后在 getCommentsAttribute() 中:
return $this->comments()->paginate($this->commentsLimit);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.