質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1170閲覧

一覧ページでボタンを押すとデータが並び替わる方法

kato_junnichi

総合スコア2

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2021/11/03 10:39

前提・実現したいこと

現在Ruby on Rails で本に評価をつけて投稿するシステムを作っており
本の一覧ページ(books#index)で本を「新しい順」と「評価の高い順」に並び替えるボタンを作りたいです。(元々本は古いものから順(降順)に並んでおります)
選択後は元居たページに遷移させたいです。

発生している問題・エラーメッセージ

該当のソースコード

_index.html.erb

<table class='table table-hover table-inverse'> <thead> <%= link_to '新着順', books_path(created_at: "true") %>   <%= link_to '評価順', books_path(evaluation: "true") %> <tr> <th></th> <th>Title</th> <th>Opinion</th> <th colspan="3"></th> </tr> </thead> <tbody> <% books.each do |book| %> <tr> <td><%= link_to user_path(book.user) do %> <%= attachment_image_tag(book.user, :profile_image, :fill, 50, 50, fallback: "no-image-icon.jpg") %> <% end %> </td> <td><%= link_to book.title, book_path(book), class: "book_#{book.id}" %></td> <td><%= book.body %></td> <td class="favorite-btn"><%= render "favorites/favorite-btn", book: book %></td> <td>コメント数: <%= book.book_comments.count %></td> <td class="book-evaluation" data-score="<%= book.evaluation %>"></td> </tr> <% end %> </tbody> </table> <script> $('.book-evaluation').raty({ readOnly: true, score: function() { return $(this).attr('data-score'); }, path: '/assets/' }); </script>

books_contoroller.rb

class BooksController < ApplicationController helper_method :sort_column, :sort_direction before_action :authenticate_user! before_action :ensure_correct_user, only: [:edit, :update, :destroy] def show @book = Book.find(params[:id]) @book_comment = BookComment.new end def index @books = Book.all.order(evaluation: :desc) @book = Book.new end def create @book = Book.new(book_params) @book.user_id = current_user.id if @book.save redirect_to book_path(@book), notice: "You have created book successfully." else @books = Book.all render 'index' end end def edit end def update if @book.update(book_params) redirect_to book_path(@book), notice: "You have updated book successfully." else render "edit" end end def destroy @book.destroy redirect_to books_path end private def book_params params.require(:book).permit(:title, :body, :evaluation) end def ensure_correct_user @book = Book.find(params[:id]) unless @book.user == current_user redirect_to books_path end end end

試したこと

まったくわからないので上記のソースコードの
<%= link_to '新着順', books_path(created_at: "true") %>
<%= link_to '評価順', books_path(evaluation: "true") %>
部分のようにしてみましたが、上手くいくはずもありませんでした。
Ransackも試そうと試みましたが検索のみでしか使えないのでしょうか。

補足情報(FW/ツールのバージョンなど)

ruby バージョン:2.6.3p62
Rails バージョン: 5.2.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

erb

1A <%= link_to '新着順', books_path %> 2B <%= link_to '評価順', books_path(order: "evaluation") %>

こうすると、A は /books B は /books?order=created_at のリンクが作成されます。
この order の値はコントローラーで params[:order] で取得できます。
(order は任意で、sort とか別の名前でも良いです)

ruby

1def index 2 @books = Book.order(order_by) 3 @book = Book.new 4end 5 6private 7 8def order_by 9 # order の指定に許可するカラムを列挙 10 allow = ["evaluation", "updated_at"] 11 # すべてのカラムを指定するには 12 # allow = Book.column_names 13 14 # params[:order] が allow に含まれているならその値を 15 # 含まれていない時(デフォルト値)は created_at を返す 16 allow.include?(params[:order]) ? params[:order] : "created_at" 17end

order に直接 params[:order] は指定しないでください。
SQLインジェクションの温床になります。

ruby

1# ダメ! 2@books = Book.order(params[:order])

追記

order_by がハッシュを返すようにします。
params[:order] が配列 ASC に含まれるとき { params[:order] => :asc }
DESC に含まれるとき { params[:order] => :desc }
含まれない時(リーロードしたとき) { id: :asc} を返します

ruby

1def index 2 @books = Book.order(order_by) 3end 4 5ASC = ["evaluation"] 6DESC = ["updated_at", "created_at"] 7 8def order_by 9 if ASC.include?(params[:order]) 10 { params[:order] => :asc } 11 elsif DESC.include?(params[:order]) 12 { params[:order] => :desc } 13 else 14 { id: :asc } 15 end 16end

投稿2021/11/03 16:20

編集2021/11/05 14:05
neko_daisuki

総合スコア2090

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kato_junnichi

2021/11/04 00:26

回答ありがとうございます。 分かりやすくてとても助かりました。 度々の質問で申し訳ないのですが 降順にする方法が分からないのですがどうすればいいでしょうか。 ,,, <%= link_to '新着順', books_path(order: "created_at: :desc") %>  <%= link_to '評価順', books_path(order: "evaluation: :desc") %> ,,, のようにしてみましたが反映されません。 どのようにするのが正解でしょうか。
neko_daisuki

2021/11/04 04:26

すべて desc で良いなら @books = Book.order(order_by => :desc)
kato_junnichi

2021/11/05 13:34

ご回答ありがとうございます。 たびたびの質問で申し訳ありませんが リロード時は昇順に並んでおり、新着順、評価順を選択したときのみ降順にしたいと考えております。 ご教授いただいたコードに変更を加え、いろいろ試してみましたがうまくいきません。 どのように書けばよろしいでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問