Eloquent makes managing and working with these relationships smooth and supports several different types of relationships:
- One To One
- One To Many
- Many To Many
- Has Many Through
- Polymorphic Relations
- Many To Many Polymorphic Relation
If you want to learn more about Laravel, check out the following link.
Laravel Eloquent Relationships
Eloquent relationships in Laravel are defined as the methods on your Eloquent model classes. It is like Eloquent models themselves; relationships also serve as an essential query builder, representing the relationships as methods provide powerful method chaining and querying capabilities.
Step 1: Configure Laravel Project
Install by the following command.
composer create-project laravel/laravel --prefer-dist Relationships
Set up the MySQL database.
Now, edit the .env file.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=relationship DB_USERNAME=root DB_PASSWORD=mysql
Now, we need to make Three tables to build the relationships between them.
- Orders table
- Items table
- Invoice table
php artisan make:migration create_items_table php artisan make:migration create_orders_table php artisan make:migration create_invoice_table
Define the Schema of these tables.
<?php // create_items_table use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateItemsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('items', function (Blueprint $table) { $table->increments('id'); $table->string('item_name'); $table->integer('price'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('items'); } }
<?php // create_orders_table use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateOrdersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('orders', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); $table->integer('item_id'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('orders'); } }
<?php // create_invoice_table use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateInvoiceTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('invoice', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); $table->integer('order_id'); $table->integer('paid_amount'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('invoice'); } }
Next, type the following command.
php artisan migrate
It will create all five tables in the database.
Step 2: Fill the dummy data into the database.
Type the following command to generate the seed files.
php artisan make:seeder UsersTableSeeder php artisan make:seeder ItemsTableSeeder php artisan make:seeder OrdersTableSeeder php artisan make:seeder InvoiceTableSeeder
Feed these tables with the values.
<?php use Illuminate\Database\Seeder; class UsersTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('users')->insert([ 'name' => str_random(10), 'email' => str_random(10).'@gmail.com', 'password' => bcrypt('secret'), ]); DB::table('users')->insert([ 'name' => str_random(10), 'email' => str_random(10).'@gmail.com', 'password' => bcrypt('secret'), ]); DB::table('users')->insert([ 'name' => str_random(10), 'email' => str_random(10).'@gmail.com', 'password' => bcrypt('secret'), ]); DB::table('users')->insert([ 'name' => str_random(10), 'email' => str_random(10).'@gmail.com', 'password' => bcrypt('secret'), ]); DB::table('users')->insert([ 'name' => str_random(10), 'email' => str_random(10).'@gmail.com', 'password' => bcrypt('secret'), ]); } }
<?php use Illuminate\Database\Seeder; class ItemsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('items')->insert([ 'item_name' => 'mobile', 'price' => 1000 ]); DB::table('items')->insert([ 'item_name' => 'laptop', 'price' => 2000 ]); DB::table('items')->insert([ 'item_name' => 'camera', 'price' => 500 ]); DB::table('items')->insert([ 'item_name' => 'ipod', 'price' => 200 ]); DB::table('items')->insert([ 'item_name' => 'tabs', 'price' => 800 ]); } }
<?php use Illuminate\Database\Seeder; class InvoiceTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('invoice')->insert([ 'user_id' => 1, 'order_id' => 1, 'paid_amount' => 1000 ]); DB::table('invoice')->insert([ 'user_id' => 3, 'order_id' => 2, 'paid_amount' => 4000 ]); DB::table('invoice')->insert([ 'user_id' => 4, 'order_id' => 4, 'paid_amount' => 1000 ]); DB::table('invoice')->insert([ 'user_id' => 5, 'order_id' => 5, 'paid_amount' => 1000 ]); DB::table('invoice')->insert([ 'user_id' => 2, 'order_id' => 3, 'paid_amount' => 1000 ]); } }
<?php use Illuminate\Database\Seeder; class OrdersTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('orders')->insert([ 'user_id' => 1, 'item_id' => 1 ]); DB::table('orders')->insert([ 'user_id' => 1, 'item_id' => 5 ]); DB::table('orders')->insert([ 'user_id' => 2, 'item_id' => 2 ]); DB::table('orders')->insert([ 'user_id' => 4, 'item_id' => 3 ]); DB::table('orders')->insert([ 'user_id' => 5, 'item_id' => 1 ]); } }
Now, finally, call all these classes in the DatabaseSeeder.php file.
<?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { $this->call(UsersTableSeeder::class); $this->call(OrdersTableSeeder::class); $this->call(ItemsTableSeeder::class); $this->call(InvoiceTableSeeder::class); } }
So, it fills the values described in the query.
Step 3: Make models for all these three new tables.
Type the following command.
php artisan make:model Item php artisan make:model Order php artisan make:model Invoice
One To Many Relationships
A “one-to-many” relationship is generally used to define relationships where a single or one model owns any other model.
In our example, the User can have multiple Orders.
So, in the User model, we can write the following functions.
<?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; public function orders(){ return $this->hasMany(Order::class); } }
Now, go to the terminal and type the following command.
php artisan tinker
Type the following code in it.
$orders = App\User::find(1)->orders;
So, it will display the orders whose user_id is 1
Illuminate\Database\Eloquent\Collection {#734 all: [ App\Order {#738 id: 1, user_id: 1, item_id: 1, created_at: null, updated_at: null, }, App\Order {#741 id: 2, user_id: 1, item_id: 5, created_at: null, updated_at: null, }, ], }
If your table’s local Primary Key is different, id and Foreign Key are different from user_id. Then, you need to specify further arguments like this.
<?php public function orders() { return $this->hasMany('App\Order', 'foreign_key', 'local_key'); }
One To Many (Inverse)
Now that we can access the user that has placed the order.
So, in the Order.php model, put the following function in it.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Order extends Model { /** * Get the user that owns an order. */ public function user() { return $this->belongsTo(User::class); } }
Go to the tinker and type the following code in it.
$user = App\Order::find(2)->user;
It will list the output like the following.
App\User {#735 id: 1, name: "kbXBRnz9no", email: "9WQ1CwXjZY@gmail.com", created_at: null, updated_at: null, }
So, we can find the User that had placed the Order.
Finally, our First article on One to Many Relationships is over.
Another relationship tutorial will publish in the next article.
If you have any questions regarding Laravel Eloquent Relationships, ask in a comment below.
Hi, The first tinker consult works to me, but the second one gives me:
=> null
any help with that?
thanks
Hi Dan,
Its true that the first time tinker will work in this example and give you the required 2 entries. However, if you try the second example “`$user = App\Order::find(2)->user;“` it will return null. The reason is that at this stage tinker doesn’t know the second method (belongsTo) that you just created. The solution if for you to exit tinker and rerun it. This will work. It’s like a refresh… Lol
Hi, first i run the command tinker, i found the error message like this :
PHP Notice: Trying to get property ‘orders’ of non-object in Psy Shell code on line 1
I ran into the same problem. I think that’s because the seeding wasn’t performed yet (it’s is not described here). After some searching I found the following article: https://laravel.com/docs/5.7/seeding
composer dump-autoload
php artisan db:seed
This seeded the tables, so now I didn’t get that messages.
$orders = AppUser::find(1)->orders;
=> IlluminateDatabaseEloquentCollection {#2928
all: [],
$orders = App\User::find(1)->orders;
=> Illuminate\Database\Eloquent\Collection {#2928
all: [],
no data will be display
i dont understand where or how you set up the relations? i see no foreign key or Auth::user references thx
Thanks buddy Very Useful for me