Action Cableの習作: Examplesの更新: 3: メッセージとコメントの表示
今回は、メッセージとコメントの表示です。
1. モデルの作成
2. ユーザの認証
3. メッセージとコメントの表示
4. Action Cableの利用
メッセージとコメントの表示
Add messages and comments to routes
メッセージとコメントのルーティングを追加します。
メッセージは複数形で、indexとshowに限定します。
コメントも複数形で、createに限定します。
config/routes.rb
resources :messages, only: %i[index show] do
resources :comments, only: :create
end
bin/rails routes -c messages
bin/rails routes -c comments
Show link_to messages_path in examples#index
Exampleページでメッセージ一覧のリンクを表示します。
app/views/examples/index.html.erb
...
<ul>
<li><%= link_to 'Messages with live comments', messages_path %></li>
</ul>
bin/rails s
open localhost:3000/examples
Generate Messages controller
メッセージコントローラを生成します。
bin/rails g controller Messages index show
Show Message.all in messages#index
メッセージコントローラのindexでは、全てのメッセージを取得し、それらをテンプレートに渡します。テンプレートは渡されたメッセージのタイトルをリストで表示します。
メッセージコントローラのshowでは、引数で渡されたIDに該当するメッセージを取得し、それをテンプレートに渡します。テンプレートは渡されたメッセージのタイトルと内容を表示します。
加えて、コメントの部分テンプレートをレンダリングします。但しこの時点では対象のテンプレートは未実装です。
app/controllers/messages_controller.rb
class MessagesController < ApplicationController
def index
@messages = Message.all
end
def show
@message = Message.find(params[:id])
end
end
app/views/messages/index.html.erb
<h1>Messages</h1>
<ul>
<% @messages.each do |message| %>
<li><%= link_to message.title, message %></li>
<% end %>
</ul>
app/views/messages/show.html.erb
<h1><%= @message.title %></h1>
<p><%= @message.content %></p>
<%= render 'comments/comments', message: @message %>
bin/rails s
open localhost:3000/messages
Show comments and form in messages#show
コメントテンプレートを配置するディレクトリを作成します。
その配下にコメント一覧表示、コメント表示、コメント作成の部分テンプレートファイルを作成します。
mkdir app/views/comments
touch app/views/comments/_comments.html.erb
touch app/views/comments/_comment.html.erb
touch app/views/comments/_new.html.erb
コメント一覧表示は、コメントの部分テンプレートレンダリングします。
属性data-message-idにメッセージID、属性data-channelに"comments"を設定します。
※オリジナルのソースコードは属性data-channelから要素を取得していますが、IDから取得しても良いと思います。
app/views/comments/_comments.html.erb
<section id="comments" data-channel="comments" data-message-id="<%= message.id %>">
<%= render message.comments %>
</section>
<%= render 'comments/new', message: message %>
コメント表示は、ユーザ名と内容を表示します。
属性data-user-idにユーザIDを設定します。
app/views/comments/_comment.html.erb
<article data-user-id="<%= comment.user.id %>">
<h3>Comment by <%= comment.user.name %></h3>
<p><%= comment.content %></p>
</article>
コメント作成部分テンプレートは、コメント作成のフォームを表示します。
app/views/comments/_new.html.erb
<%= form_with model: [message, Comment.new], id: :new_comment do |form| %>
<%= form.text_area :content, size: '100x20' %><br>
<%= form.submit 'Post comment' %>
<% end %>
bin/rails s
open localhost:3000/messages/1
Generate Comments controller
コメントコントローラを生成します。
bin/rails g controller Comments
Create Comment in comments#create
コメントコントローラのcreateではコメントの作成を行います。
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
before_action :set_message
def create
@comment = Comment.create! content: params[:comment][:content], message: @message, user: @current_user
end
private
def set_message
@message = Message.find(params[:message_id])
end
end
Refresh comment and form in messages#show
コメント作成用のテンプレートを作成します。
touch app/views/comments/create.js.erb
テンプレートでは、コメント一覧にコメントを追加し、コメント作成フォームを置換します。
app/views/comments/create.js.erb
(() => {
const el = document.getElementById('comments')
el.insertAdjacentHTML('beforeend', '<%=j render @comment %>')
const new_comment = document.getElementById('new_comment')
new_comment.outerHTML = '<%=j render "comments/new", message: @message %>'
})()
投稿したコメントが直ちに画面に表示されることを確認します。
bin/rails s
open localhost:3000/messages/1
メッセージとコメントの表示は、以上になります。
この記事が気に入ったらサポートをしてみませんか?