简体   繁体   中英

Laravel 4: Model Relationships Not Working (sort of)?

I have 3 models in my Laravel 4 project: Employee , EmployeeClass , Employer :

class Employee extends Eloquent {
    protected $table = 'users';
    public function employee_class () {
        return $this->belongsTo('EmployeeClass', 'employee_class_id');
     }
}
class EmployeeClass extends Eloquent {
    protected $table = 'employee_classes';
    public function employees () {
        return $this->hasMany('Employee');
    }

    public function employer () {
        return $this->belongsTo('Employer');
    }
}
class Employer extends Eloquent {
    protected $table = 'employers';
    public function employee_classes () {
        return $this->hasMany('EmployeeClass');
    }   
}

The EmployeeClass relationships work as expected. I can execute EmployeeClass::find(1)->employees; or EmployeeClass::find(1)->employer; and it returns the object.

Trying to make the same calls on the other two (to retrieve the relationship to EmployeeClass ) doesn't work. Both of these lines return empty sets:

Employee::find(1)->employee_class;
Employer::find(1)->employee_classes;

However, the weird thing is, both of these lines work correctly:

Employee::find(1)->employee_class()->first();
Employer::find(1)->employee_classes()->first();

The first example returns NULL (I believe it should be returning a Collection ). The second example returns an EmployeeClass object (the expected instance).

I want to point out that there is one entry in each table with an id of 1, and each one is set up with the FK = 1 as well, so they should join properly. In fact, I think the fact that EmployeeClass works correctly, and the fact that getting the query and executing it (in the second, successful, set of code) does as well, sort of proves that.

I'm sure I'm just doing something stupid; maybe another set of eyes will help!

I can use the workaround (the second set of code) since it seems to be working but I'd like to get it clean and correct if at all possible...

For multi-word relationships, the function should be in camelCase (in fact, all class methods should). When accessing a model's attributes, it is still allowed to access the relationship name in snake case (in your example, 'employee_class', but note that this bypasses all eager loading and you should access the relationship in exactly the same case as the relationship method's name.

In your example, if you rename the employee_class(es) functions to employeeClass(es), everything should work.

// gets all employees and their class(es). the argument(s) for with()
// MUST match the names of the methods exactly.
Employee:with('employeeClass')->get();

// you MUST access eager loaded data in the same case as in with().
// if you access via snake case, eager loading is bypassed.
$employee->employeeClass;

// this also works but should generally be avoided.
Employee::find(1)->employeeClass()->first();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM