【问题标题】:Find all chatrooms associated with a current user using Group Chat via Actioncable通过 Actioncable 使用 Group Chat 查找与当前用户关联的所有聊天室
【发布时间】:2017-05-21 02:47:36
【问题描述】:

为基本问题道歉。我设法遵循教程并使用 Action Cable 建立了一个群聊,并从中学到了很多东西。但是,我试图打开一个特定的 html 页面——与当前用户关联的所有聊天室。我尝试了以下操作,但这仅给了我当前显示的 direct_message 页面。我在下面列出了所有相关代码。

show.html.erb(在我的聊天室 html 文件夹中)

<% @chatroomall.each do |chatroom| %>
<div>
<%= @chatroom.name %>
</div>
<% end %>

Rails 日志

 Chatroom Load (0.4ms)  SELECT  "chatrooms".* FROM "chatrooms" WHERE "chatrooms"."direct_message" = ? AND "chatrooms"."name" = ? ORDER BY "chatrooms"."id" ASC LIMIT ?  [["direct_message", true], ["name", "Monica and Rodrigo Williams"], ["LIMIT", 1]]

Chatroom.rb

class Chatroom < ApplicationRecord
has_many :chatroomusers
has_many :users, through: :chatroomusers
has_many :messages

scope :public_channels, ->{where(direct_message: false) }
scope :direct_messages, ->{ where(direct_message: true) }

def self.direct_message_for_users(users)
    user_ids = users.map(&:username).sort
    name = "#{user_ids.join(" and ")}"

    if chatroom = direct_messages.where(name: name).first
        chatroom
    else

        chatroom = new(name: name, direct_message: true)
        chatroom.users = users
        chatroom.save
        chatroom
    end

end
end

chatroomuser.rb

class Chatroomuser < ApplicationRecord
belongs_to :user
belongs_to :chatroom
end

message.rb

class Message < ApplicationRecord
belongs_to :user
belongs_to :chatroom
end

用户.rb

class User < ApplicationRecord
devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :omniauthable, omniauth_providers: [:facebook]

cattr_accessor :current_user
has_many :chatroomusers
has_many :chatrooms, through: :chatroomusers
has_many :messages
end

Chatrooms_controller.rb

class ChatroomsController < ApplicationController
before_action :set_chatroom, only: [:show, :edit, :update, :destroy]
def index
@chatrooms = Chatroom.public_channels
end
def show
@messages = @chatroom.messages.order(created_at: :desc).limit(100).reverse
end
private
def set_chatroom
  @chatroom = Chatroom.find(params[:id])
end
def chatroom_params
  params.require(:chatroom).permit(:name)
end
end

直接消息控制器

class DirectMessagesController < ApplicationController
before_action :authenticate_user!

def show
    users = [current_user, User.find(params[:id])]
    @messageduser = User.find(params[:id])
    @chatroom = Chatroom.direct_message_for_users(users)        
    @chatroomall = Chatroom.all
    @messages = @chatroom.messages.order(created_at: :desc).limit(100).reverse
    @messagelast = @chatroom.messages.last(1)
    render "chatrooms/show"
end
private

def chatroomuserlocator
    @chatroomlocator = Chatroom.find(params[:chatroom_id])
end
end

ChatroomUsers 控制器

class ChatroomUsersController < ApplicationController
before_action :authenticate_user!
before_action :set_chatroom
def create
@chatroomuser = @chatroom.chatroomusers.where(user_id: current_user.id).first_or_create
redirect_to @chatroom
end
def destroy
@chatroomuser = @chatroom.chatroomusers.where(user_id: current_user.id).destroy_all
redirect_to chatrooms_path
end
  private

def set_chatroom
  @chatroom = Chatroom.find(params[:chatroom_id])
end
end

Schema.rb

