Conversation şeklinde bir model daha düşünün. Bir kullanıcı diğerine mesaj attığında aslında bir konuşma başlatmış oluyor. Bu modeli ilk mesajı, yani konuşmayı tutmak için kullanın. Message modeline de conversation_id şeklinde bir alan ekleyin Conversation modeli ile arasında belongsTo/hasMany ilişkisi kurun. Bir kullanıcı diğer bir kullanıcıya bir mesaj attığında önce Conversation modeli oluşacak (id, sender_id, receiver_id, message, created_at), sonra aynı mesajı Message modeline de ekleyeceksiniz (id, conversation_id, sender_id, receiver_id, message, created_at). Böylece Conversation modelini sender_id'ye göre filtrelediğinizde gönderenin giden kutusu; receiver_id'ye göre filtrelediğinizde alıcının gelen kutusu oluşmuş olacak. Yazışmaya ulaşmak istediğinizde ise o Conversation modeli altındaki Message modellerini getireceksiniz.
Her iki modele de sender_deleted_at ve receiver_deleted_at şeklinde iki tane timestamp ekleyebilirsiniz. Gönderen mesajı sildiğinde sender_deleted_at alanına silindiği tarihi yazacak ama kaydı silmeyecek. Aynı şeyi alıcı için de yapacaksınız. Alıcı silerse receiver_deleted_at alanına tarih atacak. Bir mesajda her iki alana da tarih işlendiğinde iki taraf da silmiş gibi olaağı için mesajı isterseniz gerçekten silebilirsiniz. Aynı şekilde Conversation silinmeye çalışıldığında aynı işlemi yapacaksınız fakat bu sefer örneğin Conversation modelini silen gönderici ise bu modelin altındaki tüm Message modellerinin sender_deleted_at alanını aynı tarihle dolduracaksınız. Aynı Conversation modelinin iki deleted_at alanı da dolduğu anda isterseniz o Conversation ve altındaki Message modellerinin hepsini silebilirsiniz. İki taraf da silmiş oluyor. Nasıl bir strateji izleyeceğiniz size kalmış. Kayıtları da kullanıcılara gösterirken elbette bu deleted_at alanlarının NULL olduğu kayıtları çekeceksiniz. NULL olmayanları silinmiş sayıyoruz (softdelete olayı).
Elbette teorik konuşuyorum, karşınıza farklı sorunlar çıkabilir ama bunu bir başlangıç kabul edebilirsiniz.