0
0

More than 1 year has passed since last update.

[Rails]Indexを条件を指定して並び替える

Posted at

行いたいこと

本の一覧を条件を指定して並び替える
今回の条件

  • 投稿日の新しい順
  • 投稿日の古い順
  • 評価の高い順

スクリーンショット 2022-12-08 16.48.27.png

環境

  • Ruby3.1.2
  • Rails6.1.7
  • Bookモデル作成済み
  • 評価機能作成済み(並び替えで使用しているだけなので必須ではない)

1.並び替える方法

orderを用いてデータを並び替える

Book.order(条件: :並び順)
Book.order(created_at: :desc) created_at:は作成日時。 :descは降順
Book.order(created_at: :asc) created_at:は作成日時。 :ascは昇順
Book.order(rating: :desc) ratingは評価の値が入っているカラム名

勿論このまま書いてもいいが、コントローラーをスッキリさせるためscopeを用いて簡潔にする

models/book.rb
  scope :sort_rate, ->{order(rating: :desc)}
  scope :sort_new, ->{order(created_at: :desc)}
  scope :sort_old, ->{order(created_at: :asc)}

2.viewでのリンクの作成

view各検索方法へとアクセスするリンクを作成する

views/books/index.erb
~省略~
 <h2>Books</h2>
 <p><%= link_to '新しい順', books_path(new:new)%> | 
<%= link_to '古い順', books_path(old:old)%> | 
<%= link_to '評価の高い順', books_path(rate:rate)%></p>
~省略~

ここでのbooks_path(new:"new")books_path(old:"old")books_path(rate:"rate")
は送信先は全てindexになるが、さらに( )の中の値を一緒に送信している
例:books_path(new:"new")ならnew:という項目にnewという値を付与
この( )の値は任意のもので良い。後述するコントローラーでの分岐に必要になる

3.コントローラーでの分岐処理

indexアクションを以下のように変更

controller/books_controller.rb
  def index
    if params[:rate].present?
      @books = Book.sort_rate
    elsif params[:new].present?
      @books = Book.sort_new
    elsif params[:old].present?
      @books = Book.sort_old      
    else
      @books = Book.all
    end
    @book = Book.new
  end

ここで仮に「新しい順」を押した時に送られる値を確認してみる

[1] pry(#<BooksController>)> params
=> #<ActionController::Parameters {"new"=>"new", "controller"=>"books", "action"=>"index"} permitted: false>

"new"=>"new"という値が送られてきているのがわかる。
あとはif params[:~~].present? でその値が有るかを確認し、
合致する場所の処理を、1で設定したscopeを用いて記述していく
present? はその要素が存在していればtrue、なければfalseを返す。

これで完成!

参考にした記事

0
0
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
0
0