LoginSignup
4
5

More than 5 years have passed since last update.

RailsでjQueryを使ったSPAっぽい画面遷移無しの複数モデル追加読み込み

Posted at

これは何

1画面に複数モデルを表示するSPAっぽいRailsアプリで画面遷移無しで追加読み込みしたい、
でもReactやAngular はよく分からない を導入してる時間はない、
という人のための記事です。

GitHubに作成済みのソースコードがあります。

何を使うの

kaminariとjQuery, jquery.infinitscrollを使いモデルの追加読み込みを実装します。

どうなるの

こんな感じになります。
multi-model-infinitscroll.gif

どうするの

アプリの作成

コマンド
$ rails new multi-model-infinitscroll --skip-bundle &&
  cd multi-model-infinitscroll

下拵え

kaminariとjquery-turbolinksのインストール

Gemfile
#追記
gem "jquery-turbolinks"
gem "kaminari"
コマンド
$ bundle install

jquery.infinitscrollのダウンロード

コマンド
$ curl -k -o vendor/assets/javascripts/jquery.infinitescroll.js \
 https://raw.githubusercontent.com/paulirish/infinite-scroll/master/jquery.infinitescroll.js

Asset Pipelineにjquery-turbolinksとjquery.infinitscrollを追加

app/assets/javascripts/application.js
#追記
//= require jquery.turbolinks
//= require jquery.infinitescroll

モデルの準備

モデルの作成

コマンド
$ rails g model Hoge name description &&
  rails g model Piyo name description &&
  rails db:migrate

初期データの投入

db/seeds.rb
#追記
1000.times do |i|
  Hoge.create!(name: 'Hoge' + i.to_s, description: 'This is Hoge ' + i.to_s)
  Piyo.create!(name: 'Piyo' + i.to_s, description: 'This is Piyo ' + i.to_s)
end
コマンド
$ rails db:seed

Controllerの準備

メイン画面となるControllerを作成

コマンド
$ rails g controller home home
app/controllers/home_controller.rb
class HomeController < ApplicationController
  def home

    #下記追記

    #普通のアクセスの時に実行
    @hoges = Hoge.page(params[:hoge_page]) if params[:piyo_page].blank?
    @piyos = Piyo.page(params[:piyo_page]) if params[:hoge_page].blank?
    #*_pageが渡された時はもう片方は不要なのでif文でDBへのアクセスを軽減

    #追加読み込み時に実行、レイアウト無しでデータのみを返す
    unless params[:hoge_page].blank?
      return render @hoges, layout: false
    end
    unless params[:piyo_page].blank?
      return render @piyos, layout: false
    end

  end
end

ルーティングの設定

config/routes.rb
Rails.application.routes.draw do
  get 'home/home' #要らないので任意で削除

  root to: 'home#home' #追記
end

モデル読み込み用のControllerを作成

これはなくても動くので任意で作成してください。

コマンド
$ rails g controller hoges &&
  rails g controller piyos

Viewの準備

home viewの編集

app/views/home/home.html.erb
<div id='hoge_container'>
  <table id="hoges">
    <thead>
      <tr>
        <th>Name</th>
        <th>Description</th>
      </tr>
    </thead>

    <tbody class="page">
      <%= render @hoges %>
    </tbody>
  </table>

  <br>
  <%= paginate @hoges, remote: true, param_name: :hoge_page %>
</div>

<div id='piyo_container'>
  <table id="piyos">
    <thead>
      <tr>
        <th>Name</th>
        <th>Description</th>
      </tr>
    </thead>

    <tbody class="page">
      <%= render @piyos %>
    </tbody>
  </table>

  <br>
  <%= paginate @piyos, remote: true, param_name: :piyo_page %>
</div>

hogeテンプレートの作成

app/views/hoge/_hoge.html.erb
<tr class="hoge">
  <td><%= hoge.name %></td>
  <td><%= hoge.description %></td>
</tr>

piyoテンプレートの作成

app/views/piyo/_piyo.html.erb
<tr class="piyo">
  <td><%= piyo.name %></td>
  <td><%= piyo.description %></td>
</tr>

cssの編集

app/assets/stylesheets/application.css
/*追記*/
#infscr-loading, .pagination {
  width: 0;
  display: none;
}

#hoge_container, #piyo_container{
  float: left;
  margin: 10px 50px;
  padding: 10px 50px;
}

thead, tbody {
  display:block;
}

tbody {
  overflow-y:scroll;
  height:500px;
}

infinitescrollの設定

behaviorsとbinderを指定する事でウィンドウではなく特定の要素が下までスクロールされた時に追加読み込みを実行します。

app/assets/javascripts/home.coffee
#追記
$ ->
  $("#hoges .page").infinitescroll
    loading: {
      img: ""
      msgText: ""
      finishedMsg: ""
    }
    animate: true
    navSelector: "#hoge_container nav.pagination"
    nextSelector: "#hoge_container nav.pagination a[rel=next]"
    itemSelector: "tr.hoge"
    behaviors: "local"
    binder: $("#hoge_container .page")

$ ->
  $("#piyos .page").infinitescroll
    loading: {
      img: ""
      msgText: ""
      finishedMsg: ""
    }
    animate: true
    navSelector: "#piyo_container nav.pagination"
    nextSelector: "#piyo_container nav.pagination a[rel=next]"
    itemSelector: "tr.piyo"
    behaviors: "local"
    binder: $("#piyo_container .page")

実行

コマンド
$ rails s

localhost:3000/にアクセスして動作を確認してみてください。

それぞれをスクロールして自動で追加読み込みされれば成功です。

まとめ

JavaScriptフレームワークを勉強しましょう。

参考

Infinite Scroll

RailsでInfinite Scrollとkaminariを使いスクロールによる動的にページロード機能を実装する

【Ruby On Rails】infinit scrollとkaminariによる無限スクロールの実装

4
5
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
4
5