在Laravel中尝试获取子模型时,模型关联不起作用。

huangapple go评论62阅读模式
英文:

Models relation not working when trying to get the children models in Laravel

问题

I understand your request. Here's the translated code portion:

我有一个属于模型 `Exam` 的模型 `Question``Exam` 可以有许多问题(一对多关系)。在存储数据时我没有问题,但是当我尝试使用 `Exam::find($exam->id)->questions;` 来获取考试的问题时,我得到了 `NULL`。我已经使用 `dd` 输出了 `Exam::find($exam->id)` 的结果,关系是空的:`#relations: []`

这是我注册我的 `Question` 模型的方式:
```php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Question extends Model
{

    public $timestamps  = false;
    protected $fillable = ['question', 'correct_answer', 'category_id', 'type'];

    public function questionCategory():belongsTo {
        return $this->belongsTo(QuestionCategory::class);
    }

    public function exam(): BelongsTo {
        return $this->belongsTo(Exam::class);
    }
}

这是 Exam 模型:

namespace App\Models;


use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Exam extends Model
{
    public $timestamps = false;
    protected $fillable = ['name'];

    public function question(): HasMany
    {
        return $this->hasMany(Question::class);
    }
}

这是问题表的数据库模式来自迁移文件:

Schema::create('questions', static function (Blueprint $table) {
            $table->id();
            $table->string('question');
            $table->integer('correct_answer')->nullable();
            $table->integer('question_category_id')->default(1);
            $table->integer('exam_id');
            $table->string('type')->default('text');
        });

这是我保存问题数据的方式:

$request->validate([
    'examId' => ['required', 'numeric'],
    'questions' => 'required'
]);

$exam = Exam::find($request->input('examId'));
$questions = $request->input('questions');

foreach ($questions as &$question_entry) {
    // 如果问题不存在则创建问题
    if ((int)$question_entry['id'] === 0) {
        $question = new Question();
    } else {
        $question = Question::find($question_entry['id']);
    }

    $question->exam_id = $exam->id;
    $question->question = $question_entry['body'];
    $question->type = $question_entry['type'];
    $question->question_category_id = $question_entry['category'];
    $question->save();     
}

成功保存到数据库,并且我可以在数据库中看到记录。如果我尝试像 Question::where('exam_id', 1)->get() 这样的操作,我会得到来自该考试的问题,但我不明白为什么当我尝试从父模型获取结果(例如 Exam::find(1)->questions)时,我得到了 NULL。似乎两个模型之间没有关系。

我正在使用 Laravel 10 与 Homestead 和 Breeze。


This should cover the code portion without any additional information.

<details>
<summary>英文:</summary>

I&#39;m having a model `Question` that belongs to model `Exam`. `Exam` can have many questions (one-to-many relation). I&#39;ve no problem with storing the data, but when I try to get the questions for the exam with `Exam::find($exam-&gt;id)-&gt;questions;` I get `NULL`. I&#39;ve `dd` the result for `Exam::find($exam-&gt;id)` and the relations are empty: `#relations: []`. 

This is how I&#39;ve registered my `Question` model:
```php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Question extends Model
{

    public $timestamps  = false;
    protected $fillable = [&#39;question&#39;, &#39;correct_answer&#39;, &#39;category_id&#39;, &#39;type&#39;];

    public function questionCategory():belongsTo {
        return $this-&gt;belongsTo(QuestionCategory::class);
    }

    public function exam(): BelongsTo {
        return $this-&gt;belongsTo(Exam::class);
    }
}

And this is the Exam model:

namespace App\Models;


use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Exam extends Model
{
    public $timestamps = false;
    protected $fillable = [&#39;name&#39;];

    public function question(): HasMany
    {
        return $this-&gt;hasMany(Question::class);
    }
}

Here is the DB schema for the question's table from the migration file:

Schema::create(&#39;questions&#39;, static function (Blueprint $table) {
            $table-&gt;id();
            $table-&gt;string(&#39;question&#39;);
            $table-&gt;integer(&#39;correct_answer&#39;)-&gt;nullable();
            $table-&gt;integer(&#39;question_category_id&#39;)-&gt;default(1);
            $table-&gt;integer(&#39;exam_id&#39;);
            $table-&gt;string(&#39;type&#39;)-&gt;default(&#39;text&#39;);
        });

Also this is how I'm saving the data for the questions:

$request-&gt;validate([
    &#39;examId&#39; =&gt; [&#39;required&#39;, &#39;numeric&#39;],
    &#39;questions&#39; =&gt; &#39;required&#39;
]);

$exam = Exam::find($request-&gt;input(&#39;examId&#39;));
$questions = $request-&gt;input(&#39;questions&#39;);

foreach ($questions as &amp;$question_entry) {
    // create the question if it doesn&#39;t exist
    if ((int)$question_entry[&#39;id&#39;] === 0) {
        $question = new Question();
    } else {
        $question = Question::find($question_entry[&#39;id&#39;]);
    }

    $question-&gt;exam_id = $exam-&gt;id;
    $question-&gt;question = $question_entry[&#39;body&#39;];
    $question-&gt;type = $question_entry[&#39;type&#39;];
    $question-&gt;question_category_id = $question_entry[&#39;category&#39;];
    $question-&gt;save();     
}

The saving to the DB is successful and I can see the entries in the DB. And if I try to do something like Question::where(&#39;exam_id&#39;,1)-&gt;get() I will get the questions from that exam, but I don't understand why when I try to get the results from the parent model (like Exam::find(1)-&gt;questions) I get NULL`. It seems like there is no relation between the two models.

I'm using Laravel 10 with Homestead and Breeze.

答案1

得分: 1

I see you are using the singular question in your relation definition in the Exam model. That could be the reason why it is null.

Did you also try the plural questions, like this:

public function questions(): HasMany
{
    return $this->hasMany(Question::class);
}

The rest of the code seems fine, but you could also create the foreign id like this:

$table->foreignId('exam_id');

You can read more about foreign keys in the documentation.

英文:

Is see you are using the singular question in your relation definition in the Exam model.
That could be the reason why it is null.

Did you also try the plural questions, like this:

public function questions(): HasMany
{
    return $this-&gt;hasMany(Question::class);
}

The rest of the code seems fine, but you could also create the foreign id like this:

$table-&gt;foreignId(&#39;exam_id&#39;);

You can read more about foreign keys in the documentation

huangapple
  • 本文由 发表于 2023年5月22日 17:17:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76304668.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定