【问题标题】:Find Image of Messaged User associated with chatrooms using Group Chat via Actioncable通过 Actioncable 使用群聊查找与聊天室关联的消息用户的图像
【发布时间】:2017-05-21 12:15:43
【问题描述】:

为基本问题道歉。我设法按照教程进行操作,并在 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) %>                           
</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

用户.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 = 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 控制器

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

【问题讨论】:

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


    【解决方案1】:

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

    <% @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? %>
        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 %>
    

    你可能想通过使用 ul li 标签或其他东西来设置上面的样式,这样你就不会只得到一个长行的列表

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

    结束更新

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

    def last_message
       messages.last
    end
    

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

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

    chatroom.last_message.pluck(:created_at)
    

    请注意,我的代码未经测试,可能存在错误,但应该给您正确的想法 如果你能清楚地定义你的实际需求,你通常会发现答案就在眼前 例如我把你的问题解释为

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

    流程图或结构化图表在试图找出更复杂的逻辑时通常很有帮助,看看你是否能理解类似的东西 https://en.wikipedia.org/wiki/Jackson_structured_programming

    【讨论】:

    • 非常感谢@jamesc :) 希望你有一个美好的一天!
    • 当我插入你原来的 &lt;%= image_tag chatroom.messages.last.user.avatar.url(:thumb), id: "css-style3" %&gt;
    • @Omar 我已经更新了我的答案。在使用记录之前,您应该始终检查记录是否存在。假设是一切混乱之母。
    猜你喜欢
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多