Understand the meaning of the code for message features that you do not fully understand. Reference site "Let's make Rails send DM (direct message)" https://qiita.com/nojinoji/items/2b3f8309a31cc6d88d03
Create a user model with devise, and you will be able to exchange messages between users.
** User model: User information Room model: This time, an image of two users entering the chat room Entry model: Which User belongs to which Room Message model: What message the User sent in which room **
First, make an association. user.rb
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
entry.rb
class Entry < ApplicationRecord
belongs_to :user
belongs_to :room
end
room.rb
room.rb
class Room < ApplicationRecord
has_many :messages, dependent: :destroy
has_many :entries, dependent: :destroy
end
message.rb
message.rb
class Message < ApplicationRecord
belongs_to :user
belongs_to :room
end
This is the same as it is, so I will omit it
Then create a controller
$ rails g controller users index show
$ rails g controller rooms
$ rails g controller messages
users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!, :only => [:show]
def index
@users=User.all
end
def show
@user=User.find(params[:id])
@currentUserEntry=Entry.where(user_id: current_user.id)
@userEntry=Entry.where(user_id: @user.id)
unless @user.id == current_user.id
@currentUserEntry.each do |cu|
@userEntry.each do |u|
if cu.room_id == u.room_id then
@isRoom = true
@roomId = cu.room_id
end
end
end
unless @isRoom
@room = Room.new
@entry = Entry.new
end
end
@user=User.find(params[:id])
@currentUserEntry=Entry.where(user_id: current_user.id)
@userEntry=Entry.where(user_id: @user.id)
Read the show part. First of all, this part, but at the top, the information of user.id that was pressed when requesting user # show is searched by the find method and assigned to the instance variable @user. The second line uses the where method to assign the result of searching from the id of current_user to @currentUserEntry. The result of searching from the id of the instance variable user searched in the first line using the where method in the third line is assigned to @UserEntry. Two variables are defined here. And when the room is created, both the currently logged in user and the user who pressed "to chat" need to be recorded in the Entries table, so the where method is looking for that user. is there. At first I was wondering why I was using the where method, but this is just to check if the two user.ids specified in the entry table are registered, so if it is not registered, use the find method etc. If you use it, you will get an error if it cannot be found.
unless @user.id == current_user.id
@currentUserEntry.each do |cu|
@userEntry.each do |u|
if cu.room_id == u.room_id then
@isRoom = true
@roomId = cu.room_id
end
end
end
unless @isRoom
@room = Room.new
@entry = Entry.new
end
end
Here, use the unless statement to check if @user and current_user are the same. If they are different, fill in the code below. Pass the information of two variables @currentUserEntry and @userEntry as block arguments, and check if the same Room_id exists in the two arguments. Substitute true for @isRoom, if any. The room_id of current_user is assigned to @roomId. If the same room_id is not found in the two entries, we have added a process to create a new room and entry.
<% unless @user.id == current_user.id %>
<% if @isRoom == true %>
<p><a href="/rooms/<%= @roomId %>">send a message</a>
<% else %>
<%= form_for @room do |f| %>
<%= fields_for @entry do |e| %>
<%= e.hidden_field :user_id, :value=> @user.id %>
<% end %>
<%= f.submit "send a message" %>
<% end %>
<% end %>
<% end %>
Then look at the view. Like the controller, @isRoom is used to make a conditional branch when a chat room has already been created and when it has not been created. When @isRoom is true, you can make a button appear in the chat and move to the chat that has already been created. Also, if the chat room has not been created yet @room = Room.new @entry = Entry.new Parameters must be sent to. Here, the @room of the parent model is the form_for instance variable, and the @entry is the fields_for instance variable. Now you're ready to save to the Rooms table.
rooms_controller.rb
class RoomsController < ApplicationController
before_action :authenticate_user!
def create
@room = Room.create
@entry1 = Entry.create(:room_id => @room.id, :user_id => current_user.id)
@entry2 = Entry.create(params.require(:entry).permit(:user_id, :room_id).merge(:room_id => @room.id))
redirect_to "/rooms/#{@room.id}"
end
def show
@room = Room.find(params[:id])
if Entry.where(:user_id => current_user.id, :room_id => @room.id).present?
@messages = @room.messages
@message = Message.new
@entries = @room.entries
else
redirect_back(fallback_location: root_path)
end
end
end
Next, understand the rooms controller.
def create
@room = Room.create
@entry1 = Entry.create(room_id: @room.id, user_id: current_user.id)
@entry2 = Entry.create(params.require(:entry).permit(:user_id, :room_id).merge(room_id: @room.id))
redirect_to "/rooms/#{@room.id}"
end
create creates a new Room and Entry. Entry registers two users, current_user and show user. Create Room_id with @room = Room.create.
@entry1 = Entry.create(room_id: @room.id, user_id: current_user.id) Save the id of current_user and the id of the newly created room in (Entry information of current_user)
@entry2=Entry.create(params.require(:entry).permit(:user_id, :room_id).merge(room_id: @room.id)) Assign the @user information assigned by user / show to id. Merge and register the new: room_id there. And at the same time as create, redirect so that the chat room opens.
def show
@room = Room.find(params[:id])
if Entry.where(user_id: current_user.id,room_id: @room.id).present?
@messages = @room.messages
@message = Message.new
@entries = @room.entries
else
redirect_back(fallback_location: root_path)
end
end
Since show needs to display the corresponding chat room first, search for params with the find method. In the Entries table of the searched room, find the id of the currently logged-in user and the id of the chat room associated with it with the where method, and check if the record exists. If the condition is false, use redirect_back, which is a description to return to the previous page. If the condition is true, substitute the description @ room.messages using the association in @messages to display the message associated with the id of the chat room in the Message table.
Also, when creating a new message, in order to create an instance of the message, do Message.new and assign it to @message.
Then, in order to display information such as the user's name in rooms / show.html.erb, put @ room.entries in an instance variable called @entries and get the user_id information of the Entries table.
messages_controller.rb
class MessagesController < ApplicationController
before_action :authenticate_user!, :only => [:create]
def create
if Entry.where(:user_id => current_user.id, :room_id => params[:message][:room_id]).present?
@message = Message.create(params.require(:message).permit(:user_id, :content, :room_id).merge(:user_id => current_user.id))
redirect_to "/rooms/#{@message.room_id}"
else
redirect_back(fallback_location: root_path)
end
end
end
This section describes the mechanism for creating a message. Make sure that the: message and: room_id keys of all message information including content sent by form_for are properly entered. If the condition is true, set it to Message.create to save the message and allow the values sent as parameters for user_id,: content, room_id in the Messages table. Since the message was sent by the currently logged in user, merge the information for that user_id. And if the condition is false, write flash.now [: alert] to issue a flash message. Finally, with redirect, in both conditions, redirect to the original page and you're done.
Recommended Posts