通过 Actioncable 使用群聊查找与聊天室关联的消息用户的图像 [英] Find Image of Messaged User associated with chatrooms using Group Chat via Actioncable

查看:57
本文介绍了通过 Actioncable 使用群聊查找与聊天室关联的消息用户的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对基本问题表示歉意.我设法按照教程进行操作,并在 SO 社区的帮助下设法使用 Action Cable 建立了群聊,并从中学到了很多东西.但是,我正在尝试打开特定的 html 页面 - 与 current_users 聊天室关联的消息用户的图像.我已经能够拉取与当前用户关联的聊天室以及这些聊天室中传递的最后一条消息.我尝试了以下操作,但这仅给了我当前聊天室中已发送消息的用户的图像.我在下面列出了我所有的相关代码.

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

<% @chatroomall.each do |chatroom|%><div><%= image_tag @messageduser.avatar.url(:thumb), id: "css-style3" %><%= chatroom.name %><%= chatroom.messages.last(1).pluck(:created_at) %><%= chatroom.messages.last(1).pluck(:body) %>

<%结束%>

Chatroom.rb

class 聊天室 <申请记录has_many : 聊天室用户has_many :users, 通过: :chatroomusershas_many :消息范围 :public_channels, ->{where(direct_message: false) }范围 :direct_messages, ->{ where(direct_message: true) }def self.direct_message_for_users(用户)user_ids = users.map(&:username).sortname = "#{user_ids.join(" and ")}"if chatroom = direct_messages.where(name: name).first聊天室别的聊天室 = 新(名称:名称,直接消息:真)chatroom.users = 用户聊天室.save聊天室结尾结尾结尾

chatroomuser.rb

class Chatroomuser <申请记录归属地:用户归属地:聊天室结尾

message.rb

类消息<申请记录归属地:用户归属地:聊天室结尾

User.rb

class User <申请记录设计 :database_authenticable, :registerable,:recoverable, :rememberable, :trackable, :validatable, :omniauthable, omniauth_providers: [:facebook]cattr_accessor :current_userhas_many : 聊天室用户has_many :chatrooms, 通过: :chatroomusershas_many :消息结尾

Chatrooms_controller.rb

class ChatroomsController <应用控制器before_action :set_chatroom, only: [:show, :edit, :update, :destroy]定义索引@chatrooms = Chatroom.public_channels结尾高清秀@messages = @chatroom.messages.order(created_at: :desc).limit(100).reverse结尾私人的def set_chatroom@chatroom = Chatroom.find(params[:id])结尾def chatroom_paramsparams.require(:chatroom).permit(:name)结尾结尾

直接消息控制器

class DirectMessagesController <应用控制器before_action :authenticate_user!高清秀用户 = [current_user, User.find(params[:id])]@messageduser = User.find(params[:id])@chatroom = Chatroom.direct_message_for_users(users)@chatroomall = current_user.chatrooms@messages = @chatroom.messages.order(created_at: :desc).limit(100).reverse@messagelast = @chatroom.messages.last(1)渲染聊天室/节目"结尾私人的定义聊天室用户定位器@chatroomlocator = Chatroom.find(params[:chatroom_id])结尾结尾

ChatroomUsers 控制器

class ChatroomUsersController <应用控制器before_action :authenticate_user!before_action :set_chatroom定义创建@chatroomuser = @chatroom.chatroomusers.where(user_id: current_user.id).first_or_create重定向到@chatroom结尾销毁@chatroomuser = @chatroom.chatroomusers.where(user_id: current_user.id).destroy_allredirect_to chatrooms_path结尾私人的def set_chatroom@chatroom = Chatroom.find(params[:chatroom_id])结尾结尾

Schema.rb

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

解决方案

所以你有一个你正在浏览的聊天室列表

<% @chatroomall.each do |chatroom|%>

所以在循环内部,您可以访问名为 chatroom 的变量中的每个特定聊天室,对吗?

所以对于每个特定的聊天室,您想显示最后一条消息用户的头像对吗?

<% @chatroomall.each do |chatroom|%><%= image_tag chatroom.messages.last.user.avatar.url(:thumb), id: "css-style3" %>

等等...

应该做的伎俩

更新

当然,有时可能会有聊天室中没有消息,因此需要通过简单的检查来处理

<% @chatroomall.each do |chatroom|%><% if chatroom.messages.empty?%>此聊天室中没有消息<%其他%><%= image_tag chatroom.messages.last.user.avatar.url(:thumb), id: "css-style3" 除非 chatroom.messages.last.user.blank?%>//注意对用户的额外检查<%结束%>

