カラムデータの順序をviewで切り替える(昇順・降順)


それでは、今回はカラムデータを昇順・降順で並び替える機能を実装します。

まずは、カラムデータの用意をします

今回は、"rails console"からデータを投入します。
Textsテーブルを作成済みです。

terminal
$ rails c
Running via Spring preloader in process 8195
Loading development environment (Rails 5.2.2.1)
irb(main):001:0> text = Text.new(genre:"△△△",title:"xxxxxx")
=> #<Text id: nil, title: "xxxxxx", contents: nil, genre: "△△△", created_at: nil, updated_at: nil>
irb(main):002:0> text.save!
   (0.2ms)  begin transaction
  Text Create (1.9ms)  INSERT INTO "texts" ("title", "genre", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "xxxxxx"], ["genre", "△△△"], ["created_at", "2019-04-15 14:24:55.534682"], ["updated_at", "2019-04-15 14:24:55.534682"]]
   (1.6ms)  commit transaction
=> true

ちなみに、少しボケていたんですが、"rails c"にてデータを入れるときは、きちんと"save!"しましょう。
saveした時点でidも追加されます。

なぜか、データが反映されないな、と少し悩んでしまいました。

viewでテーブルを作ります!

今回はBootstrapを利用します。

index.html.erb
<table class="table table-striped m-auto">
  <thead class="thead-color">
    <tr>
      <th scope="col">
        <%= link_to 'スキル', texts_path(id: @sort)  %>
      </th>
      <th scope="col">
        ジャンル
      </th>
      <th scope="col">
        内容
      </th>
    </tr>
  </thead>
  <tbody>
    <% @texts.each do |text| %>
      <tr>
        <th scope="row">
          <%= "Lv.#{text.id}" %>
        </th>
        <td>
          <%= text.genre %>
        </td>
        <td>
          <%= text.title %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>
  • table-striped:テーブルレコードをストライプ状に色分けする
  • m-auto:"margin: 0 auto;"と同じ意味。

モデルにscopeを実装

これは以前の記事に記載しましたので、説明は割愛します。

text.rb
class Text < ApplicationRecord
    scope :asc_sort, ->{ order(id: :asc)}
    scope :desc_sort, ->{ order(id: :desc)}
end

コントローラに実装

if文を使い、降順と昇順を切り替えます。

以下がコントローラ部分です。

texts_controller.rb
class TextsController < ApplicationController

    def index

        if request.fullpath.include?('desc')
            @texts = Text.all.desc_sort
            @sort = "asc"
        else
            @texts = Text.all.asc_sort
            @sort = "desc"
        end

    end

end

流れとしては、

  1. 一旦、ルーティングroot:toでtexts#indexに飛ぶように設定
  2. localhost:3000にアクセスし、indexビューへ飛ぶ(@sortに"desc"代入される)
  3. indexのlink_toのパスをtexts#index(texts_path)に設定し、クリックで再びindexコントローラ(if文)を経由させる
  4. その際にpathの引数をid: @sortなどとしておく
  5. indexコントローラにてカラムデータが降順になった後、@sortに"asc"が代入される
  6. 以下、繰り返し

ちなみに、

request.fullpath.include?('desc')

は、pathに'desc'という文字列を含んでいるかどうかを判定します。
実装されましたら、URLがどのように変化するのかを見てみると、よくわかります。