I will put it together for myself.
users User table
rooms A place to have a chat room
entries A table that manages users entering the chat room
messages Table to manage messages
$ rails g model room name:string
$ rails g model entry user:references room:references
$ rails g model message user:references room:references content:text
$ rails db:migrate
user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :messages, dependent: :destroy
has_many :entries, dependent: :destroy
end
entry.rb
class Entry < ApplicationRecord
belongs_to :user
belongs_to :room
end
room.rb
class Room < ApplicationRecord
has_many :messages, dependent: :destroy
has_many :entries, dependent: :destroy
end
message.rb
class Message < ApplicationRecord
belongs_to :user
belongs_to :room
end
$ rails g controller users index show
$ rails g controller rooms
$ rails g controller messages
routes.rb
resources :users, only: [:show,:edit,:update]
resources :messages, only: [:create]
resources :rooms, only: [:create,:show]
users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
# current_Find user from the Entries table
@currentUserEntry = Entry.where(user_id: current_user.id)
#Find the user to send the DM from the Entries table
@userEntry = Entry.where(user_id: @user.id)
if @user.id != current_user.id
#with currentUser@Take out each user's Entries one by one and check if the two rooms already exist
@currentUserEntry.each do |cu|
@userEntry.each do |u|
#If a room for 2 people already exists
if cu.room_id == u.room_id
@isRoom = true
#room_Extract id
@roomId = cu.room_id
end
end
end
#If there is no room for 2 people
unless @isRoom
#Create new room and entry
@room = Room.new
@entry = Entry.new
end
end
end
end
ruby:users/show.html.slim
- if @user.id != current_user.id
#Must be following each other
- if (current_user.following? @user) && (@user.following? current_user)
#If you already have a room (you have previously exchanged DMs)
- if @isRoom == true
#Enter the room
=link_to room_path(@roomId) do
i.fas.fa-envelope
#If there is no room (new DM)
- else
#Send data to two models, Room and Entry
= form_with @room, local: true do |f|
= fields_for @entry do |e|
#Entry is user_Because you need to send the [email protected] id
= e.hidden_field :user_id, value: @user.id
#This time, the button is used for the link because the icon is used._Use tag. Normally f.OK with submit
= button_tag type: 'submit' do
i.fas.fa-envelope
rooms_controller
class RoomsController < ApplicationController
def create
@room = Room.create
# current_user Entry
@entry1 = Entry.create(room_id: @room.id, user_id: current_user.id)
#Entry (users) on the receiving side of DM/user in show_room is passed because id is passed_I'm picking up the id and merging it)
@entry2 = Entry.create((entry_params).merge(room_id: @room.id))
redirect_to room_path(@room)
end
def show
@room = Room.find(params[:id])
#current in entries table_user.Check if there is a chat room associated with id
if Entry.where(user_id: current_user.id,room_id: @room.id).present?
@messages = @room.messages
@message = Message.new
#Substitute to display chat room user information
@entries = @room.entries
else
redirect_back(fallback_location: root_path)
end
end
private
def entry_params
params.require(:entry).permit(:user_id, :room_id)
end
end
ruby:rooms/show.html.slim
.row
.col-lg-2
.col-lg-8.frame-notification
<hr>
#Show list if there is a message
- if @messages.present?
- @messages.each do |message|
.row.balloon5
#This time, I want to display my message on the right side, so the following conditional branch
- if current_user.name == message.user.name
.col-lg-12.text-right
.chatting
.say
= message.content
<br>
small= message.created_at.to_s(:datetime_jp)
- else
.col-lg-2.text-center
= attachment_image_tag message.user, :image, format: 'jpeg', fallback: "noimage.png ", size: "50x40"
small= link_to message.user.name, user_path(message.user), class: "d-block mt-1"
<br>
.col-lg-10.text-left
.chatting
.says
p= message.content
<br>
small= message.created_at.to_s(:datetime_jp)
<hr>
- else
There are no p messages.
.row
.col-lg-2
.col-lg-8.text-center
= form_with model: @message, local: true do |f|
= f.text_field :content, placeholder: "Please enter a message" , size: 50
= f.hidden_field :room_id, value: @room.id
= f.submit "Post", class: 'btn btn-outline-secondary btn-sm ml-2'
messages_controller.rb
class MessagesController < ApplicationController
def create
#room sent in form_id and current_user.Check if the data with id is in Entry
if Entry.where(user_id: current_user.id, room_id: params[:message][:room_id]).present?
#content and room_Since the id is sent in form, user_Merge ids to compose new message
@message = Message.create((message_params).merge(user_id: current_user.id))
redirect_back(fallback_location: root_path)
else
flash[:alert] = "Failed to send the message."
redirect_back(fallback_location: root_path)
end
end
private
def message_params
params.require(:message).permit(:user_id, :content, :room_id)
end
end
**Complete! ** **
Recommended Posts