您可能希望通过使用 ul li 标签或其他东西来设置上述样式,这样您就不会只在一行中得到一个列表

将这样的逻辑放在模型中的另一个原因是,您可以在一个地方完成所有检查,并且在需要获取您正在寻找的信息时不必担心它,例如聊天室中的 last_user 方法模型也许只是一个简单的 chatroom.last_user.name 除非 last_user.blank? 将在您需要时发挥作用.更干净,这是 Rails 的方式!

结束更新

但是,您应该通过创建名为 last_message 的命名范围或方法将一些重复的代码重构到聊天室模型中

def last_message消息.last结尾

这样,如果您需要重构获取聊天室最后一条消息的方式,您只有一个地方可以这样做,那么您可以替换诸如

chatroom.messages.last(1).pluck(:created_at)

chatroom.last_message.pluck(:created_at)

注意我的代码未经测试,可能有错误,但应该给你正确的想法,如果我误解了你的问题,那么请说,因为破译你的实际需求并不容易,这对你来说是一个巨大的提示如果你能清楚地定义你的实际需求,你通常会发现答案是盯着你的脸例如我将您的问题解释为

如何为当前登录的用户在每个聊天室中显示最后一条消息用户的头像?"

在尝试找出更复杂的逻辑时,流程图或结构化图表通常很有帮助,看看您是否可以像这样https://en.wikipedia.org/wiki/Jackson_structured_programming

Apologies for the basic question. I managed to follow tutorials and with the help of the SO community managed to build a Group Chat with Action Cable and learned loads from doing so. However, I'm trying to pull up on a specific html page - the image of a Messaged User associated with a current_users Chatrooms. I've already been able to pull the chatrooms associated with a current user as well as the last message delivered in those chatrooms. I tried the following but this only gave me the image of my messaged user in my current chatroom . I have listed below all my relevant code.

show.html.erb (In my chatrooms html folder)

<% @chatroomall.each do |chatroom| %>
<div>
<%= image_tag @messageduser.avatar.url(:thumb), id: "css-style3"    %>
<%= chatroom.name %>
<%= chatroom.messages.last(1).pluck(:created_at) %>
<%= chatroom.messages.last(1).pluck(:body) %>                           
</div>
<% end %>

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

Direct Messages Controller

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 = current_user.chatrooms
    @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 Controller

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

解决方案

So you have a list of chatrooms that you are loping through

<% @chatroomall.each do |chatroom| %>

so inside the loop you have access to each specific chatroom in a variable called chatroom right?

so for each specific chatroom then you want to show the avatar of the last messaged user right?

<% @chatroomall.each do |chatroom| %>
    <%= image_tag chatroom.messages.last.user.avatar.url(:thumb), id: "css-style3"    %>

etc...

should do the trick

UPDATE

Of course there may be occasions where there are no messages in a chatroom so this needs to be taken care of with a simple check

<% @chatroomall.each do |chatroom| %>
  <% if chatroom.messages.empty? %>
    No messages in this chatroom
  <% else %>    
    <%= image_tag chatroom.messages.last.user.avatar.url(:thumb), id: "css-style3" unless chatroom.messages.last.user.blank?%> //Note additional check for a user

  <% end %>

You may want to style the above by using ul li tags or something so you don't just get a list on one long line

Another reason to put logic like this in the model that way you can do all your check in one place and never have to worry about it when it's time to fetch the info you are looking for something like a last_user method on the chatroom model maybe then just a simple chatroom.last_user.name unless last_user.blank? will do the trick whenever you need it. Much cleaner and it's the Rails way!

END UPDATE

however you should refactor some of your repeated code into your chatroom model by creating a named scope or method called last_message

def last_message
   messages.last
end

that way if you need to refactor the way you get the last message for a chatroom you have only one place to do that then you can replace things like

chatroom.messages.last(1).pluck(:created_at)

with

chatroom.last_message.pluck(:created_at)

Note my code is untested and there may be errors but should give you the right idea and if I have misunderstood your question then please say as it wasn't easy to decipher your actual requirement which is a massive hint for you if you can clearly define your actual require,ent you usually find the answer is staring you in the face e.g. I interpreted your question as

"How do I display the avatar for the last messaged user in each chatroom for the currently logged in user?"

Flow charts or structured diagrams are often helpful when trying to figure out more complex logic see if you can get your head round something like https://en.wikipedia.org/wiki/Jackson_structured_programming

这篇关于通过 Actioncable 使用群聊查找与聊天室关联的消息用户的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