So this isn’t my actual scenario, but I think it illustrates my problem quite well. Imagine an online school report system. I have Teachers, Students, and Reports. Teachers and Students are both Users. The relationship between Students and Reports is one-to-one (a student just has a single report card), but between Teachers and Reports is one-to-many (a teacher has a whole classroom-worth of reports.) The Report model has both a student_id and a teacher_id, both of which are foreign keys to the User table.
I’d like to represent these relationships in my models, so for a given User I can call:
User::find(5)->reports;
I expect you can already see a problem!
So the following is something like pseudocode (since I don’t think it will work!) but here’s roughly what I want to do:
class User extends Eloquent {
public function reports() {
switch($this->user_type->name) {
case 'student':
return $this->has_one('Report', 'student_id');
break;
case 'teacher':
return $this->has_many('Report', 'teacher_id');
break;
return null;
}
}
// Just for a bit of background, here's the separate relationship to my UserType model
// which I'm sure is very standard!
public function user_type() {
return $this->belongs_to('UserType', 'user_type_id');
}
}
I think there’s a fundamental problem with the above, but if I’m mistaken about that please let me know!
An alternative method would be to define student_report() and teacher_reports() methods, but this is a bit weird because e.g. for a teacher instance..
$teacher->student_report;
..is meaningless. Similarly:
$student->teacher_reports;
..is also meaningless. They could simply return null, which seems ok, but it is not really a very elegant solution.
Ok so the alternative method I was considering is to subclass my User model:
class User extends Eloquent {
public function reports() {
return null;
}
// etc..
}
class Student extends User {
public static $table = 'users';
public function reports() {
// I know I said the relationship here is one-to-one..!
// But I don't mind hacking this too much.
return $this->has_many('Report', 'student_id');
}
}
class Teacher extends User {
public static $table = 'users';
public function reports() {
return $this->has_many('Report', 'teacher_id');
}
}
This actually works fine! However, something like:
Teacher::all();
..will return all Users, which is clearly not a meaningful result. I want to automatically append a WHERE user_type=?
to lots of the queries that Eloquent runs. I can do this by implementing Eloquent methods in my subclasses, but this seems really like overkill! So what’s the alternative? Could I add something in my Teacher and Student constructors that ensure this extra WHERE clause is appended to queries?
That is a very good question. I am also looking for an answer :( I am getting kind of desperate.