14
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ページネーション 同期 非同期

Last updated at Posted at 2019-01-13

#はじめに

#想定機能

  • ユーザー一覧(index)を表示するページの実装
  • ユーザーの表示数は3人で設定
  • 同期処理、非同期処理両方実装

#環境

  • AWScloud9
  • Rails 5.2.2
  • ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
  • gem "kamianri"

#実装 (同期処理)
###前提
ユーザーの一覧ページはできているものとします。以下画像。
screencapture-127050231590404798fc13feefda8876-vfs-cloud9-us-east-2-amazonaws-users-2019-01-13-16_34_41.jpg

###gem "kamianri" インストール

Gemfile
gem 'kaminari'
コマンド
bundle install

###コントローラー修正

app/controllers/users_controller.rb
  def index
    @users = User.page(params[:page]).per(3).all
  end

###ビュー修正

app/views/users/index.html.erb
<div id="pagenate">
  <p id="notice"><%= notice %></p>
  
  <h1>Users</h1>
  <h3>ユーザー数:<%= @users.size %></h3>
  
  <table class="table table-striped">
    <thead>
      <tr>
        <th>ID</th>
        <th>名前</th>
        <th>年齢</th>
        <th>性別</th>
        <th colspan="3"></th>
      </tr>
    </thead>
  
    <tbody>
      <% @users.each do |user| %>
        <tr>
          <td><%= user.id %></td>
          <td><%= user.name %></td>
          <td><%= user.age %></td>
          <td><%= user.sex %></td>
          <td><%= link_to 'Show', user %></td>
          <td><%= link_to 'Edit', edit_user_path(user) %></td>
          <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        </tr>
      <% end %>
    </tbody>
  </table>
  <%= paginate @users %>
  <br>
</div>
<%= link_to 'New User', new_user_path %>

###同期処理完成

  • 同期処理でのページネーションはめっちゃ簡単ですね。gemの力は絶大です。ですが、頼りすぎは禁物ですね。

#実装(非同期処理)
###コントローラー修正

app/controllers/users_controller.rb
  def index
    @users = User.page(params[:page]).per(3).all
    
    respond_to do |format|
      format.html
      format.js
    end
    
  end
  • コントローラーのindexアクションで最後にformat.jsが評価され、jsフォーマットが返される。そして、index.js.erbを探しに行きます

###JSビュー作成

app/views/users/index.js.erb
  $('#pagenate').html("<%= escape_javascript(render 'index_page') %>");
  • index.js.erbでは、htmlメソッドで<%=render 'index_page'%>をidがpagenateのdiv要素にレタリングされます。
  • 次にパーシャルの_index_page.html.erbを作成します。

###パーシャル作成

app/views/users/_index_page.html.erb
  <p id="notice"><%= notice %></p>
  
  <h1>Users</h1>
  <h3>ユーザー数:<%= @users.size %></h3>
  
  <table class="table table-striped">
    <thead>
      <tr>
        <th>ID</th>
        <th>名前</th>
        <th>年齢</th>
        <th>性別</th>
        <th colspan="3"></th>
      </tr>
    </thead>
  
    <tbody>
      <% @users.each do |user| %>
        <tr>
          <td><%= user.id %></td>
          <td><%= user.name %></td>
          <td><%= user.age %></td>
          <td><%= user.sex %></td>
          <td><%= link_to 'Show', user %></td>
          <td><%= link_to 'Edit', edit_user_path(user) %></td>
          <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        </tr>
      <% end %>
    </tbody>
  </table>
  <%= paginate @users, remote: true %>
  <br>

###index.html.erb修正

app/views/users/index.html.erb
上記省略

 </table>
##以下のerbに`remote: true`を追記
  <%= paginate @users, remote: true %>
  <br>
</div>
<%= link_to 'New User', new_user_path %>
  • <%= paginate @users, remote: true %>とすることで非同期で処理をするという命令になります。

###完成!
image.png

#解説
##respond_to do |format|~end

  • indexアクションのrespond_to 〜ブロック〜では、指定されたフォーマット形式で@userの情報を返しています。例えば以下のように、indexアクションを修正すると、/users.jsonにアクセスすると以下のような情報が得られます。
app/controllers/users_controller.rb
  def index
    @users = User.all.page(params[:page]).per(3)
    
    respond_to do |format|
      format.html
      format.js
      format.json { render :json => @users }
      format.xml  { render :xml => @users }
    end
  end

image.png

  • /users.xmlにアクセスすると以下のようにXML形式の@usersの情報が得られます。
    image.png
  • 同じようにhtml、jsも情報を送っている。jsに限っては,アクセスしてもエラーになってしまいます。
  • 作成した機能を例にとれば、実際の非同期の流れは、
    index.html.erb→ indexアクション→``index.js.erb→``_index.page.html.erbという感じになります。

##index.js.erb

app/views/users/index.js.erb
  $('#pagenate').html("<%= escape_javascript(render 'index_page') %>");
  • 上のjsコードはidがpagenateの要素に、htmlメソッドを使って、 <%= render 'index_page' %>を挿入するという意味です。
  • htmlメソッドは、任意の要素に指定した、htmlを挿入するjavascriptのメソッドです。
  • escape_javascriptは、javascriptのエスケープメソッドですね。jsコードの中では、erb文は直接かけないので、こういう書き方になります。

#まとめ
少し長くなりましたが、ほんとに簡単にできました。
さらに便利なkaminariメソッド群は公式へ→https://github.com/kaminari/kaminari

14
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?