0
votes

I have a laravel model

class Project extends Eloquent {

    public static $timestamps = true;

    public $includes = array('members','members.memberdata');

    public function tasks() {

        return $this->has_many('Usertask','project_id');
    }

    public function members() {

        return $this->has_many('Projectmember','project_id');
    }
}

and a related models

class Projectmember extends Eloquent {

    public static $table = "project_members";
    public static $timestamps = true;

    public function project() {

        return $this->belongs_to('Project');
    }

    public function memberdata() {

        return $this->has_one('Usermetadata','user_id');
    }
}

class Usermetadata extends Eloquent {

    public static $table = "users_metadata";

    public function user() {

        return $this->belongs_to('User');
    }

    public function member() {

        return $this->belongs_to('Projectmember','user_id');
    }
}

When i attempt to retrieve a single project model like so

 $project = Project::find($id);

 return Response::eloquent($project);

my json output looks like this

{"id":1,"user_id":1,"name":"UberWork","description":"Web based project management \/ task management app","target_date":"2013-11-15 00:00:00","budget":null,"status":0,"created_at":"2013-04-16 20:13:59","updated_at":"2013-04-16 20:13:59","members":[{"id":1,"project_id":1,"user_id":1,"created_at":"2013-04-16 20:13:59","updated_at":"2013-04-16 20:13:59","memberdata":{"user_id":1,"first_name":"Tamarakuro","last_name":"Foh","photo":"","company_name":null,"phone":null,"package":"free","subscription_start":"0000-00-00 00:00:00","subscription_end":"0000-00-00 00:00:00","api_key":"12b14a7d3ca48c53bb5b1a88fa3eca3b"}},{"id":3,"project_id":1,"user_id":3,"created_at":"2013-04-16 20:13:59","updated_at":"2013-04-16 20:13:59","memberdata":{"user_id":3,"first_name":"Ebere","last_name":"Uche","photo":"","company_name":"Chronotech Labs","phone":null,"package":"free","subscription_start":"0000-00-00 00:00:00","subscription_end":"0000-00-00 00:00:00","api_key":"ab446bd9ffbb898e818a892c7401e0f6"}},{"id":4,"project_id":1,"user_id":2,"created_at":"2013-04-17 08:13:00","updated_at":"2013-04-17 08:13:00","memberdata":null}]}

My database look like this;

Users

  • id
  • email
  • password
  • ip_address
  • active
  • ...

users_metadata

  • id
  • user_id
  • first_name
  • last_name
  • profile_photo
  • ...

Projects

  • id
  • user_id
  • name
  • description
  • status
  • ...

project_members

  • id
  • project_id
  • user_id

My question is why is the last member of the project having its memberdata as "null", while the others are not null. Am i doing something wrong?

1
Are you certain that there is a matching record for your last member in the memberdata table? Your last member's id and user_id do not match, I don't know if this is significant, but the relationship will be matching id to the other table's user_id?Phill Sparks
Yes there is a matching record on the users_metadata tableMrFoh
Can you explain a bit more about your database design? What does user_id refer to everywhere?Phill Sparks
I have edited my question to include the database designMrFoh
The problem is because you want project_members.user_id = users_metadata.user_id, but relationships always use the id of one table and the fk (user_id) on the other table. This works for most of your data because the project_members.id and project_members.user_id are the same; it breaks when they're not (your last project member).Phill Sparks

1 Answers

0
votes

Relationships in Eloquent always link a primary key (pk) with a foreign key (fk). However, you're trying to base a relationship on two foreign keys, skipping out a relationship. The only Eloquent solution is to include the extra relationship step. Here are some models (I've ommited the relationships we don't need for this example)...

class Project extends Eloquent {

    public static $timestamps = true;

    public $includes = array('members','members.user', 'members.user.metadata');

    public function members()
    {
        return $this->has_many('Projectmember','project_id');
    }
}

class Projectmember extends Eloquent {

    public static $table = "project_members";
    public static $timestamps = true;

    public function user()
    {
        return $this->belongs_to('User');
    }
}

class User extends Eloquent {

    public static $timestamps = true;

    public $hidden = array('password', 'ip_address');

    public function metadata()
    {
        return $this->has_one('Usermetadata');
    }

}

class Usermetadata extends Eloquent {

    public static $table = "users_metadata";

    public function user() {

        return $this->belongs_to('User');
    }

}

I can see why you'd want to skip the relationship, but sadly it's not possible with relationships.