How to hide deleted message from recipient with inbox - ruby-on-rails

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" %>

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.

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

Related

Reference message id when submitting form

When users compose a message, how can I setup so that it references the new message_id created for the conversation_id inside the Messages table?
For example User A sends a new message to User B. Message_id 26 is created and the conversation_id will be 26.
show.html.erb:
<h4>Send Message To User</h4>
<p><%= link_to "Message Me", new_user_message_path(#user), :class => "button" %>
new.html.erb:
<%= f.text_field :conversation_id %>
controller:
def index
#messages = Message.scoped
#message = Message.new
if params[:mailbox] == "sent"
#messages = #user.sent_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
elsif params[:mailbox] == "inbox"
#messages = #user.received_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
#elsif params[:mailbox] == "archived"
# #messages = #user.archived_messages
end
if params[:mailbox] == "unread"
#messages = #user.unread_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
end
if params[:mailbox] == "trash"
#messages = #user.deleted_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
end
end
def new
#message = Message.new
#message.conversation_id = params[:conversation_id]
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
#new_message = Message.new
#message = Message.find(params[:id])
#message.readingmessage if #message.recipient == current_user
end
def reply
#reply_message = Message.new
#message = Message.new
#message.conversation_id = params[:conversation_id]
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
def update
#message = Message.new
if params[:reply_to]
#reply_to = User.find_by_id(params[:reply_to])
unless #reply_to.nil?
#message.recipient_id = #reply_to.id
end
end
end
Model:
class Message < ActiveRecord::Base
attr_accessible :subject, :conversation_id, :body, :parent_id, :sender_id, :recipient_id, :read_at,:sender_deleted,:recipient_deleted
validates_presence_of :subject, :message => "Please enter message title"
has_many :notifications, as: :event
belongs_to :conversation, inverse_of: :messages
belongs_to :user
scope :unread, -> {where('read_at IS NULL')}
scope :not_deleted_by_recipient, where('messages.recipient_deleted IS NULL OR messages.recipient_deleted = ?', false)
scope :not_deleted_by_sender, where('messages.sender_deleted IS NULL OR messages.sender_deleted = ?', false)
belongs_to :sender,
:class_name => 'User',
:foreign_key => 'sender_id'
belongs_to :recipient,
:class_name => 'User',
:foreign_key => 'recipient_id'
after_create :set_converstation_id
def set_conversation_id
update_column :conversation_id, id
end
def reply
new_message.reply_from_user_id = self.id #save the user id of original repost, to keep track of where it originally came from
end
def self.by_date
order("created_at DESC")
end
# 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 = user_id if self.recipient_id == user_id
(self.sender_deleted > 0 && self.recipient_deleted > 0) ? self.destroy : self.save!
(self.sender_deleted != 0 && self.recipient_deleted != 0)
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 next(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 previous(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
private
def send_notification(message)
message.notifications.create(user: message.recipient)
end
If you don't have separate models for conversations and messages, how will you discriminate between the creation of a message and the creation of a conversation?
You should have a Conversation Model that has_many messages and references both users.
Anyways, what you're asking is to have a conversation_id when creating a brand new message (or conversation)?
You can do this in two ways:
1.- Change
#message.conversation_id = params[:conversation_id]
to
#message.conversation_id = #message.id
And in the view use a hidden_field_tag (or the helper that does that) for your conversation_id
2.- Set this id directly on the create method
#message.conversation_id = #message.id
(is that the behavior you wanted?)
Also, why do you have #new_message and #message?
Update
As said in the comments:
I have this
<%= link_to "Reply", reply_user_messages_path(#message.sender, :conversation_id => #message) %>
<%= link_to "Reply", reply_user_messages_path(#message.sender, :conversation_id => #message.conversation_id) %>
I need to find a way to merge the two of them. One method sets a conversation_id and the other copies it.
Easiest way to do that, one line if:
<%= link_to "Reply", reply_user_messages_path(#message.sender, conversation_id: #message.conversation_id ? #message.conversation_id : #message.id) %>

The action 'update' could not be found for MessagesController

I am trying to add the compose box on the message view so that it can send a new message that references the original message id. The code I have is giving me a The action 'update' could not be found for MessagesController. It should not be updating the current record, as it's supposed to be submitting a new message id and referencing the original_message_id.
Should I change how the form submits itself? As on my working reply page the page url is http://localhost:3000/users/1/messages/new?reply_to=3 and that submits a new message. With my current code I am being directed to http://localhost:3000/users/1/messages/new
Can someone take a look and let me know what I am doing wrong?
Message show with compose box:
<strong>From:</strong>
<%= #message.sender %>
</p>
<p>
<strong>Received:</strong>
<%= #message.created_at.strftime('%B %-d, %Y %l:%M%P') %>
</p>
<p>
<strong>Subject:</strong>
<%= #message.subject %>
</p>
<p>
<strong>Message</strong><br />
<%=h #message.body %>
</p>
<%= form_for #message, :url => new_user_message_path(#user, :reply_to => #message.sender.id) do |f| %>
<% if #message.recipient_id.nil? %>
<p>
To:<br />
<%= f.hidden_field :recipient_id, :value => params[:user_id] %>
</p>
<% end %>
<p>
<%= f.hidden_field :subject %>
</p>
<p>
Reply:<br />
<%= f.text_area :body %>
</p>
<%= submit_tag "Send"%>
<% end %>
<p>
<% if #message.next %>
<%= link_to 'Next', user_message_path(current_user, #message.next) %>
<% end %>
<% if #message.previous %>
<%= link_to 'Previous', user_message_path(current_user, #message.previous) %>
<% end %>
</p>
<p>
<% if #message.recipient == #user %>
<%= link_to "Reply", new_user_message_path(#user, :reply_to => #message.sender.id) %>
|
<% end %>
<%= link_to "Inbox", user_messages_path(current_user, :mailbox=>:inbox)%>
|
<%= link_to "Delete", [current_user, #message], :confirm => 'Are you sure you want to delete this message?', :method => :delete %>
</p>
Messages controller:
before_filter :set_user
def index
if params[:mailbox] == "sent"
#messages = #user.sent_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
elsif params[:mailbox] == "inbox"
#messages = #user.received_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
#elsif params[:mailbox] == "archived"
# #messages = #user.archived_messages
end
if params[:mailbox] == "unread"
#messages = #user.unread_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
end
if params[:mailbox] == "trash"
#messages = #user.deleted_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
end
end
def new
#message = Message.new
if params[:reply_to]
#reply_to = User.find_by_id(params[:reply_to])
unless #reply_to.nil?
#message.recipient_id = #reply_to.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
def reply
#message = Message.find(params[:id]).reply(id)
end
private
def set_user
#user = current_user
end
end
Messages model:
attr_accessible :subject, :body, :sender_id, :recipient_id, :read_at,:sender_deleted,:recipient_deleted
validates_presence_of :subject, :message => "Please enter message title"
has_many :notifications, as: :event
belongs_to :user
scope :unread, -> {where('read_at IS NULL')}
scope :not_deleted_by_recipient, where('messages.recipient_deleted IS NULL OR messages.recipient_deleted = ?', false)
scope :not_deleted_by_sender, where('messages.sender_deleted IS NULL OR messages.sender_deleted = ?', false)
belongs_to :sender,
:class_name => 'User',
:foreign_key => 'sender_id'
belongs_to :recipient,
:class_name => 'User',
:foreign_key => 'recipient_id'
def reply
new_message.reply_from_user_id = self.id #save the user id of original repost, to keep track of where it originally came from
end
def self.by_date
order("created_at DESC")
end
# 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 = user_id if self.recipient_id == user_id
(self.sender_deleted > 0 && self.recipient_deleted > 0) ? self.destroy : self.save!
(self.sender_deleted != 0 && self.recipient_deleted != 0)
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 next(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 previous(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
private
def send_notification(message)
message.notifications.create(user: message.recipient)
end
You are really missing the update method in your Controller. Implementing it should solve your problem.

how to setup previous/next message for inbox messaging

I have created a inbox messaging system and it works perfect. However I don't know how to implement a previous and next feature for the messages (so users can go to the next or previous message while viewing one). These are normal functions for viewing messages on the internet. Previous should mean previous by message creation time. Any help would be appreciated.
messages_controller:
before_filter :set_user
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
message model:
attr_accessible :subject, :body, :sender_id, :recipient_id, :read_at,:sender_deleted,:recipient_deleted
validates_presence_of :subject, :message => "Please enter message title"
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
end
show.html (message view):
<strong>From:</strong>
<%= #message.sender %>
</p>
<p>
<strong>Received:</strong>
<%= #message.created_at.to_s(:long) %>
</p>
<p>
<strong>To:</strong>
<%= #message.recipient %>
</p>
<p>
<strong>Message</strong><br />
<%=h #message.body %>
</p>
<p>
<% if #message.recipient == #user %>
<%= link_to "Reply", new_user_message_path(#user, :reply_to => #message.sender) %>
|
<% end %>
<%= link_to "Inbox", user_messages_path(current_user, :mailbox=>:inbox)%>
|
<%= link_to "Delete", [current_user, #message], :confirm => 'Are you sure you want to delete this message?', :method => :delete %>
</p>
In the Message model:
def previous(same_recipient = true)
collection = Message.where('id <> ? AND updated_at > ?', self.id, self.updated_at).order('updated_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 updated_at < ?', self.id, self.updated_at).order('updated_at DESC')
collection.where(recipient_id: self.recipient_id) if same_recipient
collection.first
end
This is what we use in our Calendar system, very usefull to go Previous / Next with the Apppointments.
This rely on the updated_at column, which is kind of bad (if I update an old message it will confuse the next/previous). Maybe you want to use the created_at column, or your own. With this you could do in your view:
# [...]
<p>
<strong>Message</strong><br />
<%=h #message.body %>
</p>
<p>
<%= link_to 'Next', user_message_path(current_user, #message.next) %>
<%= link_to 'Previous', user_message_path(current_user, #message.previous) %>
</p>
In your controller for the viewing of the message, get 3 messages from the DB, and display the middle entry as the current message. Set the ID's to the previous and next message as variables.
Then in your view make two buttons: previous and next where their link urls are the path to the IDs you saved.

#user.received_messages not displaying messages for inbox

I am making a inbox messaging for a rails app. In my _inbox.html file I have "<% #user.received_messages.each do |message| %>" but it is not displaying any of the messages I have sent. There's no error message, just a blank space.
Is there another line of coding I should be using to display all messages from inbox?
_inbox.html:
<h2>Your Inbox</h2>
<% #user.received_messages.each do |message| %>
No messages in your Inbox
<% end %>
message model:
class Message < ActiveRecord::Base
attr_accessible :subject, :body, :sender_id, :recepient_id, :read_at,:sender_deleted,:recepient_deleted
validates_presence_of :subject, :message => "Please enter message title"
belongs_to :sender,
:class_name => 'User',
:foreign_key => 'sender_id'
belongs_to :recepient,
:class_name => 'User',
:foreign_key => 'recepient_id'
# marks a message as deleted by either the sender or the recepient, which ever the user that was passed is.
# When both sender and recepient marks it deleted, it is destroyed.
def mark_message_deleted(id,user_id)
self.sender_deleted = true if self.sender_id == user_id and self.id=id
self.recepient_deleted = true if self.recepient_id == user_id and self.id=id
self.sender_deleted && self.recepient_deleted ? self.destroy : save!
end
# Read message and if it is read by recepient then mark it is read
def self.readingmessage(id, reader)
message = find(id, :conditions => ["sender_id = ? OR recepient_id = ?", reader, reader])
if message.read_at.nil? && (message.recepient.user_id==reader)
message.read_at = Time.now
message.save!
end
message
end
# Based on if a message has been read by it's recepient returns true or false.
def read?
self.read_at.nil? ? false : true
end
end
message controller:
class MessagesController < ApplicationController
before_filter :set_user
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
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.recepient_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.readingmessage(params[:id],#user_id)
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
I finally fixed the problem I was having.
In user.rb I had to remove the "has many: received messages" block. Then def received_messages as following:
def received_messages
Message.received_by(self)
end
Following that in the _inbox views this line of coding had to be removed:
<td><%= "#{message.sender.first_name} #{message.sender.last_name}" %></td>
I don't see where you are printing the messages. Try something like:
<h2>Your Inbox</h2>
<% if #user.received_messages.empty? %>
No messages in your Inbox
<% end %>
<% #user.received_messages.each do |message| %>
<%= message.body %>
<% end %>

how to setup action to delete message for inbox

I am working on custom inbox system. When I go to delete message it flashes a message that message is deleted. However I can still view the message from my inbox and by typing in the URL. How do I setup an action so that the message actually permanently deletes or at least gets place inside of a delete folder (that I have no created yet)?
message model:
class Message < ActiveRecord::Base
attr_accessible :subject, :body, :sender_id, :recepient_id, :read_at,:sender_deleted,:recepient_deleted
validates_presence_of :subject, :message => "Please enter message title"
belongs_to :sender,
:class_name => 'User',
:foreign_key => 'sender_id'
belongs_to :recepient,
:class_name => 'User',
:foreign_key => 'recepient_id'
# marks a message as deleted by either the sender or the recepient, which ever the user that was passed is.
# When both sender and recepient marks it deleted, it is destroyed.
def mark_message_deleted(id,user_id)
self.sender_deleted = true if self.sender_id == user_id and self.id=id
self.recepient_deleted = true if self.recepient_id == user_id and self.id=id
self.sender_deleted && self.recepient_deleted ? self.destroy : save!
end
# Read message and if it is read by recepient then mark it is read
def self.readingmessage(id, reader)
message = find(id, :conditions => ["sender_id = ? OR recepient_id = ?", reader, reader])
if message.read_at.nil? && (message.recepient.user_id==reader)
message.read_at = Time.now
message.save!
end
message
end
# Based on if a message has been read by it's recepient returns true or false.
def read?
self.read_at.nil? ? false : true
end
def self.received_by(user)
where(:recepient_id => user.id)
end
def self.not_recepient_deleted
where("recepient_deleted = ?", false)
end
end
message controller:
class MessagesController < ApplicationController
before_filter :set_user
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
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.recepient_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])
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
inbox view:
<h2>Your Inbox</h2>
<% if #messages.size == 0 %>
No messages in your Inbox
<% end %>
<% else %>
<%= form_tag delete_multiple_user_messages_path, :method=>:post do %>
<table class="table table-bordered">
<tr>
<th>Delete?</th>
<th>Sent</th>
<th>Sender</th>
<th>Sent</th>
</tr>
<% for message in #messages %>
<tr>
<td><%= check_box_tag "delete[]", message.id %></td>
<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>
</tr>
<% end %>
</table>
<%= submit_tag "Delete selected" %> |
<% end %>
<%= link_to "Compose New Message", new_user_message_path(#user)%> |
<%= link_to "View Sent Messages", user_messages_path(current_user, :mailbox => :sent)%>
Here we go...
One way is to delete the messages permanently from the database, so that they wont be available further even if one can hit the specific url.
or if you want to do soft-delete the messages instead of permanently deleting from the database, in that case, you have to add one condition in the show method so that if a message is soft-deleted, then index page.
so your show method could be
def show
#message = Message.where(:id => params[:id], :deleted => false).first
redirect_to messages_path unless #message.present?
end
in the above query, i assumed that deleted is the field which can be used to tell weather one has deleted or not. And the above query will return a message if only that deleted is false.
UPDATE:
After checking your method mark_message_deleted in model, modify the method as below
def mark_message_deleted(id,user_id)
self.sender_deleted = true if self.sender_id == user_id
self.recepient_deleted = true if self.recepient_id == user_id
(self.sender_deleted && self.recepient_deleted) ? self.destroy : self.save!
end
this one alone is sufficient.

Resources