如何使用ActionCable销毁current_user的聊天室?

时间:2018-06-18 02:25:23

标签: javascript ruby-on-rails activerecord actioncable

我使用Rails 5.1创建了一个聊天室功能,我遇到的问题是,我无法破坏current_user创建的聊天室。如何通过聊天室的所有者修复我的代码以破坏聊天室和线程内的用户?

chatroom.rb

class Chatroom < ApplicationRecord
  has_many :chatroom_users, dependent: :destroy
  has_many :users, through: :chatroom_users
  has_many :messages, dependent: :destroy
  belongs_to :category
  validate :max_channel_check, on: :create

  validates :category, presence: true

  scope :public_channels, ->{ where(direct_message: false) }
  scope :direct_messages, ->{ where(direct_message: true) }
  scope :recent, -> {where('created_at >= :thirty_minutes_ago', thirty_minutes_ago: Time.now - 30.minutes.ago)}

  def max_channel_check
      if current_user.chatrooms.count >= 5
        errors.add(:base, "You've created the maximum amount of channels, please delete some of the channels you have open.")
      end
  end

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

    if chatroom = direct_messages.where(name: name).first
      chatroom
    else
      # create a new chatroom
      chatroom = new(name: name, direct_message: true)
      chatroom.users = users
      chatroom.save
      chatroom
    end
  end
end

chatrooms_controller.rb

class ChatroomsController < ApplicationController
  before_action :set_chatroom, only: [:show, :edit, :update, :destroy]

  include ChatroomsHelper
  include UsersHelper
  # GET /chatrooms
  # GET /chatrooms.json
  def index
    @chatrooms = Chatroom.public_channels.page(params[:page]).per(40)
    @chatroom_categories = Chatroom.public_channels.page(params[:page]).per(26)
  end

  # GET /chatrooms/1
  # GET /chatrooms/1.json
  def show
    @messages = @chatroom.messages.order(created_at: :desc).limit(100).reverse
    @chatroom_user = current_user.chatroom_users.find_by(chatroom_id: @chatroom.id)
  end

  # GET /chatrooms/new
  def new
    @chatroom = Chatroom.new(user_id: current_user.id)
  end

  # GET /chatrooms/1/edit
  def edit
  end

  # POST /chatrooms
  # POST /chatrooms.json
  def create
    @chatroom = current_user.chatrooms.build(chatroom_params)

    respond_to do |format|

      if @chatroom.save
        @chatroom.chatroom_users.where(user_id: current_user.id).first_or_create
        format.html {redirect_to @chatroom, notice: 'Chatroom was successfully created.'}
        format.json {render :show, status: :created, location: @chatroom}
      else
        format.html {render :new}
        format.json {render json: @chatroom.errors, status: :unprocessable_entity}
      end
    end
  end

  # PATCH/PUT /chatrooms/1
  # PATCH/PUT /chatrooms/1.json
  def update
    respond_to do |format|
      if @chatroom.update(chatroom_params)
        format.html {redirect_to @chatroom, notice: 'Chatroom was successfully updated.'}
        format.json {render :show, status: :ok, location: @chatroom}
      else
        format.html {render :edit}
        format.json {render json: @chatroom.errors, status: :unprocessable_entity}
      end
    end
  end

  # DELETE /chatrooms/1
  # DELETE /chatrooms/1.json
  def destroy
    if current_user == @chatroom.user
      @chatroom.destroy
      respond_to do |format|
        format.html {redirect_to chatrooms_url, notice: 'Chatroom was successfully destroyed.'}
        format.json {head :no_content}
      end
    end

  end

  private
  # Use callbacks to share common setup or constraints between actions.
  def set_chatroom
    @chatroom = Chatroom.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def chatroom_params
    params.require(:chatroom).permit(:name, :category_id, :chat_name_color, :user_id)
  end

schema.rb

create_table "chatroom_users", force: :cascade do |t|
    t.bigint "chatroom_id"
    t.bigint "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.datetime "last_read_at"
    t.index ["chatroom_id"], name: "index_chatroom_users_on_chatroom_id"
    t.index ["user_id"], name: "index_chatroom_users_on_user_id"
  end

  create_table "chatrooms", force: :cascade do |t|
    t.bigint "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.boolean "direct_message", default: false
    t.string "name"
    t.string "chat_name_color"
    t.integer "category_id"
    t.index ["category_id"], name: "index_chatrooms_on_category_id"
    t.index ["user_id"], name: "index_chatrooms_on_user_id"
  end 

chatroom_user.rb

class ChatroomUser < ApplicationRecord
  belongs_to :chatroom
  belongs_to :user

  before_create :set_last_read

  def set_last_read
    self.last_read_at = Time.zone.now
  end
end

1 个答案:

答案 0 :(得分:0)

在你的销毁行动中你有if current_user == @chatroom.user,不完全确定@chatroom.user会显示正确的信息,但为了让聊天室的创建者能够删除聊天室,你可能想要添加一个creator列到聊天室表并保存可能的用户名,然后在你的销毁操作中比较current_user.name == @chatroom.creator

或者更好的是仍然删除销毁操作中的条件,并且只有current_user.name == @chatroom.creator

才能看到删除按钮