通过 Actioncable 使用群聊查找与当前用户关联的所有聊天室
Find all chatrooms associated with a current user using Group Chat via Actioncable
很抱歉这个基本问题。我设法按照教程进行操作,并使用 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
User.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
聊天室用户控制器
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
在 class User < ApplicationRecord
中你有以下声明
has_many :chatrooms, through: :chatroomusers
这允许用户 class 的实例获取与该用户关联的所有聊天室。
鉴于您要求
all the chatrooms associated with a current 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 更改为匹配
很抱歉这个基本问题。我设法按照教程进行操作,并使用 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
User.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
聊天室用户控制器
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
在 class User < ApplicationRecord
中你有以下声明
has_many :chatrooms, through: :chatroomusers
这允许用户 class 的实例获取与该用户关联的所有聊天室。
鉴于您要求
all the chatrooms associated with a current 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 更改为匹配