小编And*_*ker的帖子

如何在Laravel模型上延迟加载自定义属性?

是否有任何可能的方式来延迟加载在Laravel模型的自定义属性,而不使用每次加载它appends的财产?我正在寻找类似于你可以懒惰加载雄辩关系的方式.

例如,在模型上给定此访问器方法:

public function getFooAttribute(){
    return 'bar';
}
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这样的事情:

$model = MyModel::all();
$model->loadAttribute('foo');
Run Code Online (Sandbox Code Playgroud)

这个问题是一样的事情的自定义属性添加到负载的Laravel /雄辩的模式?因为它想在每个模型加载上加载自定义属性 - 我希望仅在指定时延迟加载属性.

我想我可以使用与自定义属性相同的名称为模型实例分配属性,但这具有两次调用访问器方法的性能缺点,如果该访问器影响类属性可能会产生意外的副作用,并且只是感觉很脏.

$model = MyModel::all();
$model->foo = $model->foo;
Run Code Online (Sandbox Code Playgroud)

有没有人有更好的方法处理这个?

php laravel laravel-5

8
推荐指数
1
解决办法
4337
查看次数

对一个策略使用多个Auth警卫

我在Laravel 5.4项目中实现了多个Auth警卫(一个用于管理员,另一个用于普通用户).到目前为止,这已经成功运行,管理员和用户都可以登录.我现在正在尝试实现一个适用于两个Auth警卫的Policy类.这是因为我有一些模型,我希望所有管理员都可以编辑,只有拥有该模型的用户才能进行编辑.所以我用这种方法定义了一个策略.

软件\政策\ ModelPolicy

public function update(User $user, Model $model)
{
    if ($user->id === $model->user_id) {
        return true;
    }

    if (Auth::guard('admin')->check()) {
        return true;
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

然后在我的模型控制器方法中:

应用程序\ HTTP \控制器\ ModelController

public function update(Model $model)
{
    $this->authorize('update', $model);

    // update model
}
Run Code Online (Sandbox Code Playgroud)

如果常规用户登录,这将完美地工作.但是,当管理员用户登录时,它甚至没有达到策略(我从错误记录中知道这一点).我猜测如果默认防护Auth::check()失败,Policy类会自动拒绝请求.但是,由于我的用户有几个警卫(不仅仅是默认值)之一是有效的,我需要绕过这种行为.

我知道我可以在我的控制器方法中实现管理逻辑,只有在我知道我正在处理非管理员时才使用该策略:

public function update(Model $model)
{
    if (!Auth::guard('admin')->check()) {
        $this->authorize('update', $model);
    }

    // update model
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我的管理条件比单纯登录更复杂,这可能会迅速失控.更重要的是,所有这些逻辑都属于策略,而不是混淆我的控制器.

如何为多个身份验证保护使用相同的Policy类?

laravel laravel-5

5
推荐指数
1
解决办法
1382
查看次数

Laravel动态关系 - 在渴望加载时访问模型属性

我在Laravel模型上有一个雄辩的关系,它是动态的 - 也就是说,特定数据库字段的值决定了哪个模型将被加载.当我第一次实例化模型实例然后引用关系时,我能够很好地加载这种关系,但是当我急切地加载这种关系时它不起作用.

具体来说,我有一个Product模型.该产品可能是也可能不是其他产品的父母.如果parent_id产品的设置被设置为0那么该产品被视为父产品(无论是否有孩子).如果将parent_id其设置为其他产品的ID,则该产品是子产品.我需要能够访问Product::with('parent')和知道的parent关系将返回要么本身(是的,重复的数据),或者不同的产品,如果它是一个孩子.

这是我到目前为止的关系:

public function parent()
{
    if ($this->parent_id > 0) {
        return $this->belongsTo('App\Product', 'parent_id', 'id');
    } else {
        return $this->belongsTo('App\Product', 'id', 'id');
    }
}
Run Code Online (Sandbox Code Playgroud)

当我急切加载时,$this->parent_id总是未定义,因此即使它实际上是父产品,这种关系也只会自行返回.

关系被急切加载之前,有没有办法访问模型的属性?在我返回关系之前,我考虑过在单独的查询中工作,但我意识到我甚至无法访问产品的id来运行该查询.

如果不可能,还有哪些其他方法可以解决这类问题?这似乎不能通过传统的多态关系来解决.我只有两个可能的想法:

  • belongsTo在我动态确定外键的关系中添加某种约束.
  • 创建我自己的自定义关系,该关系使用基于不同数据库字段的外键.

老实说,我不知道如何实现其中任何一个.我是以正确的方式来做这件事的吗?有什么我可以忽略的吗?


在考虑了这个之后,我认为提出问题的最简单方法是:有没有办法在运行时为关系本身内部的关系动态选择外键?当我调用关系时,我的用例不允许我使用急切的加载约束 - 约束需要应用于关系本身.

php eager-loading laravel eloquent laravel-5

3
推荐指数
1
解决办法
3974
查看次数

标签 统计

laravel ×3

laravel-5 ×3

php ×2

eager-loading ×1

eloquent ×1