Tôi đang cố gắng thiết lập hệ thống nhắn tin tương tự như facebook nơi bạn có danh sách thư được sắp xếp theo cuộc hội thoại giữa hai người dùng (điều này không quan trọng đối với nhiều người nhận vào lúc này, nhưng có lẽ nếu tôi đã sử dụng một thiết kế thông minh hơn thì có thể dễ dàng triển khai trong tương lai. Tôi không nghĩ sẽ dễ dàng thêm vào những gì tôi hiện có). Tôi có một số loại làm việc, nhưng tôi không thể thực hiện một vài tính năng. Tôi khá mới để rails/lập trình web, vì vậy bất kỳ và tất cả các mẹo/gợi ý/giải pháp được nhiều đánh giá cao.Thực hiện hệ thống nhắn tin kiểu facebook, nơi người dùng có thể ở một trong hai cột khác nhau của một mô hình khác
Vì vậy, tôi có ba mô hình có liên quan: Người dùng, Cuộc trò chuyện và Tin nhắn. Người dùng có nhiều cuộc hội thoại, Cuộc hội thoại có nhiều tin nhắn và thuộc về Người dùng và Tin nhắn thuộc về Cuộc hội thoại. Được rồi, vì vậy đây là những gì các mô hình trông giống như:
User: có liên quan lĩnh vực ID: int, tên người dùng: string
class User < ActiveRecord::Base
has_many :conversations, :class_name => "Conversation", :finder_sql =>
proc {
"SELECT * FROM conversations " +
"WHERE conversations.user1_id = #{id} OR conversations.user2_id = #{id} " +
"ORDER BY conversations.updated_at DESC" }
thoại: có lĩnh vực liên quan: ID: int, user1_id: int, user2_id: int, user1_deleted: boolean, user2_deleted: boolean, created_at: datetime, updated_at: datetime
class Conversation < ActiveRecord::Base
has_many :messages
belongs_to :participant_one, :class_name => "User", :foreign_key => :user1_id
belongs_to :participant_two, :class_name => "User", :foreign_key => :user2_id
private
def self.between(user1, user2)
c = Conversation.arel_table
Conversation.where(c[:user1_id].eq(user1).and(c[:user2_id].eq(user2)).or(c[:user1_id].eq(user2).and(c[:user2_id].eq(user1))))
nhắn: có lĩnh vực liên quan: id: int, conversation_id: int, AUTHOR_ID: int, nội dung: văn bản, created_at: datetime, updated_at: datetime
class Message < ActiveRecord::Base
belongs_to :conversation, :touch => true
Tôi không thực sự chắc chắn nếu tôi cần participant_one và participant_two, nhưng tôi sử dụng
def conversation_partner(conversation)
conversation.participant_one == current_user ? conversation.participant_two : conversation.participant_one
end
trong một ConversationHelper để trong quan điểm, tôi có thể hiển thị các thành viên khác.
Vì vậy, điều này về cơ bản hoạt động. Nhưng một trong những biến chứng tôi có là tôi không thực sự phân biệt người dùng rất tốt trong Cuộc trò chuyện, người dùng có thể ở trong trường user1 hoặc trường user2. Vì vậy, tôi cần phải liên tục tìm kiếm người dùng trong một hoặc một trường khác, ví dụ: trong hàm finder_sql của khai báo has_many của người dùng. Ngoài ra, khi tôi tạo một thư mới, trước hết tôi tìm kiếm xem có tham số Cuộc trò chuyện hay không, nếu có, hãy xem có cuộc trò chuyện giữa hai người dùng không và sau đó tạo cuộc trò chuyện mới. (Bạn có thể gửi tin nhắn từ chỉ mục hội thoại (như trả lời) hoặc current_user có thể xem người dùng khác và nhấp vào liên kết "gửi người dùng này một tin nhắn". Bộ điều khiển messagecontroller trông như thế này và sử dụng bản thân đó. giữa phương pháp trong mô hình hội thoại:.
class MessagesController < ApplicationController
before_filter :get_user
before_filter :find_or_create_conversation, :only => [:new, :create]
def new
@message = Message.new
end
def create
@message = @conversation.messages.build(params[:message])
@message.author_id = current_user.id
if @message.save
redirect_to user_conversation_path(current_user, @conversation), :notice => "Message sent!"
else
redirect_to @conversation
end
end
private
def get_user
@user = User.find(params[:user_id])
end
def find_or_create_conversation
if params[:conversation_id]
@conversation = Conversation.find(params[:conversation_id])
else
@conversation = Conversation.between(@user.id, current_user.id).first or @conversation = Conversation.create!(:user1_id => current_user.id, :user2_id => @user.id)
end
end
(tuyến đường của tôi trông như thế này :)
resources :users do
resources :conversations, :only => [:index, :create, :show, :destroy] do
resources :messages, :only => [:new, :create]
end
resources :messages, :only => [:new]
end
Vì vậy, bây giờ, tôi đang gặp vấn đề cố gắng để thiết lập các cờ user1_deleted hoặc user2_deleted (và tương tự nếu/khi tôi thực hiện cờ đọc/cập nhật) Vấn đề là vì cùng một Người dùng có thể có nhiều cuộc hội thoại, nhưng anh ta có thể là user1 hoặc user2, nó trở nên khó tìm anh ta. Tôi đã suy nghĩ tôi có thể làm một cái gì đó như thế này trong mô hình hội thoại:
def self.active(user)
Conversation.where(which_user?(user) + "_deleted = ?", false)
end
def self.which_user?(user)
:user1_id == user ? 'user1' : 'user2'
end
Nhưng sau đó bạn không thể chạy nó toàn bộ cuộc nói chuyện, trừ khi bạn lặp qua từng trò chuyện một người dùng một, bởi vì đôi khi ông là user1 và đôi khi anh ta là user2. Tôi có nên mương toàn bộ cách tiếp cận này và thử thiết kế mới không? Nếu vậy, liệu có ai có thể tiếp cận tốt hơn/thực hiện tốt hơn/thực sự làm việc và vẫn đáp ứng được nhu cầu tương tự không?
Đây là một câu hỏi khá dài, vì vậy tôi đánh giá cao bất cứ ai sẵn sàng lội qua tất cả điều này với tôi. Cảm ơn.
Hey Brandon, nhiều nghĩa vụ cho một câu trả lời hào phóng như vậy. Tôi sẽ nghiên cứu kỹ vào ngày mai. Thật thú vị, khi tôi làm việc này, tôi đã nghĩ cả việc tạo bản sao của Cuộc hội thoại cũng như sử dụng một số loại proxy giữa người dùng và cuộc trò chuyện, nhưng tôi không thể ghép các mảnh lại với nhau. Nếu tôi có bất kỳ câu hỏi nào sau khi tôi làm việc, tôi sẽ cho bạn biết. Cảm ơn một lần nữa! – kindofgreat
Xin chào Brandon, bạn có thể thêm các thuộc tính có thể truy cập vào các mô hình không? Nó sẽ giúp ích rất nhiều trong việc học bảo mật phần mềm tốt. –
Michelle, tôi yêu bạn! Cảm ơn vì điều này và mã github! – kpaul