Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php firstOrFail从雄辩的查询生成器返回错误的记录_Php_Laravel_Laravel 4_Eloquent - Fatal编程技术网

Php firstOrFail从雄辩的查询生成器返回错误的记录

Php firstOrFail从雄辩的查询生成器返回错误的记录,php,laravel,laravel-4,eloquent,Php,Laravel,Laravel 4,Eloquent,我的数据库中有一个名为计数的表,用于跟踪特定实体的计数。表中的两个关键字段是: 类型:实体的名称 计数:实体的计数 现在在表中我有两条记录,第一条记录的类型为硬盘驱动器,第二条记录的类型为监视器 我的存储库中有一种方法,用于增加计数表中特定记录的计数: public function decreaseCountBy($type, $number){ $countCollection = $this->tally->where('type', '=', $type )-&

我的数据库中有一个名为
计数
的表,用于跟踪特定实体的
计数。表中的两个关键字段是:

  • 类型:实体的名称
  • 计数:实体的计数
现在在表中我有两条记录,第一条记录的类型为
硬盘驱动器
第二条记录的类型为
监视器

我的存储库中有一种方法,用于增加
计数表中特定记录的计数:

public function decreaseCountBy($type, $number){

    $countCollection = $this->tally->where('type', '=', $type )->firstOrFail();

    $record = $countCollection->first();

    // Troubleshooting output
    die(var_dump([$type, $record->toArray()]));

    // The rest of the method
    $record->count -= $number;
    $result = $record->save();
    if(!$result){
        throw new \Exception('Error saving decrementation');
    }
    return $record->count;
}
当我向increment
监视器发送请求时,用此方法查看故障排除模具和转储的输出,并获得以下输出:

array (size=2)
  0 => string 'monitors' (length=8)
  1 => 
    array (size=5)
      'id' => int 4
      'type' => string 'hardDrives' (length=10)
      'count' => int 15
      'created_at' => string '2014-12-21 03:50:04' (length=19)
      'updated_at' => string '2014-12-21 14:35:28' (length=19)
即使我使用
监视器
作为查询中
$type
的值,我也会得到
硬盘驱动器
的记录

在此之后,我尝试更改方法以触发查询:

$countCollection = $this->tally->where('type', $type )->get();
然后我得到了正确的结果:

array (size=2)
  0 => string 'monitors' (length=8)
  1 => 
    array (size=5)
      'id' => int 5
      'type' => string 'monitors' (length=8)
      'count' => int 3
      'created_at' => string '2014-12-21 03:50:04' (length=19)
      'updated_at' => string '2014-12-21 03:50:04' (length=19)
如果查找记录时出错,我可以在这里停止并添加我自己的异常抛出,但是当我阅读构建器类的“method
firstOrFail()
(很抱歉,我无法直接链接到它)时,该方法描述为:

执行查询并获得第一个结果或引发异常

我想使用内置的Laravel异常,当找不到记录时会抛出该异常,而不是使用我自己的异常

这里有我遗漏的东西吗?当我在laravel文档中查找其他示例时,看起来我正确地构建了查询

最重要的是,我想知道为什么它会失败,而不仅仅是一个变通办法

分辨率

以下是该方法的最终版本,旨在向所有人展示其最终结果:

public function decreaseCountBy($type, $number){
    $record = $this->tally->where('type', '=', $type )->firstOrFail();
    $record->count -= $number;
    $result = $record->save();
    if(!$result){
        throw new \Exception('Error saving decrementation');
    }
    return $record->count;
}
通常在执行
->get()时
要检索数据,结果是一个雄辩的
集合
实例,其中包含多条记录。从那里,如果您只想检索第一条记录,您可以使用Collection类的
->first()
方法获得一个具有该记录信息的雄辩的
模型
类实例

firstOrFail()
的情况下,您要告诉查询生成器的是,您只需要找到第一条记录。因为您只会收到一条记录的数据,所以eloquent跳过收集并返回一个模型实例


在上面的代码中,我删除了“获取第一条记录的模型”的行,即
$record=$countCollection->first()
,并重命名变量以更好地适应预期结果,即用
$record
代替
$countCollection

在您已经调用了
firstOrFail()
之后,无需调用
first()
。firstOrFail()已返回单个模型而不是集合,对模型调用
first()
将触发一个全新的select语句(这次没有
where

正如@Jarek Tkaczyk在下面指出的,使用您的代码,将对DB运行两个查询

  • type=?
  • 从盘点中选择*
  • 这意味着在您的情况下,第一个查询的结果将被第二个查询覆盖

    一些背景资料
    firstOrFail()
    除了调用
    first()
    然后在
    first()
    返回
    null

    public function firstOrFail($columns = array('*'))
    {
        if ( ! is_null($model = $this->first($columns))) return $model;
    
        throw (new ModelNotFoundException)->setModel(get_class($this->model));
    }
    

    不确定这是否是导致问题的原因,但在使用
    firstOrFail()
    后,您肯定不需要调用
    first()
    firstOrFail()
    已返回单个模型,而不是必须已返回的集合。当我从记录中删除
    first()
    时,它工作了。这也是有道理的,如果我首先调用单个
    talls
    model实例,就像说“嘿,给我找到的记录,然后给我表中的第一条记录”。如果你想提交答案,我会给你支票。好的。当然可以:)谢谢你提供的额外细节。这并不是说再次调用
    没有意义。实际上,它返回完全不同的结果。引擎盖下有两个db查询:
    select*from-tallises,其中type=?
    然后对第一次查询返回的模型调用
    select*from-tallises
    。@JarekTkaczyk Ooops你说得对。我忽略了model类中的
    \u调用
    ,该调用创建了一个新的查询,因此运行了一个新的select语句。我会相应地更新答案。谢谢你指出这一点。