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

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

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

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

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

Q&A

1回答

955閲覧

子モデルのデータのテーブルのカラムをソートしたい

kawa0tatsu

総合スコア7

Ruby on Rails 6

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

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

0グッド

0クリップ

投稿2020/05/29 02:33

編集2020/05/30 12:35

前提・実現したいこと

楽曲とその音源を登録するアプリを作っています。1つの曲に対し複数の演奏音源がつきます。親モデルはpostで、子モデルはrecordingです。

楽曲(親モデル)を表示するページにて、Sortable Table Columnsおよび[Railsで並べ替え可能なテーブルの実装手順](a href="https://www.virment.com/rails-sortable-table/)を参考にして音源(子モデル)の情報をカラム別にソートできるテーブルを作っています。

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

テーブルに表示されたリンクをクリックしても何も起こりません。
URL自体はhttp://localhost:3000/posts/60?direction=asc&sort=Mov2という風に機能します。

該当のソースコード

Ruby

1モデル 2Post.rb 3class Post < ApplicationRecord 4  has_many :recordings, dependent: :destroy 5  has_many :post_instruments 6  has_many :instruments, :through => :post_instruments, dependent: :destroy 7  accepts_nested_attributes_for :recordings, {allow_destroy: true} 8end 9 10recording.rb 11class Recording < ApplicationRecord 12  belongs_to :post 13  has_many :durations, dependent: :destroy 14  accepts_nested_attributes_for :durations 15  mount_uploader :image, ImageUploader 16end 17 18コントローラおよびヘルパー 19application_controller.rb 20 21ApplicationController 22class ApplicationController < ActionController::Base 23    include SessionsHelper 24    include RecordingsHelper 25end 26 27 28recordings_helper.rb 29 30module RecordingsHelper 31    def sortable(column, title = nil) 32        title ||= column.titleize 33        css_class = (column == sort_column) ? "current #{sort_direction}" : nil 34        direction = (column == sort_column && sort_direction == "asc") ? "desc" : "asc" 35        link_to title, {:sort => column, :direction => direction}, {:class => css_class} 36    end 37  38    def sort_direction 39        %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc" 40    end 41 42    def sort_column 43        Recording.column_names.include?(params[:sort]) ? params[:sort] : "name" 44    end 45end 46 47posts_controller 48helper_method :sort_column, :sort_direction 49 50  def show 51    @post = Post.includes(:instruments, :recordings=>:durations).find(params[:id]) 52    #@post.recordings.order(sort_column+ "" + sort_direction) 53    @post.recordings.order("recordings + sort_column+  ' ' + sort_direction") 54    @instruments = @post.instruments.order('created_at desc') 55  end 56 57ビュー(show.html.erb) 58 59<table> 60 61 <tr><%# Start of th %> 62 <% @instruments.each do |instrument| %>%# Start of instruments th %><%# 楽曲編成に応じてカラムを追加 %> 63 <% if instrument.name.include? 'orchestra' %><%# 管弦楽曲の場合、指揮者カラムを追加 %> 64 <th><%= sortable "conductor", "Conductor" %></th> 65 <% end %> 66 67 <% if instrument.name.include? "#{instrument.name}" %> 68 <th><%= sortable "#{instrument.name}","#{instrument.name}" %></th> 69 <% end %> 70 <% end %><%# End of instruments th %> 71 72 <% (1..@post.mov).each do |movnum| %><%# 楽章数に応じてカラム数が変化 %> 73 <th width="70"><%= sortable "Mov#{movnum}" %></th> 74 <% end %> 75 </tr><%# End of th %> 76 77 78<% @post.recordings.each do |recording| %> 79 80 <tr> 81 <% @instruments.each do |instrument| %> 82 83 <% if instrument.name.include? 'orchestra' %> 84 <td><%= recording.conductor %></td> 85 <% end %> 86 87 <% if instrument.name.include? "#{instrument.name}" %> 88 <td><%=recording.send("#{instrument.name}") %></td> 89 <% end %> 90 91 <% end %><%# End of the loop of instruments %> 92 93 <% recording.durations.each do |duration| %><%# 楽章ごとの演奏時間 %> 94 <td><%=Time.at(duration.total_seconds).utc.strftime("%M:%S") %></td> 95 <% end %><%# End of durations %> 96 97 </tr> 98 99 <% end %><%# End of the loop of each recordings %> 100 101</table>

試したこと

親モデルにおいて子モデルのデータをソートするには
親モデル.includes(:子モデル).oder("子モデル名の複数形.カラム名 DESC")
とすればいいらしいですが、それと今回のことをどう組み合わせればいいか分かりません。

Helperを親モデルにすることなどを試しましたが結果は変わりませんでした。

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

Ruby on Rails 6.0

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

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

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

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

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

winterboum

2020/05/30 05:42

viewを載せてください
winterboum

2020/05/30 14:15

そのviewには「テーブルに表示されたリンク」が見当たらないんですが?
kawa0tatsu

2020/05/31 15:29

<th><%= sortable... %>の部分のことを言っているつもりなのですが・・・。
winterboum

2020/05/31 20:36

ああ、そこか。 この link_to がよろしくないように見えます。 どのURLになることを期待してますか?
kawa0tatsu

2020/06/01 11:31

クリックして表示されるURL自体は正しいように見えます。例:http://localhost:3000/posts/56?direction=asc&sort=Mov1 クリックしたら格納されている文字列がアルファベット順、そして演奏時間(time型)の数字が昇順・降順で並び替えられるようにしたいですが、そうなりません。あと、sortがascだけで、クリックしてもdescになりません。
guest

回答1

0

@post.recordings.order("recordings + sort_column+ ' ' + sort_direction")

@post.recordings.order(ort_column+ ' ' + sort_direction)
にしてみてください

ただ、、、direction=asc&sort=Mov2 の Mov2 が気になります。
ここは Recording のカラム名でなければならないのですが、そういうのあります?
まず、captalで始まってるのも??ですし

投稿2020/06/01 11:43

winterboum

総合スコア23347

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

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

kawa0tatsu

2020/06/05 13:56

(1)@post.recordings.order(sort_column+ ' ' + sort_direction)にしてみてください> 最初そうしたら効かなかったので、今回質問しました。 子モデルのソートは 親モデル名.includes(:子モデル名).order("子モデル名の複数形.カラム名 desc") で出来るらしいので、それを組み合わせるべきかと思って @post.recordings.order('recordings.' + sort_column + ' ' + sort_direction) としたのですが、出来ませんでした。 そもそもこれらの文言があってもなくても挙動に影響がないので、ヘルパーとかメソッドの置き方にも問題があるのかも知れません。いろいろ試してますが出来ていません。 (2)まず、captalで始まってるのも??ですし> 今回のコードは参考もとのサイトのコピペですが、sortableメソッドにおけるtitlizeで自動的に大文字になるらしいです。ただ、なぜこれを使う必要があるのかはよく分かりません。 (3)確かに言われてようやく気づきましたが、mov1, mov2などというカラムは確かにRecordingモデルには存在しません。 末尾の番号はDurationモデル(recordingモデルの子モデル、postモデルからみて孫モデル)においてmovカラムに格納しています。 また、Durationモデルに格納した分と秒をもとに、こちら(https://teratail.com/questions/252331)で書いたように、自作関数で出した時間を表示しています。これもソートしたいですが、別の複雑な問題になるので、これについてはまた質問を立て直そうかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問