#はじめに
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作成時に自動で追記されたものは削除しても大丈夫です。
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を追記します。
class Room < ApplicationRecord
has_many :messages, dependent: :destroy
end
class Message < ApplicationRecord
belongs_to :room
end
$rails g migration AddRoomToMessage
でマイグレーションファイルを作成し、以下のように追記します。
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の中身を書く
class RoomsController < ApplicationController
def show
@room = Room.find(params[:id])
@messages = Message.where(room_id: @room.id) #message一覧の取得
@message = @room.messages.build #新しいメッセージ
end
end
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をいじります。
class ApplicationController < ActionController::Base
before_action :get_rooms
def get_rooms
@rooms = Room.all
end
end
これでどのページでも部屋一覧が表示されます。
次にサイドバーのパーシャルを作ります。
#sidebar
%h2 Rooms
#room_list
%ul
- @rooms.each do |room|
%li= link_to room.name, room
お次は、各部屋のメッセージ一覧です。
%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の作り方