Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eloquent relation setup, two foreign keys to same table laravel 5.2

Tags:

php

laravel-5

I have been in big problem, I am maintaining eloquent relationship setup in my project where i am having the following relationship:

  1. User info related to login stored in users table.
  2. User profile related information stored in profiles information.
  3. Users address stored in address table
  4. configurations related information stored in configurations like city, state, country

Efforts

Here is the migration and model and their relationship:

Users migration table:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->rememberToken();
            $table->timestamps();
        });
    }

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

User Model:

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'email', 'password',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function profile()
    {
        return $this->hasOne('App\Profile','user_id');
    }
}

Profile migration table:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProfilesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('profiles', function (Blueprint $table) {
            $table->increments('profile_id');
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->string('lastname')->nullable();
            $table->string('firstname')->nullable();
            $table->string('gender')->nullable();
            $table->string('phonenumber', 20)->nullable();
            $table->timestamps();
        });
    }

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

Profile Model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
     protected $fillable = [
        'firstname', 'lastname',
    ];

    public function user(){
        return $this->belongsTo('App\User');
    }
    public function address()
    {
        return $this->hasOne('App\Address','profile_id');
    }
}

Configuration migration table:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateConfigurationsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('configurations', function (Blueprint $table) {
            $table->increments('config_id');
            $table->string('configuration_name');
            $table->string('configuration_type');
            $table->string('parent_id');
            $table->timestamps();
        });
    }

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

Configuration Model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Configuration extends Model
{
    public function children() {
        return $this->hasMany('App\Configuration','parent_id');
    }
    public function parent() {
        return $this->belongsTo('App\Configuration','parent_id');
    }

    public function city() {
        return $this->hasOne('App\Address', 'city');
    }

    public function state() {
      return $this->hasOne('App\Address', 'state');
    }

    public function country() {
        return $this->hasOne('App\Address', 'country');
    }
}

Address Migration Table:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateAddressesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('addresses', function (Blueprint $table) {
            $table->increments('address_id');
            $table->integer('profile_id')->unsigned();
            $table->foreign('profile_id')->references('profile_id')->on('profiles')->onDelete('cascade');
            $table->string('address')->nullable();
            $table->integer('city')->unsigned();
            $table->foreign('city')->references('config_id')->on('configurations')->onDelete('cascade');
            $table->string('pincode')->nullable();
            $table->integer('state')->unsigned();
            $table->foreign('state')->references('config_id')->on('configurations')->onDelete('cascade');
            $table->integer('country')->unsigned();
            $table->foreign('country')->references('config_id')->on('configurations')->onDelete('cascade');
            $table->timestamps();
        });
    }

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

Address Model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Address extends Model
{
    public function profile(){
        return $this->belongsTo('App\Profile');
    }

    public function city() {
        return $this->belongsTo('App\Configuration');
    }

    public function state() {
      return $this->belongsTo('App\Configuration');
    }

    public function country() {
        return $this->belongsTo('App\Configuration');
    }
}

I have used Eloquent relation setup, two foreign keys to same table to make my project relationship. But unfortunately above code does not generating desire output. Take a look:

If I use the command Auth::user()->profile->firstname it will print user first name. So if i use Auth::user()->profile->address->city it should print city name stored in configuration table, but instead print name it print the id.

Please suggest me the solution.

Thanks,

like image 388
Mandy Avatar asked Mar 02 '16 05:03

Mandy


1 Answers

Well, I found the solution for my own question. Thanks for everyone who think this question have some worth.

Well, we don't nedd to change user or profile, we just need to make some changes in configuration and address model only.

change

class Address extends Model
{
    public function profile(){
        return $this->belongsTo('App\Profile');
    }

    public function city() {
        return $this->belongsTo('App\Configuration');
    }

    public function state() {
      return $this->belongsTo('App\Configuration');
    }

    public function country() {
        return $this->belongsTo('App\Configuration');
    }
}

to

class Address extends Model
{
    public function profile(){
        return $this->belongsTo('App\Profile');
    }

    public function cityConfiguration() {
        return $this->belongsTo('App\Configuration', 'city');
    }

    public function stateConfiguration() {
      return $this->belongsTo('App\Configuration', 'state');
    }

    public function countryConfiguration() {
        return $this->belongsTo('App\Configuration', 'country');
    }
}

and change

class Configuration extends Model
{
    public function children() {
        return $this->hasMany('App\Configuration','parent_id');
    }
    public function parent() {
        return $this->belongsTo('App\Configuration','parent_id');
    }

    public function city() {
        return $this->hasOne('App\Address', 'city');
    }

    public function state() {
      return $this->hasOne('App\Address', 'state');
    }

    public function country() {
        return $this->hasOne('App\Address', 'country');
    }
}

To

class Configuration extends Model
{
    public function children() {
        return $this->hasMany('App\Configuration','parent_id');
    }
    public function parent() {
        return $this->belongsTo('App\Configuration','parent_id');
    }

    public function city() {
        return $this->hasOne('App\Address', 'city');
    }

    public function state() {
      return $this->hasOne('App\Address', 'state');
    }

    public function country() {
        return $this->hasOne('App\Address', 'country');
    }
}

and that's it. Everything is working fine.

like image 117
Mandy Avatar answered Sep 30 '22 19:09

Mandy