Reputation: 11153
I'm having trouble with has_many
through:
models.
What I'd like to do is create 2 person chat rooms in my model. Therefore, users has_many
chats and has_many
messages through chats.
How do I access a recently created id and also allow for that id to be non-unique? Also, do I have the right setup for what I am trying to do?
@u = User.find_by_id(1)
@u.chats.new.save <--How to get this chat id to associate with another user id?
my models:
class User < ActiveRecord::Base
has_many :chats
has_many :messages, through: :chats
end
class Chat < ActiveRecord::Base
belongs_to :user
belongs_to :message
end
class Message < ActiveRecord::Base
has_many :chats
has_many :users, through: :chats
end
Upvotes: 0
Views: 43
Reputation: 76774
This is a tough one - we have implemented something similar recently using the following setup:
#app/models/user.rb
Class User < ActiveRecord::Base
#Chats
def messages
Chat.where("user_id = ? OR recipient_id = ?", id, id) # -> allows you to call @user.chats.sent to retrieve sent messages
end
end
#app/models/chat.rb #- > id, user_id, recipient_id, message, read_at, created_at, updated_at
Class Chat < ActiveRecord::Base
belongs_to :user
belongs_to :recipient, class_name: "User", foreign_key: "recipient_id"
#Read
scope :unread, ->(type) { where("read_at IS #{type} NULL") }
scope :read, -> { unread("NOT") }
#Sent
scope :sent, -> { where(user_id: id) }
scope :received, -> { where(recipient_id: id) }
end
This setup makes every chat
"owned" by a particular user. This is done when you create a message, and represents the sender
. Every message has a single recipient
, which you can see with recipient_id
So you'll be able to send new messages to users like this:
@chat = Chat.new(chat_params)
def chat_params
params.require(:chat).permit(:user_id, :recipient_id, :message)
end
This will be okay for a single chat room (I.E single message transcript between two users -- private messaging etc).
Can you explain how your chat rooms need to work? For example, if you only have two-way chats, surely you can use my above code? However, I feel it's not right; and I therefore want to refactor or you to accommodate multiple chat rooms
Upvotes: 1
Reputation: 9443
I'm sure there's a better way to do this, but this should give you your desired results.
@u = User.find(1) # You can use "find" instead of "find_by_id"
(@chat = @u.chats.new).save
@chat.users << User.find(x) # However you want to get the other user in the chat
Upvotes: 0