create_table "chatrooms", force: :cascade do |t|
t.string   "name"
t.datetime "created_at",     null: false
t.datetime "updated_at",     null: false
t.boolean  "direct_message"
end
create_table "chatroomusers", force: :cascade do |t|
t.integer  "user_id"
t.integer  "chatroom_id"
t.datetime "created_at",   null: false
t.datetime "updated_at",   null: false
t.datetime "last_read_at"
t.index ["chatroom_id"], name: "index_chatroomusers_on_chatroom_id"
t.index ["user_id"], name: "index_chatroomusers_on_user_id"
end
create_table "create_messages", force: :cascade do |t|
t.integer  "user_id"
t.integer  "chatroom_id"
t.text     "body"
t.datetime "created_at",  null: false
t.datetime "updated_at",  null: false
t.index ["chatroom_id"], name: "index_create_messages_on_chatroom_id"
t.index ["user_id"], name: "index_create_messages_on_user_id"
end

【问题讨论】:

  • 聊天室用户的架构是什么样的?也许您没有正确命名命名约定和活动记录?您正在使用连接表 (chatroomusers) 那么为什么在 rails 生成的 SQL 查询中没有连接呢?如果 chatroomusers 有一个 user_id 和 chat_room_id 他们可能没有正确命名,因为没有生成 SQL 连接。
  • @OneNeptune 非常感谢您的回复。我已经用我的架构和 chatroom_users 控制器更新了这个问题。加入是通过 chatroom.rb 模型使用 name = "#{user_ids.join(" and ")}" 至少我相信的。
  • 我已经提供了答案,但如果您仍然在苦苦挣扎,请随时打开聊天,因为我认为您在一些基本的 Rails 概念上苦苦挣扎,我很乐意提供帮助

标签: ruby-on-rails ruby ruby-on-rails-5 actioncable


【解决方案1】:

class User &lt; ApplicationRecord 你有以下声明

has_many :chatrooms, through: :chatroomusers

这允许 User 类的实例获取与该用户关联的所有聊天室。

鉴于你的要求

与当前用户关联的所有聊天室

在你的视图模板中你有

<% @chatroomall.each do |chatroom| %>
<div>
<%= @chatroom.name %>
</div>
<% end %>

您需要修复@chatroom.name 以引用@chatroomall.each do |chatroom|设置的本地聊天室变量,方法是将代码更改为

<%= chatroom.name %>

请注意,您现在引用的是局部变量,而不是控制器设置的全局 @chatroom

您可以通过将显示操作修改为如下所示来设置控制器显示操作以提供实例变量 @chatroomall

def show
    users = [current_user, User.find(params[:id])]
    @messageduser = User.find(params[:id])
    @chatroom = Chatroom.direct_message_for_users(users)        
    #@chatroomall = Chatroom.all Change this to
    @chatroomall = current_user.chatrooms
    @messages = @chatroom.messages.order(created_at: :desc).limit(100).reverse
    @messagelast = @chatroom.messages.last(1)
    render "chatrooms/show"
end

注意变化

#@chatroomall = Chatroom.all Change this to
@chatroomall = current_user.chatrooms

或更改您的模板以循环遍历 current_user.chatrooms

** 更新 ** 这假设您在某个地方有一个 current_user。如果您当前登录的用户实例的名称不是 current_user 则更改 current_user 以匹配

【讨论】:

  • 非常感谢您在这件事上提供的帮助。效果很好,我希望如果你有时间可以帮助我解决这个相关问题。我尝试按照您的示例并应用它来获取属于当前用户的每个聊天室的最后一条消息。我能够走得很远,但我的部分被困在一个数组中。我怎样才能只显示正文部分,这是我的 html 视图中的代码 - &lt;%= chatroom.messages.last(1) %&gt;
  • @Omar 请将此作为另一个问题提出,请随时回到这里并指点我,我很乐意看看
  • 非常感谢,我刚刚把它放到了一个新问题中 - stackoverflow.com/questions/44096732/…
  • 如果您有空闲时间并且可以有机会看看这个我完全被困在搜索方面的新问题,先生stackoverflow.com/questions/44230346/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2012-07-29
  • 2012-10-27
  • 2012-01-17
  • 2020-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多