A
A
Anton Ipatov2020-08-30 00:51:02
MongoDB
Anton Ipatov, 2020-08-30 00:51:02

How to make messages readable by only two users (private messages) in Rails?

Hello, I use Ruby on Rails and Mongoid
. I need messages in MessagesController to be read only by the user who sent the messages and to whom the message was intended, that is, in fact, private messages between two users

message.rb

class Message
  include Mongoid::Document
  include Mongoid::Timestamps::Created

  field :body, type: String
  field :read,  type: Mongoid::Boolean, default: false  
  field :is_deleted, type: Mongoid::Boolean, default: false
  field :conversation_id, type: BSON::ObjectId
  field :sender_id, type: BSON::ObjectId
  field :receiver_id, type: BSON::ObjectId

  belongs_to :conversation
  belongs_to :sender, class_name: 'User', foreign_key: 'sender_id'
  belongs_to :receiver, class_name: 'User', foreign_key: 'receiver_id'

  validates_presence_of :body, :conversation_id, :sender_id, :receiver_id

  index({ conversation_id: 1 }, { name: 'index_messages_on_conversation_id', background: true })
  index({ user_id: 1 }, { name: 'index_messages_on_user_id', background: true })

  def message_time
    created_at.strftime("%d/%m/%y at %l:%M %p")
  end
end


messages_controller.rb

class MessagesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_conversation, only: [:index, :create]
  before_action :correct_user, only: [:index]
  
  def index
    @conversation.messages.where(receiver_id: current_user.id, read: false).update_all(read: true)
    @message = @conversation.messages.new
  end

  def create
    @message = @conversation.messages.new(message_params.except(:recipient_ids))
    @message.sender_id = current_user.id
    @message.receiver_id = @conversation.recipient(current_user)
    @message.save!

  end

  private

  def message_params
    params.require(:message).permit(:body)
  end

  def set_conversation
    @conversation = Conversation.find(params[:conversation_id])
  end

  def correct_user
    redirect_to root_path if @conversation.messages.any_of({sender_id: current_user.id}, {receiver_id: current_user.id}) == current_user._id
  end
end


conversation.rb

class Conversation
  include Mongoid::Document

  field :is_deleted, type: Mongoid::Boolean, default: false
  field :sender_id, type: Integer
  field :receiver_id, type: Integer

  belongs_to :sender, class_name: 'User', foreign_key: 'sender_id'
  belongs_to :receiver, class_name: 'User', foreign_key: 'receiver_id'
  has_many :messages, dependent: :destroy


  validates_uniqueness_of :sender_id, scope: :receiver_id

  scope :between, -> (sender_id, receiver_id) do
    any_of({sender_id: sender_id, receiver_id: receiver_id}, {sender_id: receiver_id, receiver_id: sender_id})
  end


  def recipient(current_user)
    self.sender_id == current_user.id ? self.receiver : self.sender
  end
end

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Ipatov, 2020-08-30
@IpatovAnton

I decided with a simple check if the current user is not the sender and not the receiver of this dialog, then the user will be redirected to the home page.

class MessagesController < ApplicationController
  before_action :correct_user, only: [:index]

private

  def correct_user
    redirect_to root_path unless @conversation.sender_id == current_user.id || @conversation.receiver_id == current_user.id
  end
end

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question