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 for attach()
which exists on the hasMany
relationships but seem to be missing in hasOne
.
First off, you misunderstood the relation you refer to.
Here's what you need:
then you can link them together like this:
You can explicitly pass an id to associate as well:
You can't do this:
for this way Eloquent handles model attributes, not relations.
Question 2:
Answering question 1 for me both methods are good, you don't need to change anything.
Answering question 2 you should do it as you showed. ORM won't create automatically
QuestionType
until you use manuallysave
method.For example if you used code:
what ORM should decide? Question isn't connected to any of
$t
or$t2
so ORM won't decide it for you. You need to tell ORM what's the type.I'm not an ORM/Eloquent expert but I think you expect too much from ORM. ORM shouldn't guess what you want to do. It help you manage relations or objects but it won't associate objects if you don't tell it to do so.
You could however try with mutator. You could add to your Question model:
and now it should be possible to use
$q->type = $t;
(However I haven't tested it)