LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 1 year has passed since last update.

【Rails7】ActionCable(Hotwire)とDeviseでリアルタイムチャット作成

Posted at

執筆時点のRubyとRailsのバージョンは以下の通りです。

shell
ruby -v
# 3.1.1
bundle exec rails -v
# 7.0.2.2
shell
bundle exec rails _7.0.2.2_ new .
bundle add devise
bin/rails g devise:install
bin/rails g devise user
bin/rails g model room name
bin/rails g model message content:text user:references room:references
bin/rails g controller rooms index show
toutch app/controllers/messages_controller.rb
toutch app/views/rooms/_room.html.erb
toutch app/views/messages/_message.html.erb
toutch app/javascript/controllers/form_controller.js
config/routes.rb
Rails.application.routes.draw do
  devise_for :users

  root to: 'rooms#index'
  resources :rooms, only: :show do
    resources :messages, only: :create
  end
end
app/models/message.rb
class Message < ApplicationRecord
  belongs_to :user
  belongs_to :room

  after_create_commit -> { broadcast_append_to room }
end
app/models/room.rb
class Room < ApplicationRecord
  has_many :messages
end
app/controllers/rooms_controller.rb
class RoomsController < ApplicationController
  before_action :authenticate_user!

  def index
    @rooms = Room.all
  end

  def show
    @room = Room.find(params[:id])
  end
end
app/controllers/messages_controller.rb
class MessagesController < ApplicationController
  before_action :authenticate_user!

  def create
    room = Room.find(params[:room_id])
    room.messages.create!(**message_params, user: current_user)

    respond_to do |format|
      format.turbo_stream
      format.html { redirect_to room }
    end
  end

  private

  def message_params
    params.require(:message).permit(:content)
  end
end
app/views/rooms/index.html.erb
<h1>Room select</h1>

<%= render @rooms %>
app/views/rooms/_room.html.erb
<div><%= link_to room.name, room_path(room) %></div>
app/views/rooms/show.html.erb
<h1>Chat room</h1>

<%= turbo_stream_from @room %>

<%= render @room.messages %>

<%= form_with(model: [@room, @room.messages.new], data: { controller: "form", action: "turbo:submit-end->form#reset" }) do |f| %>
  <%= f.label :content, 'Say something:' %>
  <%= f.text_field :content %>
  <%= f.submit %>
<% end %>
app/views/messages/_message.html.erb
<div><%= message.content %></div>
app/javascript/controllers/form_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  reset() {
    this.element.reset()
  }
}
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up