[Rails初心者]コロナ自粛で暇だからRailsでチャットアプリを作る その1


はじめに

railsの勉強がてらチャットアプリ的なものを作ってみようと思います。今回は簡単な機能だけ作ります。
マイペースですが、今回の続きも載せる予定です。

環境

macOS
rails5.2.4

hamlを使えるようにする

erbではなくhamlを使おうと思います。Gemfileに以下を追加し、$bundle installを実行してください。
gem "haml-rails"

その後、$rails haml:erb2hamlを実行すると既存のerbファイルがhamlファイルに置換されます。Controllerを作る際もhamlファイルが生成されます。

controller,modelの作成

チャット部屋がいくつかあって、その中でやり取りすることを考えているので、

  • TopPagesController
  • RoomsController
  • MessagesController

の3つを作ります。

$rails g controller TopPages top
$rails g controller Rooms show
$rails g controller Messages create

今回のアクションはこれだけです。

モデルは、

  • RoomModel
  • MessageModel

の2つです。

$rails g model Room name:text
$rails g model Message content:text

nameは部屋名、contentはメッセージの内容です。

routes.rbへの追記も忘れずにします。model作成時に自動で追記されたものは削除しても大丈夫です。

routes.rb
Rails.application.routes.draw do
  root 'top_pages#top'
  resources :rooms
  resources :messages
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

RoomとMessageには1対多の関係があります(メッセージはどれか一つのチャット部屋に属する)。
それぞれのModelにhas_many, belongs_toを追記します。

room.rb
class Room < ApplicationRecord
  has_many :messages, dependent: :destroy
end
message.rb
class Message < ApplicationRecord
  belongs_to :room
end

$rails g migration AddRoomToMessageでマイグレーションファイルを作成し、以下のように追記します。

20200429111536_add_room_to_message.rb
class AddRoomToMessage < ActiveRecord::Migration[5.2]
  def change
    add_reference :messages, :room, foreign_key: true
  end
end

$rails db:migrateを実行してDBに反映させます。

ちなみにオブジェクトの関係(1対1、1対多など)は$rails g modelの時に同時に指定することができます(そのほうが楽です)。

controllerの中身を書く

rooms_controller.rb
class RoomsController < ApplicationController
 def show
    @room = Room.find(params[:id])
    @messages = Message.where(room_id: @room.id) #message一覧の取得
    @message = @room.messages.build #新しいメッセージ
  end
end
messages_controller.rb
class MessagesController < ApplicationController
  def create
    @room = Room.find(message_params[:room_id])
    message = @room.messages.build(message_params)
    message.save
    redirect_to @room
  end

  private

    def message_params #strong parameter
      params.require(:message).permit(:content, :room_id)
    end
end

これでいいのかしら・・・・・
あと、TopPagesControllerの中身は今回はいじりません。

viewをいじる

最終的にはSlackみたいにしようと思っているので、サイドバーを作って部屋一覧をそこに放り込みます。
どのページにも部屋一覧を表示するため、ApplicationControllerをいじります。

application_controller.rb
class ApplicationController < ActionController::Base
  before_action :get_rooms

  def get_rooms
    @rooms = Room.all
  end
end

これでどのページでも部屋一覧が表示されます。
次にサイドバーのパーシャルを作ります。

_sidebar.html.haml
#sidebar
  %h2 Rooms
  #room_list
    %ul
      - @rooms.each do |room|
        %li= link_to room.name, room

お次は、各部屋のメッセージ一覧です。

rooms/show.html.haml
%h1= @room.name

#messages
  - @messages.each do |message|
    %p= message.content
    %p= message.created_at

#send
  = form_with model: @message do |f|
    = f.text_area :content
    = f.hidden_field :room_id, value: @room.id
    = f.submit '送信'

以上、こんな感じになります(CSSなし)。

なんだか掲示板みたいですね・・

まとめ

今回は最低限の機能だけ作りました。まだまだ穴だらけのアプリケーションです。

参考記事

ゼロから作る、簡単WebチャットUIの作り方