目前,需要sender_id
和conversation.id
才能在2个用户之间启动对话。
如果我想允许第三个用户加入对话,协会将如何运作?
当用户开始对话时,sender_id
属于recipient_id
和visitor_id
。
我希望current_user
(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
)能够加入任何对话,所有用户都能够查看所有对话。
conversation.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
user.rb
belongs_to :visitor, :foreign_key => :visitor_id, class_name: 'User'
我很好奇是否添加
很容易class Message < ActiveRecord::Base
belongs_to :conversation
belongs_to :user
validates_presence_of :body, :conversation_id, :user_id
end
到conversation.rb模型。但我不知道如何获得属于current_user的visitor_id加入特定的对话(或让所有人都可以查看所有对话)。
编辑:添加了message.rb和控制器。
message.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
conversations_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
messages_controller.rb
pbsc qty wt
pbsc1 1 0
pbsc2 2 10
pbsc3 1 0
pbsc2 2 9
pbsc1 0 8
pbsc4 9 9
答案 0 :(得分:2)
添加:visitor
将允许第三方进行最小的更改,但不允许第四或第k个额外的访问者轻松。这似乎是一个可能的场景,因此您需要一个跟踪所有users_conversations
的联接表。
首先为连接表创建一个迁移:
class CreateUsersConversationsJoinTable < ActiveRecord::Migration
def change
create_table :users_conversations do |t|
t.integer :user_id, null: false
t.integer :conversation_id, null: false
end
add_index :users_conversations, [:user_id, :conversation_id], unique: true
end
end
然后沿着这些方向创建一个模型:
class UsersConversations
belongs_to :users, class_name: User, inverse_of: :users_conversations
belongs_to :conversations, class_name: Conversation, inverse_of: :users_conversations
validates :user_id, :conversation_id, presence: true
end
您还需要创建迁移以将发件人和收件人移动到此新模型中。
您需要将发件人属性从会话移动到邮件,并通过邮件让对话了解发件人:has_many :senders through: message, foreign_key: sender_id
。这样每条消息都会跟踪其发件人。
您的接收方将成为未发送特定消息的对话中的所有用户。您的邮件类需要添加以下内容:
has_many :users_conversations, through: :conversations
has_many :receivers, -> { where('users_conversations.user_id != messages.sender_id') }, through: :users_conversations, foreign_key: :user_id, class_name: 'User'
虽然您的会话课需要更改:between
以使用/替换为users
,您的范围将如下所示:
scope :involving, -> (user) do
users_conversations.where(user: user)
end
要获得所有对话,您只需在相关控制器中指定@conversations = Conversation.all
,或使用控制器索引路径。