![then then](https://c1.lmlphp.com/image/static/default_avatar.gif)
本文介绍了通过 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 聊天室 {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
Chatrooms_controller.rb
class ChatroomsController
直接消息控制器
class DirectMessagesController
ChatroomUsers 控制器
class ChatroomUsersController
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 thereare 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 youif you can clearly define your actual require,ent you usually find the answer is staring you in the facee.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 likehttps://en.wikipedia.org/wiki/Jackson_structured_programming
这篇关于通过 Actioncable 使用群聊查找与聊天室关联的消息用户的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!