【问题标题】:Accessing lazily eager loaded properties访问延迟加载的属性
【发布时间】:2014-01-25 15:53:40
【问题描述】:

我有以下查询返回一个对象,然后将其发送到视图

$user = $this->user->find($id)
            ->load(
                'images',
                'albums',
                'measurements',
                'medicalAnswers.medicalQuestion',
                'goals.strengthGoalDesc.excersise',
                'goals.distanceGoalDesc.excersise',
                'goals.bodyGoalDesc',
                'client.trainers.user',
                'trainer.clients.user',
                'trainer.classes',
                'trainer.types',
                'trainer.programs.weeks.days.sessions.phases.excersises',
                'trainer.testimonials'
            );

在视图中,我正在做很多事情来显示所有这些信息,并且一切都很顺利,直到我尝试访问与这些关系相关的属性

            'goals.strengthGoalDesc.excersise',
            'goals.distanceGoalDesc.excersise',

这里是一个例子,一个目标是返回一个有练习的力量目标描述

{
"id":"2",
"userId":"1",
"title":"strength goal title",
"goalDesc":"This should describe my strngth goal in text form",
"goalStatus":"0",
"bodyGoalId":null,
"strengthGoalId":"1",
"distanceGoalId":null,
"created_at":"2014-01-16 15:51:16",
"updated_at":"2014-01-16 15:51:16",
"strength_goal_desc":{
    "id":"1",
    "excersise":{
        "id":"1",
        "name":"Leg Extension",
        "type":"Resistance",
        "variation":null, 
        "equipment":"Machine", 
        "focus":"Legs", 
        "desc":"", 
        "video":null, 
        "created_at":"2014-01-16 15:51:18", 
        "updated_at":"2014-01-16 15:51:18"},
    "sets":"4", 
    "reps":"10",
    "weight":"70.00", 
    "created_at":"2014-01-16 15:51:16", 
    "updated_at":"2014-01-16 15:51:16"}, 
"distance_goal_desc":null,
"body_goal_desc":null} 

我的第一个问题是为什么 bodyGoalDesc、distanceGoalDesc 和strengthGoalDesc 被转换为蛇案例?在我所做的一切(数据库、关系方法等)中,我没有使用蛇案例。

现在我的主要问题

我可以通过

访问目标
@foreach($user->goals as $goal)
    {{ $goal }}
@endforeach

$goal->strengthGoalDesc 返回

{"id":"1","excersise":{"id":"1","name":"Leg Extension","type":"Resistance","variation":null,"equipment":"Machine","focus":"Legs","desc":"","video":null,"created_at":"2014-01-16 15:51:18","updated_at":"2014-01-16 15:51:18"},"sets":"4","reps":"10","weight":"70.00","created_at":"2014-01-16 15:51:16","updated_at":"2014-01-16 15:51:16"}

但是 $goal->strengthGoalDesc->excersise 只返回 1 而 $goal->strengthGoalDesc->excerises->name 给出

ErrorException
Trying to get property of non-object (View: /var/www/app/views/users/show.blade.php)

并尝试像数组一样访问它 $goal->strengthGoalDesc['excersises'] 只返回 1

编辑:我试图访问 name 属性的代码

@elseif($goal->strengthGoalId !== null)
   <th>{{ 'Strength' }}</th>
   <th>

      Excersise: {{ $goal->strengthGoalDesc->excersise->name) }}
      Weight: {{ $goal->strengthGoalDesc->weight }}</br>
      Sets: {{ $goal->strengthGoalDesc->sets }}</br>
      Reps: {{ $goal->strengthGoalDesc->reps }}</br>
   </th>

我认为这可能是因为它是一个集合,但将它包装在 foreach 中只会返回一个无效的参数异常,因为它说它不是一个对象

我确定我只是在做一些愚蠢的事情,但这让我完全迷失了

var_dump($goal->strengthGoalDesc) 输出

