33

I have 2 models in my app, 'User' & 'MedicineType' (each User belongs to one MedicineType).

I made the one-to-many relation between two model using belongsTo() and hasMany(). hasMany() relation works perfectly but belongTo() doesn't work. Does anyone know where did I make a mistake?

User::find(1)->medicine_type [this returns nothing]

MedicineType::find(1)->users [this returns users]

Here's the code to Models:

class MedicineType extends Eloquent {

    public function users()
    {
        return $this->hasMany('User');
    }
}


class User extends Eloquent {

    public function medicine_type()
    {
        return $this->belongsTo('MedicineType');
    }
}

And here is my database structure:

users:
    id
    name
    medicine_type_id 

medicine_types:
    id
    name
Yashari
  • 491
  • 1
  • 8
  • 14

7 Answers7

67

The reason your relation is not working is not because of the relations specified in the model, but because of the method naming in the User model and not specifying the foreign key.

Instead of:

public function medicine_type()
{
    return $this->belongsTo('MedicineType');
}

Use:

public function medicineType()
{
    return $this->belongsTo('MedicineType', 'id');
}

I hope this works for you ;)

Everything together:

<?php // app/models/MedicineType.php

class MedicineType extends Eloquent {

   // Determines which database table to use
   protected $table = 'medicine_types';

   public function users() 
   {
      return $this->hasMany('User');
   }

}

and:

<?php // app/models/User.php

class User extends Eloquent {

   // Determines which database table to use
   protected $table = 'users';

   public function medicineType() 
   {
      return $this->belongsTo('MedicineType', 'id');
   }

}

Testing if it works:

$user = User::find(1);
return $user->medicineType->name;

This successfully returns the related medicine_type's name.

I hope this helps you further ;)

Melvin Koopmans
  • 2,994
  • 2
  • 25
  • 33
  • 1
    Nice. Thanks Melvin, this was bugging me as well :) – Joseph Jun 28 '14 at 19:35
  • 3
    thank you so much. i hadn't twigged that the method had to be camel case - no underscores allowed! did i miss this in the docs? – bhu Boue vidya Sep 17 '14 at 10:57
  • Melvin, you saved me lots of headaches! Thanks a lot. – Adan Archila Nov 28 '14 at 16:03
  • Oops.. only wasted an hour! Never think of it, as always start thinking of the complex scenarios first rather than the basics :( Thank you. – bjjn Jan 22 '15 at 13:17
  • 1
    @MelvinKoopmans Why must you specify the foreign key, and isn't the foreign key `medicine_type_id` not `id` – briankip Mar 06 '15 at 15:19
  • 10
    I agree with @briankip - shouldn't foreign key be `medicine_type_id` and not `id`? The fact that it works with `id` might be just a coincidence with a few records when ids match, but the generated query might be completely wrong joining on `medicine_types.id=users.id` and not `users.medicine_type_id=medicine_types.id`, as it should. I always look into DebugBar to verify if the generated query is right. – JustAMartin Sep 07 '15 at 10:03
14

Maybe there's an issue with Eloquent finding the foreign key. Try this:

class User extends Eloquent {

    public function medicine_type()
    {
        return $this->belongsTo('MedicineType', 'medicine_type_id');
    }
}

EDIT:

Also, Eloquent tries to find the table "medicinetypes" and not "medecine_types", so you need to specify that as well using the $table variable.

class MedicineType extends Eloquent {
    protected $table = 'medicine_types';

    public function users()
    {
        return $this->hasMany('User');
    }
}
Joseph
  • 5,070
  • 1
  • 25
  • 26
  • @HooK Can you provide some more of your class implementation? – Joseph Jun 28 '14 at 17:44
  • the "User" class is the laravel default class and it uses the default implements. (implements UserInterface, RemindableInterface) – Yashari Jun 28 '14 at 17:50
  • @HooK please see my edit. I thought you had specified the table in the MedicineTypes class. – Joseph Jun 28 '14 at 17:58
  • @HooK well, if you're not getting any errors, then what data do you have in your db that we can check against? when you do find(1), you're just finding the first record in the db. Maybe `User::find(1)->medicine_type` doesn't have a medicine_type in the db. – Joseph Jun 28 '14 at 18:25
  • I double checked my db, everything seems alright... For prove here's the return of "MedicineType::find(1)->users;" [ { id: 1, name: "Yashar", medicine_type_id: 1, } ] (The ID of user is 1) – Yashari Jun 28 '14 at 18:36
  • Hmm....I'll have to look at this later tonight when I get home. I'll try to mockup your setup and see if I can duplicate the issue and get back to you. – Joseph Jun 28 '14 at 18:48
3

I made the stupid mistake of not adding the "return" in the relationship method!

Make sure you return the relationship... Obviously this will not work:

public function medicineType() 
{
    $this->belongsTo('MedicineType', 'id');
}

It works by adding a return keyword:

public function medicineType() 
{
    return $this->belongsTo('MedicineType', 'id');
}
Puspam
  • 2,137
  • 2
  • 12
  • 35
HPage
  • 1,412
  • 20
  • 27
1

I change "medicine_type" to "medicineType" and everythings got OK...

Yashari
  • 491
  • 1
  • 8
  • 14
1

In my case the related models data was deleted & laravel don't get soft deleted data in general query. To get soft deleted data you've to use "withTrashed() or onlyTrashed()".

You can check the documentation here.

https://laravel.com/docs/5.6/scout#soft-deleting

sh6210
  • 4,190
  • 1
  • 37
  • 27
0

The number one voted answer might be the best answer in most cases. However, if you still are having trouble loading the related relationship and no luck..

There is one other thing that may work. Take a look at each of the model's tables and their indexes or foreign keys. In my case I had changed the table name but I never updated the involved index and foreign keys.

Solution.

A:(Feeling Lazy) Just delete the associated index or foreign key..

B:(I am not Lazy) Drop table via laravel migration and re-run artisan migrate with the appropriate foreign keys.

slfan
  • 8,950
  • 115
  • 65
  • 78
0

Model:

class User extends Eloquent {

    public function medicine_type()
    {
        return $this->belongsTo('MedicineType');
    }
}

UserController.php

$users= App\User::all();

foreach ($users as $user) {
    echo $user->medicine_type->name;
}
  • While this code may solve the question, [including an explanation](https://meta.stackoverflow.com/questions/392712/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion – Muhammad Dyas Yaskur May 22 '20 at 00:06