Laravel雄辩:存储模型及相关子模型

Laravel雄辩:存储模型及相关子模型,laravel,eloquent,Laravel,Eloquent,我得到了模型考试和问题。简化代码: class Exam { public function questions() { return $this->hasMany('Question'); } // ... } class Question { public function exam() { return $this->belongsTo('Exam'); } // ... } 现在我想上传一个包

我得到了模型考试和问题。简化代码:

class Exam {
    public function questions() {
        return $this->hasMany('Question');
    }
    // ...
}

class Question {
    public function exam() {
        return $this->belongsTo('Exam');
    }
    // ...
}
现在我想上传一个包含考试数据的文件。解析器类将创建检查,而不保存它。然后逐步创建问题并添加到考试中。最后,所有内容都应保存在事务中

class ExamParser {
    $exam = new Exam();
    // ...
    while ($linesRemaining) {
        $question = new Question();
        // ...
        $exam->questions[] = $question;    // something like this?
    }
    $exam->saveTogetherWithQuestions();    // how do i realize this?
}

我基本上知道如何保存相关模型,但不知道如何关联它们并在以后保存整个构造。

首先创建一个
问题数组。然后创建一个
考试
,并通过
考试
的关系保存所有问题。将所有代码放入事务中

class ExamParser {
    $exam = new Exam();
    // ...
    while ($linesRemaining) {
        $question = new Question();
        // ...
        $exam->questions[] = $question;    // something like this?
    }
    $exam->saveTogetherWithQuestions();    // how do i realize this?
}
更新:将模型创建从事务执行中移出

$questions = [];
while ($linesRemaining) {
    $question = new Question();
    // ...
    $questions[] = $question;
}

$exam = new Exam();
// ...

DB::transaction(function() {
    $exam->save();
    $exam->questions()->saveMany($questions);
});

重要提示:在将
问题
附加到考试之前,必须先保存
考试
。父级
Exam
必须首先有自己的主键(通过保存自身)才能允许连接成功。否则,您将在没有父id的情况下保存
问题。

首先创建
问题的数组。然后创建一个
考试
,并通过
考试
的关系保存所有问题。将所有代码放入事务中

class ExamParser {
    $exam = new Exam();
    // ...
    while ($linesRemaining) {
        $question = new Question();
        // ...
        $exam->questions[] = $question;    // something like this?
    }
    $exam->saveTogetherWithQuestions();    // how do i realize this?
}
更新:将模型创建从事务执行中移出

$questions = [];
while ($linesRemaining) {
    $question = new Question();
    // ...
    $questions[] = $question;
}

$exam = new Exam();
// ...

DB::transaction(function() {
    $exam->save();
    $exam->questions()->saveMany($questions);
});

重要提示:在将
问题
附加到考试之前,必须先保存
考试
。父级
Exam
必须首先有自己的主键(通过保存自身)才能允许连接成功。否则,您将在没有家长id的情况下保存问题。

谢谢您的回答:)我仍然有这样的想法,但对我来说似乎不太完美。将事务代码最小化并仅将保存操作放在那里不是更好吗?如果有几个答案与一个问题相关,你会怎么做?难道没有办法先构建对象层次结构(使用成员而不是数组),然后一次性保存所有内容吗?你是对的。我更新了代码以最小化事务。据我所知,从我自己的实验来看,没有办法用雄辩的模型来“一气呵成”。您必须按层次结构创建和保存新对象,从父对象开始,然后创建其子对象并将其附加到父对象,等等。但是,将问题保留在数组中而不是作为考试的成员对我来说似乎是不合理的。如果关系结构更复杂,你必须创建一个深层数组结构,这是间接的。我发现您可以先创建考试,然后使用
$exam->questions->add($question)在考试中收集问题然后您可以使用
$exam->questions()->saveMany($exam->questions)保存它们但看起来不对。我还没有完全理解这些动态变量的行为,比如$exam->QUEST。谢谢你的回答:)我仍然有这样的想法,但它对我来说并不完美。最小化事务代码并只将保存操作放在那里不是更好吗?如果有几个答案与一个问题相关,你会怎么做?难道没有办法先构建对象层次结构(使用成员而不是数组),然后一次性保存所有内容吗?你是对的。我更新了代码以最小化事务。据我所知,从我自己的实验来看,没有办法用雄辩的模型来“一气呵成”。您必须按层次结构创建和保存新对象,从父对象开始,然后创建其子对象并将其附加到父对象,等等。但是,将问题保留在数组中而不是作为考试的成员对我来说似乎是不合理的。如果关系结构更复杂,你必须创建一个深层数组结构,这是间接的。我发现您可以先创建考试,然后使用
$exam->questions->add($question)在考试中收集问题然后您可以使用
$exam->questions()->saveMany($exam->questions)保存它们但看起来不对。我还没有完全理解这些动态变量的行为,比如$exam->question。