null
object(StrengthGoalDesc)[506]
  protected 'guarded' => 
    array (size=0)
      empty
  protected 'table' => string 'strengthGoalDescs' (length=17)
  protected 'connection' => null
  protected 'primaryKey' => string 'id' (length=2)
  protected 'perPage' => int 15
  public 'incrementing' => boolean true
  public 'timestamps' => boolean true
  protected 'attributes' => 
    array (size=7)
      'id' => string '1' (length=1)
      'excersise' => string '1' (length=1)
      'sets' => string '4' (length=1)
      'reps' => string '10' (length=2)
      'weight' => string '70.00' (length=5)
      'created_at' => string '2014-01-16 15:51:16' (length=19)
      'updated_at' => string '2014-01-16 15:51:16' (length=19)
  protected 'original' => 
    array (size=7)
      'id' => string '1' (length=1)
      'excersise' => string '1' (length=1)
      'sets' => string '4' (length=1)
      'reps' => string '10' (length=2)
      'weight' => string '70.00' (length=5)
      'created_at' => string '2014-01-16 15:51:16' (length=19)
      'updated_at' => string '2014-01-16 15:51:16' (length=19)
  protected 'relations' => 
    array (size=1)
      'excersise' => 
        object(Excersise)[480]
          protected 'guarded' => 
            array (size=0)
              ...
          protected 'table' => string 'excersises' (length=10)
          protected 'connection' => null
          protected 'primaryKey' => string 'id' (length=2)
          protected 'perPage' => int 15
          public 'incrementing' => boolean true
          public 'timestamps' => boolean true
          protected 'attributes' => 
            array (size=10)
              ...
          protected 'original' => 
            array (size=10)
              ...
          protected 'relations' => 
            array (size=0)
              ...
          protected 'hidden' => 
            array (size=0)
              ...
          protected 'visible' => 
            array (size=0)
              ...
          protected 'appends' => 
            array (size=0)
              ...
          protected 'fillable' => 
            array (size=0)
              ...
          protected 'dates' => 
            array (size=0)
              ...
          protected 'touches' => 
            array (size=0)
              ...
          protected 'observables' => 
            array (size=0)
              ...
          protected 'with' => 
            array (size=0)
              ...
          public 'exists' => boolean true
          protected 'softDelete' => boolean false
  protected 'hidden' => 
    array (size=0)
      empty
  protected 'visible' => 
    array (size=0)
      empty
  protected 'appends' => 
    array (size=0)
      empty
  protected 'fillable' => 
    array (size=0)
      empty
  protected 'dates' => 
    array (size=0)
      empty
  protected 'touches' => 
    array (size=0)
      empty
  protected 'observables' => 
    array (size=0)
      empty
  protected 'with' => 
    array (size=0)
      empty
  public 'exists' => boolean true
  protected 'softDelete' => boolean false
null

和 *var_dump($goal->stengthGoalDesc['excersise']*

null
string '1' (length=1)
null

【问题讨论】:

  • 执行var_dump 以查看它是什么类型的对象。它可能是一个数组,而不是一个 Std 对象。试试$goal-&gt;strengthGoalDesc['excersise']
  • 感谢您的快速回复 $goal->strengthGoalDesc['excersise'] 只是返回“1”,我已将 var_dump 的输出添加到我的问题中,它对我来说似乎是一个对象

标签: php laravel-4


【解决方案1】:

注意var_dump() 给出的null 输出。第一次和第三次尝试访问$goal-&gt;stengthGoalDesc-&gt;excersise$goal-&gt;stengthGoalDesc 变量是 null,这会导致 ErrorException

尝试将其包装在 if 语句中以检查 $goal-&gt;strengthGoalDesc 是否不为空:

if( $goal->strengthGoalDesc !== null ) {
    var_dump( $goal->strengthGoalDesc->exercise );
}

这应该可以解决 ErrorException。希望对您有所帮助。

【讨论】:

  • 感谢您的回复。我在这里的特殊问题是它不应该为空,因为数据库中有该特定关系的信息。 $goal->strengthGoalDesc 返回的信息(请参阅第 5 个代码块以获取输出)但由于某种原因我无法单独访问
  • @Ir1sh 我明白了。所以问题似乎在于模型之间的关系绑定,对吗?尝试使用DB::getQueryLog() 转储原始查询。也许你会在那里找到答案——因为 ORM 并不总是按预期工作。
  • 对不起,我应该补充一点,它被包裹在一个 if 语句中
  • 原始查询对您有帮助吗?尝试自己对数据库运行它们,大多数情况下这可以帮助您更好地了解幕后发生的事情。
【解决方案2】:

我猜这是一个结构问题(所有数据看起来都不错,但你在糟糕的时候称之为)

@foreach($user->goals as $goal)
    {{ $goal }}
    $goal->strengthGoalDesc->excersise 
    //this will throw an error because not all Goals have strengthGoalDesc
@endforeach

请查看您的 foreach 或粘贴更多代码。 (您尝试使用strengthGoalDesc)

【讨论】:

    【解决方案3】:

    您的问题是您有重叠的属性和关系名称。您有一个名为 exercise 的数据库列以及一个名为相同的关系,并且属性优先于关系。将列重命名为 exerciseId 或其他名称。

    至于到snake_case 的转换,请尝试在您的模型或所有模型扩展的基本模型上设置public static $snakeAttributes = false

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-08
      • 2017-12-28
      • 2013-07-03
      • 1970-01-01
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多