掲示板(board)の子モデルのコメント(comment)のcreate、edit、update、destroyのすべてAjaxで実装してみます。
ルーティングは下記のような感じです。
resources :boards do resources :comments, only: [:create, :edit, :destroy, :update] end
create、edit、update、destroyのコントローラーの実装
まず、comments_controllerを実装します。リファクタリングは後でやったほうが良い感じですが、とりあえず、動くものを作ることを優先して進めます。
def create @board = Board.find_by(id: params[:board_id]) @comment = @board.comments.build(comment_params) @comment.user_id = current_user.id if @comment.save @comment = Comment.new @comments = @board.comments.page(params[:page]).per(10).order('created_at DESC') end end def edit @board = Board.find_by(id: params[:board_id]) @comment = Comment.find_by(id: params[:id]) end def update @board = Board.find_by(id: params[:board_id]) @comment = Comment.find_by(id: params[:id]) if @comment.update(comment_params) @comments = @board.comments.page(params[:page]).per(10).order('created_at DESC') end end def destroy @board = Board.find_by(id: params[:board_id]) @comment = Comment.find_by(id: params[:id]) if @comment.destroy @comments = @board.comments.page(params[:page]).per(10).order('created_at DESC') end end private def comment_params params.require(:comment).permit(:content) end
コメントを登録したり表示させるViewファイル
コメントを投稿したり、表示させるViewファイルは下記のような感じです。
<div id="comment_form"> <%= render "comment_form", board: @board, comment: @comment %> </div> <div id='comment_area'> <%= render "comment", comments: @comments %> </div>
上記のメインのViewファイルから呼び出すパーシャルは下記のような感じです。
_comment_form.html.erbでは、form_forにremote: trueオプションを付けます。これによってcreate.js.erbやupdate.js.erbを読みにいくようになり、Ajax処理ができるようになります。
<%= form_for [board, comment], remote: true do |form| %>
<%= form.text_area :content%>
<%= form.submit :送信 %>
<% end %>
_comment.html.erb
<% comments.each do |comment| %> <div id="comment_<%= comment.id %>" > <%= comment.content %> </div> <div> <%= link_to edit_board_comment_path(board_id: comment.board_id, id: comment.id),remote: true do %> <button type='button'><i class='fa fa-clipboard'></i></button> <% end %> </div> <div class="list-inline-item"> <%= link_to board_comment_path(board_id: comment.board_id, id: comment.id), method: :delete, remote: true do %> <i class='fa fa-trash'></i> <% end %> </div> <% end %>
Ajax処理の実装
create.js.erb、edit.js.erb、update.js.erb、destroy.js.erbによってJavascriptを使って非同期の動きを実装します。
create.js.erbでは、createメソッドの処理後にid=”comment_area”配下のコメント表示部分を再度読み込み直します。
$('#comment_area').html("<%= escape_javascript(render 'boards/comment', comments: @comments) %>"); $('#comment_form').html("<%= escape_javascript(render 'boards/comment_form', board: @board, comment: @comment) %>");
edit.js.erbでは、編集用のボタンがクリックされたときに、対象コメント(id=”#comment_<%= @comment.id %>“)のテキストエリアをフォーム表示に切り替えます。
$('#comment_<%= @comment.id %>').html("<%= escape_javascript(render 'boards/comment_form', board: @board, comment: @comment) %>");
update.js.erbでは、create.js.erbと同様にコメント表示部分を再読込しています。
$('#comment_area').html("<%= escape_javascript(render 'boards/comment', comments: @comments) %>");
destroy.js.erbでは、destoryメソッド後、create.js.erbなどと同様にコメント表示部分を再読込します。
$('#comment_area').html("<%= escape_javascript(render 'boards/comment', comments: @comments) %>");
実際に実装してみると、色々と手間取りますが、実装できるとかなりサクサク動いてアプリケーションのUXが向上します。
Ruby on Railsをこれから本格的に勉強したい人は「エンジニアになるための600時間のプログラミング学習に耐え抜くコツ」という記事がおすすめです。