Search code examples
phplaravel-5foreign-key-relationshiplaravel-artisan

How to manage relationships(fk) of models?


I know how to create a model - php artisan make:model nameofmodel, i know that in the migration of the model i have to declare what columns will the table have:

class CreateNameofmodelTable extends Migration {

     /**
     * Run the migrations.
     *
     * @return void
     */
     public function up()
     {
        Schema::create('nameofmodels', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name')->unique();
            $table->string('description');
            $table->timestamps();
        });
    }

   /**
   * Reverse the migrations.
   *
   * @return void
   */
   public function down()
   {
       Schema::drop('nameofmodels');
   }
}

But if i want to relate two models using a FK, what are the configurations i have to set in the migration file or in the model file?


Solution

  • Suppose you have another model User with table name users. you can have relationship defined between addresses and users as following,

    public function up()
        {
            Schema::create('addresses', function(Blueprint $table)
            {
                $table->increments('id');
                $table->string('add1');
                $table->string('add2');
                $table->string('city');
                $table->string('contact_no');
                $table->enum('is_primary',['yes','no'])->default('no');
                $table->integer('user_id')->unsigned();
                $table->timestamps();
    
                $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            });
        }
    

    In User model class,

    class User extends Model {
       /**
       * The table associated with the model.
       *
       * @var string
       */
        protected $table = 'users';
    
        public function addresses()
        {
            return $this->hasMany('App\Address');
        }
    
    }
    

    in Address class

    class Address extends Model {
        /**
        * The table associated with the model.
        *
        * @var string
        */
       protected $table = 'addresses';
    
        public function user()
        {
            return $this->belongsTo('App\User');
        }
    
    }
    

    More detailed information about creating table can be found on Official Schema Docs on Laravel. And More information about Relation ship here

    UPDATE

    According to this question, you will have to create referenced table first before referencing table. In our case, users must exists before you run migration to create addresses table.

    Simple Use-case

    suppose, in controller you want to find out how many addresses particular users have, you can do like following,

    $addressCount = User::find($userId)->addresses->count();
    

    Please note User::find($userId)->addresses returns collection of related models while User::find($userId)->addresses() returns object of type HasMany

    you can also traverse collection as below,

    foreach(User::find($userId)->addresses as $address)
    {
        echo '<pre>';
        print_r($address);
    }
    

    On the other side, you can get user associated with particular address as below,

    $user = Address:find($addressId)->user; //returns object of type `User`
    echo $user->first_name;
    

    following will not work

    $user = Address:find($addressId)->user(); //returns object of type `belongsTo`
    echo $user->first_name;
    

    Note, above Address:find($addressId)->user will not return collection but a single object of class User. This is because a belongsTo relationship.

    I hope I made things clear for you. But nothing as good as official docs.

    Laracast videos are even better to get on with Laravel.