Eloquent relationship cheat sheet

One to one relationship

Business definition: User has Shopping cart.

Developer definition: User has one Shopping cart. Shopping cart belongs to one user.

Diagram One-to-one relationship diagram Relationship explanation: Shopping cart table should store user ID.

Models: So we need two models: User and ShoppingCart. Those models will be populated with next code:

class User{
  /*
   * This function defines a relation with Shopping Cart and tells that ID is stored in 
   * ShoppingCart model
   */
  public function shoppingCart()
  {
    return $this->hasOne(ShoppingCart::class);
  }
}
class ShoppingCart{
  /*
   * This function defines a relation with the User and tells that ID is stored in 
   * this model
   */
  public function user()
  {
    return $this->belongsTo(User::class);
  }
}

Database migration:

Schema::create('users', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('shopping_carts', function (Blueprint $table) {
  $table->increments('id');
  # Some more columns which you will need
  $table->integer('user_id')->unsigned()->index()->nullable();  
  $table->foreign('user_id')->references('id')->on('users');  
});

Store records: To create relationship between the User and ShoppingCart.

$user->shoppingCart()->save($shoppingCart);

To create a relationship between the ShoppingCart and User.

$shoppingCart->user()->associate($user)->save();

One to many relationship

Business definition: User must be able to add multiple items to shopping cart.

Developer definition: Shopping cart has multiple items.

Diagram One-to-many relationship diagram

Relationship explanation: Item table should store shopping cart ID.

Models: So we need two models: ShoppingCart and Item. Those models will be populated with the next code:

class ShoppingCart{
  /*
   * This function defines a relation with Item and tells that ID is stored in 
   * Item model
   */
  public function items()
  {
    return $this->hasMany(Item::class);
  }
}
class Item{
  /*
   * This function defines a relation with Shopping Cart and tells that ID is stored in 
   * this model
   */
  public function shoppingCart()
  {
    return $this->belongsTo(ShoppingCart::class);
  }
}

Database migration:

Schema::create('shopping_carts', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('items', function (Blueprint $table) {
  $table->increments('id');
  # Some more columns which you will need
  $table->integer('user_id')->unsigned()->index()->nullable();  
  $table->foreign('user_id')->references('id')->on('users');  
});

Store records: To create relationship between the shopping cart and items.

// Create multiple relations between Thief and Car.
$shoppingCart->items()->saveMany([$item1,$item2]);

// Or use the save() function for single model.
$shoppingCart-> items()->save($item1);

To create a relationship between the item and shopping cart.

$item->shoppingCart()->associate($shoppingCart)->save();

Polymorphic One to Many Relationship

Business definition: User can leave multiple messages. Support can leave multiple messages.

Developer definition: User has many messages. Support has many messages. Message can be owned by user or support.

Diagram Polymorphic one-to-many relationship diagram

Relationship explanation: Message table should store ID and type of message sender.

Models: So we need three models: User, Support and Message. Those models will be populated with next code:

class User{
  /*
   * This function defines a relation with Message and tells that ID and type is stored in 
   * Message model
   */
  public function messages()
  {
    return $this-> morphMany(Message::class, 'sender');
  }
}
class Support{
  /*
   * This function defines a relation with the Message and tells that ID is stored in 
   * Message model
   */
  public function messages()
  {
    return $this-> morphMany(Message::class, 'sender');
  }
}
class Message{
  /*
   * This function defines a relation and tells that ID and type is stored in Message model
   */
  public function sender()
  {
    return $this->morphTo();
  }
}

Database migration:

Schema::create('users', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('supports', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('messages', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
  $table->integer('sender_id')->unsigned()->index()->nullable();  
  $table->string('sender_type')->nullable();     
  // or use $table->morphs('sender'); instead of "sender_id" and "sender_type"
});

Store records: Create relation between sender (User/Support) and the Message.

// Create multiple relations.
$user->messages()->saveMany([$message1,$message2]);
$support->messages()->saveMany([$message1,$message2]);

// Or use the save() function for single model.
$user->messages()->save($message);
$support->messages()->save($message);

To create a relationship between Message and sender.

$message->sender()->associate($user)->save();
$message-> sender()->associate($support)->save();

Many to Many Relationship

Business definition: Item can have multiple tags.

Developer definition: Item has many tags. Tags has many items.

Diagram Many to many relationship diagram

Relationship explanation: As a single tag can belong to multiple items and the single item can have multiple tags, we need third table (which is called Pivot table) which will list the relation between those two models.

Models: So we need two models: Tag and Item. Those models will be populated with next code:

class Tag{
  public function items()
  {
    return $this->belongsToMany(Items::class);
  }
}
class Item{
  public function tags()
  {
    return $this->belongsToMany(Tag::class);
  }
}

Database migration:

Schema::create('items', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('tags', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('item_tag', function (Blueprint $table) {
  $table->id();
  $table->integer('item_id')->unsigned()->index();  
  $table->foreign('item_id')->references('id')->on('items')->onDelete('cascade');
  $table->integer('tag_id')->unsigned()->index();  
  $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');  
});

Store records: Create relation between Item and Tag

$item->tags()->attach([$tag1->id,$tag2->id]);

// Or use the sync() function to prevent duplicated relations.
$item->tags()->sync([$tag1->id,$tag2->id]);

Or create relation between Tag and Item

$tag->items()->attach([$item1->id,$item2->id]);

// Or use the sync() function to prevent duplicated relations.
$tag-> items()->sync([$item1->id,$item2->id]);

Polymorphic Many to Many Relationship

Business definition: Products and posts have multiple Tags

Developer definition: Product has many Tags. Post has many tags. Tag can be used by many tagables (Product and Post)

Diagram Polymorphic many-to-many relationship

Relationship explanation: As a single tag can belong to multiple posts or products, and the single product or post can have multiple tags, we need a third table (which is called Pivot table) which will list the relation between those models.

Models: So we need three models: Product, Post and Tag. Those models will be populated with next code:

class Product{
  public function tags()
  {
    return $this->morphToMany(Tag::class, 'tagable');
  }
}
class Post{
  public function tags()
  {
    return $this->morphToMany(Tag::class, 'tagable');
  }
}
class Tag{
  public function products()
  {
    return $this->morphedByMany(Product::class, 'tagable');
  }

  public function posts()  
  {
    return $this->morphedByMany(Post::class, 'tagable');  
  }
}

Database migration:

Schema::create('products', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('posts', function (Blueprint $table) {
  $table->id();
  # Some more columns which you will need
});
Schema::create('tagables', function (Blueprint $table) {
  $table->id();
  $table->integer('tagable_id')->unsigned()->index();  
  $table->string('tagable_type');  
  // or use $table->morphs(‘tagable’); instead of "tagable_id" and "tagable_type"

  $table->integer('tag_id')->unsigned()->index();  
  $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');  
});

Store records: Create relation between tagable (Product or Post) and Tag.

$product->tags()->saveMany([$tag1, $tag2]);
$post->tags()->saveMany([$tag1, $tag2]);

// Or use the save() function for single model.
$product->tags()->save($tag1);
$post->tags()->save($tag1);

Or create relation between Tag and tagable.

$tag->products()->attach([$product1->id,$product2->id]);
$tag->posts()->attach([$post1->id,$post2->id]);

// Or use the sync() function to prevent duplicated relations.
$tag->products()->sync([$product1->id,$product2->id]);
$tag->posts()->sync([$post1->id,$post2->id]);