Laravel belongsTo not working

69,942

Solution 1

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 ;)

Solution 2

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');
    }
}

Solution 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');
   }

Solution 4

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

Solution 5

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

Share:
69,942
Yashari
Author by

Yashari

Updated on May 22, 2020

Comments

  • Yashari
    Yashari almost 4 years

    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
    
  • Joseph
    Joseph almost 10 years
    @HooK Can you provide some more of your class implementation?
  • Yashari
    Yashari almost 10 years
    the "User" class is the laravel default class and it uses the default implements. (implements UserInterface, RemindableInterface)
  • Joseph
    Joseph almost 10 years
    @HooK please see my edit. I thought you had specified the table in the MedicineTypes class.
  • Joseph
    Joseph almost 10 years
    @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.
  • Yashari
    Yashari almost 10 years
    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)
  • Joseph
    Joseph almost 10 years
    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.
  • Yashari
    Yashari almost 10 years
    Thanks a lot Joseph! :)
  • Joseph
    Joseph almost 10 years
    Nice. Thanks Melvin, this was bugging me as well :)
  • bhu Boue vidya
    bhu Boue vidya over 9 years
    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?
  • Adan Archila
    Adan Archila over 9 years
    Melvin, you saved me lots of headaches! Thanks a lot.
  • bjjn
    bjjn over 9 years
    Oops.. only wasted an hour! Never think of it, as always start thinking of the complex scenarios first rather than the basics :( Thank you.
  • briankip
    briankip about 9 years
    @MelvinKoopmans Why must you specify the foreign key, and isn't the foreign key medicine_type_id not id
  • JustAMartin
    JustAMartin over 8 years
    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.
  • Muhammad Dyas Yaskur
    Muhammad Dyas Yaskur almost 4 years
    While this code may solve the question, including an explanation 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
  • Matthew Jonat
    Matthew Jonat about 2 years
    Maybe don't show what doesn't work and show what does work lol....this is just confusing...