预先加载的模型返回父模型属性的空集


Eager loaded model returns empty set for parent model property

我正在尝试用它们的父模型加载两个模型。不过,我为关系函数设置了一个空值。

以下是我加载模型的方式:

Master_Key控制器(显示方法):

$master_keys = Version2015_Master_Key::with('version2015_question')->paginate(50);
            return view('masterkey/show',compact('master_keys'));

响应控制器(显示方法):

$responses = Version2015_Response::with('version2015_question')->paginate(50);
         return view('response/show',compact('responses'));

我想显示主密钥和响应以及匹配的问题。以下是我对主密钥控制器show.blade.php中的片段:

<table class="table">
        <tr>
          <th>Ref Number</th>
          <th>Question</th>
          <th>Expected Response</th>
          <th>Additional Information</th>
        </tr>
        @foreach ($master_keys as $master_key)
        <tr>
          <td>{{ $master_key->question_num }} </td>
          <td>{{ $master_key->version2015_question }} </td>
          <td>{{ $master_key->expected_response }} </td>
          <td>{{ $master_key->additional_information }} </td>
        </tr>
        @endforeach
      </table> 

<td>{{ $master_key->version2015_question }} </td>是唯一尝试显示父表中数据的行。它实际上应该是<td>{{ $master_key->version2015_question->question_text }} </td> ->但是当我尝试这样做时,它会抛出一个错误,说我正在尝试从非对象访问属性。<td>{{ $master_key->version2015_question }} </td>返回一个空集。所有其他属性返回预期数据(因为它们属于主密钥模型本身)。

有三种型号:Version2015_QuestionVersion2015_ResponseVersion2015_Master_Key。 它们都在名称空间中 app'version2015 .我将只发布其中的两个(因为响应和主密钥具有相同的结构和相同的行为):

问题模型

use Illuminate'Database'Eloquent'Model;
class Version2015_Question extends Model
{
    protected $table = 'Version2015_questions';
    protected $primaryKey = 'question_num';
    public $timestamps = false;
    public function version(){
        return $this->belongsTo('App'Version');
    }
    public function Version2015_responses(){
        return $this->hasMany('App'Version2015'Version2015_Response','question_num','question_num');
    }
    public function version2015_master_keys(){
        return $this->hasMany('App'Version2015'Version2015_Master_Key','question_num','question_num');
   }
    protected $fillable = ['question_num','question_text','version_id'];
}

响应模型:

namespace App'Version2015;
use Illuminate'Database'Eloquent'Model;
use App'Encryptable;
class Version2015_Response extends Model
    {
        use Encryptable;
        protected $fillable = ['response','additional_information', 'question_num', 'vendor_id', 'label_id', 'group_id'];
        protected $encryptable = ['response','additonal_information'];
        protected $table = 'version2015_responses';
        public $timestamps = false;
        public function version2015_question(){
        return $this->belongsTo('App'Version2015'Version2015_Question','question_num','question_num');
     }
    public function vendor(){
        return $this->belongsTo('App'Vendor');
    }
    public function group(){
        return $this->belongsTo('App'Group');
    }
    public function response_label(){
        return $this->belongsTo('App'Response_Label');
    }
}

我不打算发布迁移,因为这篇文章中的代码已经太多了。当我运行php artisan migrate它工作正常时。当我创建responsesmaster keys时,questions表中引用的外键没有问题。所以我假设数据库方面没有问题。我相信这与模型和关系有关。我花了几个小时查看整个代码并查找其他线程。我没有得出任何结论,为什么它不从questions模型中提取问题数据。我正在对应用程序中的许多其他模型进行此类查询,但它只发生在这三个模型上 - 它们恰好是它们自己命名空间中唯一的模型。

    • 更新--

Version2015_question@MarcoAurélioDeleu要求的型号

namespace App'Version2015;
use Illuminate'Database'Eloquent'Model;
use App'Encryptable;
class Version2015_Master_Key extends Model
{
    use Encryptable;
    public $timestamps = false;
    protected $table = 'version2015_master_keys';
    protected $fillable = ['question_num','expected_response','group_id','label_id','additional_information'];
protected $encryptable = ['expected_response','additional_information'];
public function version2015_question(){
    //return $this->belongsTo('App'version2015'version2015_Question','question_num','question_num');
        return $this->belongsTo('App'Version2015'Version2015_Question');
    }
public function master_key_label(){
    return $this->belongsTo('App'Master_Key_Label');
}
public function group(){
    return $this->belongsTo('App'Group');
}
}

我找到了解决方案!我所要做的就是明确设置Laravel应该在父模型中查找哪个主键,因为它不遵循约定"id"而是"question_number"。 我之前正在这样做,但有一个额外的参数return $this->belongsTo('App'version2015'version2015_Question','question_num','question_num');,然后我尝试了没有任何论据return $this->belongsTo('App'version2015'version2015_Question');.但是,我应该简单地指出父表中的主键是什么:return $this->belongsTo('App'version2015'version2015_Question','question_num'); 。另一个父表return $this->belongsTo('App'Master_Key_Label','label_id');也是如此。

除此之外,父表不需要像我所做的那样为其子表显式定义:return $this->hasMany('App'version2015'version2015_Response','question_num','question_num'); .它只需要子模型名称。

所以,这就是我的模型现在的样子:

问题模型

use Illuminate'Database'Eloquent'Model;
class Version2015_Question extends Model
{
    protected $table = 'Version2015_questions';
    protected $primaryKey = 'question_num';
    public $timestamps = false;
    public function version(){
        return $this->belongsTo('App'Version');
    }
    public function Version2015_responses(){
        return $this->hasMany('App'Version2015'Version2015_Response');
    }
    public function version2015_master_keys(){
        return $this->hasMany('App'Version2015'Version2015_Master_Key');
   }
    protected $fillable = ['question_num','question_text','version_id'];
}

响应模型:

namespace App'Version2015;
use Illuminate'Database'Eloquent'Model;
use App'Encryptable;
class Version2015_Response extends Model
    {
        use Encryptable;
        protected $fillable = ['response','additional_information', 'question_num', 'vendor_id', 'label_id', 'group_id'];
        protected $encryptable = ['response','additonal_information'];
        protected $table = 'version2015_responses';
        public $timestamps = false;
        public function version2015_question(){
        return $this->belongsTo('App'Version2015'Version2015_Question','question_num');
     }
    public function vendor(){
        return $this->belongsTo('App'Vendor');
    }
    public function group(){
        return $this->belongsTo('App'Group');
    }
    public function response_label(){
        return $this->belongsTo('App'Response_Label', 'label_id');
    }
}

主密钥模型与响应密钥中相同。

我还注意到另一个问题。出于某种原因,即使使用正确的设置,我也无法急于加载相关模型。我的控制器有这个:

  $responses = version2015_Response::with('version2015_question')
  ->where('label_id','=',$label->id)
  ->paginate(50);

现在我必须这样做:

  $responses = version2015_Response::where('label_id','=',$label->id)
  ->paginate(50);

好吧,一切都完成了,一切正常。我希望它能帮助其他有类似问题的人。