Currently, it requires recipient_id
and sender_id
to start a Conversation between 2 users.
How would the associations work if I wanted to allow a 3rd user to join a Conversation?
When a user starts a conversation, the conversation.id
belongs to sender_id
and recipient_id
.
I want visitor_id
(which is the current_user
) to be able to join any conversation and all users to be able to view all conversations.
conversation.rb
class Conversation < ActiveRecord::Base
belongs_to :sender, :foreign_key => :sender_id, class_name: 'User'
belongs_to :recipient, :foreign_key => :recipient_id, class_name: 'User'
has_many :messages, dependent: :destroy
validates_uniqueness_of :sender_id, :scope => :recipient_id
scope :involving, -> (user) do
where("conversations.sender_id =? OR conversations.recipient_id =?",user.id,user.id)
end
scope :between, -> (sender_id,recipient_id) do
where("(conversations.sender_id = ? AND conversations.recipient_id =?) OR (conversations.sender_id = ? AND conversations.recipient_id =?)", sender_id,recipient_id, recipient_id, sender_id)
end
end
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :conversations, :foreign_key => :sender_id
after_create :create_default_conversation
I'm curious is if it's easy as adding
belongs_to :visitor, :foreign_key => :visitor_id, class_name: 'User'
to the conversation.rb model. But i'm not sure how i can get visitor_id which belongs to current_user to join a specific conversation (or make all conversations viewable to everyone).
EDIT: Added message.rb and controllers.
message.rb
class Message < ActiveRecord::Base
belongs_to :conversation
belongs_to :user
validates_presence_of :body, :conversation_id, :user_id
end
conversations_controller.rb
class ConversationsController < ApplicationController
before_filter :authenticate_user!
layout false
def create
if Conversation.between(params[:sender_id],params[:recipient_id]).present?
@conversation = Conversation.between(params[:sender_id],params[:recipient_id]).first
else
@conversation = Conversation.create!(conversation_params)
end
render json: { conversation_id: @conversation.id }
end
def show
@conversation = Conversation.find(params[:id])
@reciever = interlocutor(@conversation)
@messages = @conversation.messages
@message = Message.new
end
private
def conversation_params
params.permit(:sender_id, :recipient_id)
end
def interlocutor(conversation)
current_user == conversation.recipient ? conversation.sender : conversation.recipient
end
end
messages_controller.rb
class MessagesController < ApplicationController
before_filter :authenticate_user!
def create
@conversation = Conversation.find(params[:conversation_id])
@message = @conversation.messages.build(message_params)
@message.user_id = current_user.id
@message.save!
#@path = conversation_path(@conversation)
end
private
def message_params
params.require(:message).permit(:body)
end
end
users_conversations
. – Pyrcesender
attributes from conversation to message and make conversations know about sender/receiver via messages (has_many :senders through: message
). That way each message tracks its senders. Your receiver becomes all users in a conversation that didn't send a particular message. Going this route you'd probably want visitors, senders, and receivers to all just be users on a conversation instance. If this sounds right I'll form an answer along these lines. – Pyrce