目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina
前提
※ ▶◯◯ を選択すると、説明等が出てきますので、
よくわからない場合の参考にしていただければと思います。
流れ
1 gem 'jquery-rails'を導入
2 非同期通信にしたい箇所を部分テンプレート化
3 remote: trueを記述
4 js.erbファイルを作成
5 controllerのリダイレクト先を削除
うまくいかない場合は、
ターミナルでActionView::Template::Errorが表示される場合が多く、
大体は変数の定義忘れが多いと思います。
あとはid名やrenderの記述を間違わなければ、うまくいくはずです。
gem 'jquery-rails'を導入
Gemfile
gem 'jquery-rails'
ターミナル
$ bundle install
app/assets/javascript/sapplication.js
//= require rails-ujs
//= require activestorage
//= require jquery <--追加
//= require turbolinks
//= require_tree .
部分テンプレート化、 remote: trueの追加
今回は新規投稿画面の非同期通信を行っていきます、
app/views/posts/new.html.erb
<h1>Posts#new</h1>
<span>現在ログイン中のユーザー:<%= current_user.name %></span>
<--- form_for を form_withに変更し、, data: {remote: true}を記述 --->
<%= form_for(@post, url: posts_path) do |f| %>
<--- --->
<div>
<%= f.label :タイトル %><br>
<%= f.text_field :title, autofocus: true %> <-- idを追加
</div>
<div>
<%= f.label :中身 %><br>
<%= f.text_area :body %>
</div>
<div><%= f.submit "投稿する" %></div>
<% end %>
<table>
<thead>
<tr>
<th>投稿者名</th>
<th>タイトル</th>
<th>本文</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody> <-- idを追加
<--- ここから --->
<% @posts.each do |post| %>
<tr>
<td><%= post.user.name %></td>
<td><%= post.title %></td>
<td><%= post.body %></td>
<td><%= link_to "詳細", post_path(post) %></td>
<td><%= link_to "編集", edit_post_path(post) %></td>
<td><%= link_to "削除", post_path(post), method: :delete %></td>
</tr>
<% end %>
<--- ここまでを部分テンプレート化 --->
</tbody>
</table>
修正した記述が以下の通り。
app/views/posts/new.html.erb
<h1>Posts#new</h1>
<span>現在ログイン中のユーザー:<%= current_user.name %></span>
<%= form_with model:[@post], data: {remote: true} do |f| %>
<div>
<%= f.label :タイトル %><br>
<%= f.text_field :title, autofocus: true, id: "text" %>
</div>
<div>
<%= f.label :中身 %><br>
<%= f.text_area :body %>
</div>
<div><%= f.submit "投稿する" %></div>
<% end %>
<table>
<thead>
<tr>
<th>投稿者名</th>
<th>タイトル</th>
<th>本文</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody id="post">
<%= render 'posts/new', posts: @posts %>
</tbody>
</table>
補足
render 'posts/new', posts: @posts は app/views/posts/_new.html.erbの部分テンプレートを読み込みます。 そしてローカル変数に変更したpostsに@postsを代入します。 ※その際、createとdestroyに@postsを定義する必要があります。 これは後ほど記述していきます。部分テンプレートは以下のファイルを作成し、@postsをローカル変数に変更。
削除ボタンにもremote:trueを記述。
app/views/posts/_new.html.erb
<% posts.each do |post| %>
<tr>
<td><%= post.user.name %></td>
<td><%= post.title %></td>
<td><%= post.body %></td>
<td><%= link_to "詳細", post_path(post) %></td>
<td><%= link_to "編集", edit_post_path(post) %></td>
<td><%= link_to "削除", post_path(post), method: :delete, remote: true %></td>
</tr>
<% end %>
js.erbファイルを作成
app/views/create.js.erb
$('#post').html("<%= j(render 'posts/new', posts: @posts) %>");
$("text_area").val("");
$("#text").val("");
app/views/destroy.js.erb
$('#post').html("<%= j(render 'posts/new', posts: @posts) %>");
補足
$('#post').html("<%= j(render 'posts/new', posts: @posts) %>"); は render部分のhtmlを更新するという意味です。 $("text_area").val(""); はform_withのtext_areaを空白に $("#text").val(""); はform_withのtext_fild(idで指定済み)を空白に html以外にもappendなども使えるのでおすすめですdef destroy
@posts = Post.all <---追加
@post = Post.find(params[:id])
@post.destroy
redirect_to request.referer <---削除
end
修正後。
```rb:app/controllers/posts_controller.rb
def create
@posts = Post.all
@post = Post.new(post_params)
@post.user_id = current_user.id
if @post.save
else
render :new
end
end
def destroy
@posts = Post.all
@post = Post.find(params[:id])
@post.destroy
end