Laravel加载模型后仅调用方法一次

5

我正在尝试在模型的构造函数中检查当前已验证用户是否被允许访问给定的模型,但是我发现构造函数上下文中的$this为空。在Laravel中,属性赋值在哪里,以及在所有属性加载后如何调用方法?

public function __construct(array $attributes = [])
{
    parent::__construct($attributes);
    var_dump($this); // empty model
    $this->checkAccessible();

}

预先祝愿您成功。


你可以使用这个 http://laravel.io/bin/7wJ6D 。但问题是 - 为什么你想在模型中这样做呢? - Jarek Tkaczyk
@JarekTkaczyk 谢谢,我最终做了类似的事情。我想在模型中这样做的原因是,这样我就可以在控制器中只需执行 Model::find($id);,而基础模型类将会处理当前认证用户是否有权访问资源的问题。 - Brad Reed
3个回答

3
如其他答案和评论所述,有更好的方法来实现该问题的目标(至少在现代Laravel中)。在这种情况下,我会参考文档中涉及到门和策略的授权章节。
然而,为了回答如何在模型属性加载后调用方法的具体问题 - 您可以监听Eloquent“retrieved”事件。在类中最简单的方法是使用在类“booted()”方法中的闭包。
protected static function booted()
{
    static::retrieved(function ($model) {
        $model->yourMethod() //called once all attributes are loaded
    });
}

您也可以使用监听器以正常方式监听这些事件。请参阅Eloquent 事件文档。


0

你可以使用控制器过滤器来检查用户是否已登录,然后调用任何模型函数。

public function __construct(array $attributes = []){     
  $this->beforeFilter('auth', array('except' => 'login')); //login route

   if(Auth::user()){
        $user_id = Auth::user()->user_id;
        $model = new Model($attributes);
        //$model = User::find($user_id);
   }
 }

从构造函数将属性绑定到模型

Model.php

public function __construct(array $attributes = array())
{
    $this->setRawAttributes($attributes, true);
    parent::__construct($attributes);
}

用户已经通过身份验证。checkAccessible 方法检查模型上的 "created_by" 属性与 Auth::user()->id 是否相等。如果不相等,它会抛出一个异常。 - Brad Reed

0
正如Rory所提到的,retrieved事件负责此操作。 而且,如果你需要编写大量代码或只有几个处理程序,使用事件/监听器方法可以更清晰地以面向对象的方式进行编写。
正如这里所述,您只需为Model创建一个事件即可。
    protected $dispatchesEvents = [
        'retrieved' => UserLoaded::class,
    ];

你需要创建这个类,Eloquent事件默认接受模型:
class UserLoaded
{
    protected User $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

然后这里描述了如何为此事件声明监听器。它应该在EventListenerProvider中的某个地方,就像这样:

    protected $listen = [
        UserLoaded::class => [
            UserLoadedListener::class
        ],
    ];

监听器应该只需实现方法handle()(请查看文章),例如:
    public function handle(UserLoaded $event)
    {
        // your code
    }

另一种可能性是注册模型观察者,就像这里描述的一样here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接