Jacob Hyde
Jacob Hyde

Reputation: 1000

Laravel Morph Many from two columns

I need to find a way to modify the morphMany relationship to morph two different columns. Here is the table create syntax that is being morphed:

CREATE TABLE `user_friendships` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `sender_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `sender_id` bigint(20) unsigned NOT NULL,
  `recipient_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `recipient_id` bigint(20) unsigned NOT NULL,
  `status` tinyint(4) NOT NULL DEFAULT '0',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_friendships_sender_type_sender_id_index` (`sender_type`,`sender_id`),
  KEY `user_friendships_recipient_type_recipient_id_index` (`recipient_type`,`recipient_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12332 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Sender and recipient can both be a user. So I want to morph based on whatever column of the two contains the user_id.

This only looks at if the sender is the user, but not the recipient.

return $this->morphMany(Friendship::class, 'sender');

The output of the query from that is:

select * from `user_friendships` where `user_friendships`.`sender_id` = 5971 and `user_friendships`.`sender_id` is not null and `user_friendships`.`sender_type` = "App\\\User"

What we actually want is:

select * from `user_friendships` where (`user_friendships`.`sender_id` = 5971 and `user_friendships`.`sender_id` is not null and `user_friendships`.`sender_type` = "App\\\User") OR (`user_friendships`.`recipient_id` = 5971 and `user_friendships`.`recipient_id` is not null and `user_friendships`.`recipient_type` = "App\\\User")

How do I accomplish this?

Upvotes: 1

Views: 500

Answers (1)

Jacob Hyde
Jacob Hyde

Reputation: 1000

https://github.com/staudenmeir/laravel-merged-relations

This composer package was able to solve it.

Upvotes: 1

Related Questions