Cornelius Wilson
Cornelius Wilson

Reputation: 2914

How to hide deleted message from recipient with inbox

I have a custom inbox messaging system and I would like to fix the delete function of messages. At the moment when User A deletes a message, it will not permanently be deleted from database until User B also deletes the message. So the message will remain in the users Inbox/Delete folder until both the sender and recipient has erased the message.

How I would like it to function is that if one user deletes the message from their inbox or clicks the delete button again for messages inside their delete folder...the message should remain hidden as if it were deleted. Thus making that message non-viewable to the User who selected to delete it. Then of course with how I have it setup already, the message will be permanently deleted from database if both users have selected to delete it.

When message is soft deleted (hidden from one user until it is permanently deleted from database), it should not be viewable by that user. If they're browsing their messages and are using the next/previous links...messages that they've deleted should not appear while clicking next/previous.

Any help would be appreciated!

messages controller:

  def index
    if params[:mailbox] == "sent"
      @messages = @user.sent_messages
    elsif params[:mailbox] == "inbox"
      @messages = @user.received_messages
    #elsif params[:mailbox] == "archieved"
     # @messages = @user.archived_messages
    end
    if params[:mailbox] == "unread"
    @messages = @user.unread_messages
  end
  end

  def new
    @message = Message.new
    if params[:reply_to]
      @reply_to = User.find_by_user_id(params[:reply_to])
      unless @reply_to.nil?
        @message.recipient_id = @reply_to.user_id
      end
    end
  end

  def create
    @message = Message.new(params[:message])
    @message.sender_id = @user.id
    if @message.save
      flash[:notice] = "Message has been sent"
      redirect_to user_messages_path(current_user, :mailbox=>:inbox)
    else
      render :action => :new
    end
  end

  def show
     @message = Message.find(params[:id])
     @message.readingmessage if @message.recipient == current_user
   end

   def destroy
     @message = Message.find(params[:id])
     @message.destroy
     flash[:notice] = "Successfully deleted message."
     redirect_to user_messages_path(@user, @messages)
   end

  def delete_multiple
      if params[:delete]
        params[:delete].each { |id|
          @message = Message.find(id)
          @message.mark_message_deleted(@message.id,@user.id) unless @message.nil?
        }
        flash[:notice] = "Messages deleted"
      end
      redirect_to user_messages_path(@user, @messages)
  end

  private
    def set_user
      @user = current_user
    end
end

messages model:

belongs_to :sender,
:class_name => 'User',
:foreign_key => 'sender_id'
belongs_to :recipient,
:class_name => 'User',
:foreign_key => 'recipient_id'

# marks a message as deleted by either the sender or the recipient, which ever the user that was passed is.
# When both sender and recipient marks it deleted, it is destroyed.
def mark_message_deleted(id,user_id)
     self.sender_deleted = true if self.sender_id == user_id
     self.recipient_deleted = true if self.recipient_id == user_id
     (self.sender_deleted && self.recipient_deleted) ? self.destroy : self.save!
 end
# Read message and if it is read by recipient then mark it is read
def readingmessage
  self.read_at ||= Time.now
  save
end

# Based on if a message has been read by it's recipient returns true or false.
def read?
    self.read_at.nil? ? false : true
end

def self.received_by(user)
   where(:recipient_id => user.id)
 end

 def self.not_recipient_deleted
   where("recipient_deleted = ?", false)
 end

 def self.sent_by(user)
    Message.where(:sender_id => user.id)
  end

  def previous(same_recipient = true)
    collection = Message.where('id <> ? AND created_at > ?', self.id, self.created_at).order('created_at ASC')
    collection.where(recipient_id: self.recipient_id) if same_recipient
    collection.first
  end

  def next(same_recipient = true)
    collection = Message.where('id <> ? AND created_at < ?', self.id, self.created_at).order('created_at DESC')
    collection.where(recipient_id: self.recipient_id) if same_recipient
    collection.first
  end
end

inbox view:

<%= form_tag delete_multiple_user_messages_path, :method=>:post do %>
    <table  class="table table-bordered">
            <tr>
            <th>Delete</th>
            <th>Subject</th>
            <th>Date</th>
            <th>From</th>
        </tr>
            <% for message in @messages %>
                <tr>
                    <td><%= check_box_tag "delete[]", message.id %></td><p>

                    <td>
                        <% if message.read? %>
                          <%= link_to h(message.subject), user_message_path(@user, message) %>
                        <% else %>
                          <%= link_to "#{h(message.subject)} (unread)", user_message_path(@user, message) %>
                        <% end %>
                    </td>

                    <td><%=h message.created_at.to_s(:long) %></td>
            <td><%= "#{message.sender}" %></td>
                </tr>
    <% end %>
    </table>
<%= submit_tag "Delete selected" %>

Upvotes: 1

Views: 336

Answers (2)

johnnyboyy
johnnyboyy

Reputation: 76

I see this method in your model, but I don't see you calling it anywhere:

def self.not_recipient_deleted
  where("recipient_deleted = ?", false)
end

I believe if you change this for loop in the inbox view

<% for message in @messages %>

to

<% for message in @messages.not_recipient_deleted %>

it will return only the messages that the recipient hasn't deleted. That should keep the deleted messages from being displayed in the inbox.

Upvotes: 1

Nitin Jain
Nitin Jain

Reputation: 3083

you can use this in controller for index action @messages = @user.received_messages.where(recipient_deleted: false)

so it will load only messages that are not deleted by the recipient

Upvotes: 0

Related Questions