Attaching a hasOne model to another Laravel/Eloquent model without specifying id
First off, you misunderstood the relation you refer to.
Here's what you need:
// Question model
public function questionType()
{
return $this->belongsTo('QuestionType', 'type_id');
}
// QuestionType model
public function questions()
{
return $this->hasMany('Question', 'type_id');
}
then you can link them together like this:
$questionType = QuestionType::where(..)->first();
$question = new Question;
... // do something with it
// associate
$question->questionType()->associate($questionType);
// or the other way around - save new question and link to the type:
$questionType->questions()->save($question);
You can explicitly pass an id to associate as well:
$question->type_id = $someTypeId;
$question->save();
You can't do this:
$question->questionType = $someQuestionType;
for this way Eloquent handles model attributes, not relations.
Question 2:
$questionType = new QuestionType(['name' => 'multiple']);
$questionType->save();
$question = new Question([ ... some values ... ]);
// then either this way:
$questionType->questions()->save($question);
// or, again, the other way around:
$question->questionType()->associate($questionType);
$question->save();
olerass
Updated on October 04, 2020Comments
-
olerass over 3 years
Background
Given we have the following two tables where type_id references a row in questionType:
question
id | type_id | description ---+---------+------------ 1 | 1 | A nice question .. | .. | ..
questionType
id | name ---+---------------- 1 | Multiple-choice .. | ..
with the following Eloquent models:
class Question extends Model { public function type() { return $this->hasOne( 'QuestionType', 'id', 'type_id' ); } } class QuestionType extends Model { }
Question 1
How can I add a new question that references an existing question type without manually doing anything with ids? For example the following works but is ugly imo since I have to manually assign the corresponding question type id:
$q = new Question; $q->type_id = 1; // Multiple-choice $q->description = 'This is a multiple-choice question'; $q->save();
One would think there was a way to let the ORM handle the id-assignment (isn't the point to avoid stuff like this with ORMs?), something along the lines of (this does not work in Eloquent ORM):
$q = new Question; $q->type = QuestionType.where('name', '=', 'Multiple-choice'); $q->description = 'This is a multiple-choice question'; $q->save();
Question 2
In relation to question 1, how would I go about adding a new question that references a new question type without manually doing anything with ids? Similarly I imagine something along the lines of:
$t = new QuestionType; $t->name = 'Another type'; $q = new Question; $q->type = $t; $q->description = 'This is a multiple-choice question'; $q->save();
Here I'd like
$q->save()
to save both the new question type and question (or something similar).The following works, but again I'm assigning the id myself which I believe the ORM should handle:
$t = new QuestionType; $t->name = 'Another type'; $t->save(); $q = new Question; $q->type = $t->id; $q->description = 'This is a multiple-choice question'; $q->save();
I've tried playing with different combinations of
save()
,update()
methods without luck. I also looked forattach()
which exists on thehasMany
relationships but seem to be missing inhasOne
. -
olerass over 9 yearsRegarding question 1: the second method is pseudocode, it does not work in Laravel (Eloquent ORM). Or at least, I do not know how to do it. Do you? Regarding question 2: you are connecting Question to $t at
$q->type = $t
, so I'm not sure I understand your concern about what the ORM should decide. Of course it should save $t and $q at$q->save()
, and if you do not connect $t2 to anything or save it manually it is not saved. -
olerass over 9 yearsThanks so much Jarek! It seems I had mixed up the semantics of
hasOne
andbelongsTo
. In my mind$this->hasOne('QuestionType')
where$this
is aQuestion
means that Question has a QuestionType. After all that's what it implies when you real it aloud right?. But apparently it's the other way around -- confusing! -
Jarek Tkaczyk over 9 years@olerass It might be misleading in the beginning. But think about it - does really a question have a type? No, it rather belongs to a type and that's what Eloquent implies.
-
Andrew Mast over 6 yearsI know this is an old thread, but I have a solution where you can directly set the question type with
$question->questionType = $someQuestionType;
. Code: Pastebin -
Stanley Aloh over 3 yearsThis helped me overcome a problem I had with user having one roles in my laravel application