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

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

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

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

解決済

1回答

1711閲覧

子テーブル、孫テーブルの個数をカウントした値で親テーブルのデータを並び替えたい

GenkiSugiyama

総合スコア86

Ruby on Rails 6

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

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

0グッド

0クリップ

投稿2020/09/30 05:35

Userモデル(購入者)→Orderモデル(注文)→Oreder_itemモデル(購入商品)の3つのモデルがあり、左から1対多となるようなリレーションとなっています。

【user.rb】

class User < ApplicationRecord has_many :orders  def orders_counts orders.where(order_completed: true).count  end  def order_rackets_counts total_rackets = 0 orders.where(order_completed: true).each do |order| order_rackets = order.order_items.count total_rackets += order_rackets end return total_rackets  end  def order_amounts amounts = 0 orders.where(order_completed: true).each do |order| amounts += order.amount end return amounts  end end

【order.rb】

class Order < ApplicationRecord belongs_to :user has_many :order_items ・ ・ ・ end

【order_item.rb】

class OrderItem < ApplicationRecord belongs_to :order ・ ・ ・ end

【ユーザー一覧ページに掲載している内容】

<tbody class="text-center"> <td class="align-middle"> <%= user.id %> </td> <td class="align-middle"> <%= link_to user_path(user.id), class: "book_#{user.id}", method: :get do %> <%= user.name %> <% end %> </td> <td class="align-middle"> <%= user.orders_counts %>回 </td> <td class="align-middle"> <%= user.order_items.to_s(:delimited) %>本 </td> <td class="align-middle text-right"> <%= user.order_amounts.to_s(:delimited) %>円 </td> <td class="align-middle"> <%= l user.created_at, format: :very_short %> </td> ・・・ <td class="align-middle"> <%= link_to "詳細", user_path(user.id), class:"btn btn-primary" %> <%= link_to "編集", edit_user_path(user.id), class:"btn btn-success my-3" %> </td> </tbody>

現在ユーザー一覧画面(views/users/index.html.erb)で累計注文回数(userに紐付くoredersの個数をcount)、累計金額(userに紐付くordersの金額カラム(amount)をsum)、注文個数(「userに紐付くorders」に紐付くorder_itemsの個数をcount)を表示しているのですが、これらの値を使って並び替えたいと考えています。

【controllers/user_controller.rb】

class UsersController < ApplicationController  def index   @q = User.where(del_flg: 1).includes(orders: :order_items).ransack(params[:q])   @users = @q.result(distinct: true).order("created_at DESC")  end  #注文回数により並び替え→注文回数「8回」のデータが1番上に来ていない  def order_counts   @users = User.joins(orders: :order_items).select("users.id, users.name, count(orders.id) AS order_count, users.created_at, users.kit_shipped_date, count(order_items.id) AS racket_count, sum(orders.amount) AS amounts").group(:user_id).where(del_flg: 1).where(orders: {order_completed: true}).order("order_count desc")  end  #注文個数により並び替え  def racket_counts   @users = User.joins(orders: :order_items).select("users.id, users.name, count(orders.id) AS order_count, users.created_at, users.kit_shipped_date, count(order_items.id) AS racket_count, sum(orders.amount) AS amounts").group(:user_id).where(del_flg: 1).where(orders: {order_completed: true}).order("racket_count desc")  end  #注文金額合計により並び替え  def order_amount_counts   @users = User.joins(orders: :order_items).select("users.id, users.name, count(orders.id) AS order_count, users.created_at, users.kit_shipped_date, count(order_items.id) AS racket_count, sum(orders.amount) AS amounts").group(:user_id).where(del_flg: 1).where(orders: {order_completed: true}).order("amounts desc")  end end

上記のようにメソッドを分け、ルーティングで設定したそれぞれのURLにアクセスすると並び替えが実行されるようになっています。

上記の状態でブラウザで並び替え状況を確認したところ、「注文個数」による並び替えは上手く動いているように見えますが、その他2つの処理はバラバラになっております。

【order_counts.html.erb】注文回数による並び替え
イメージ説明

【racket_counts.html.erb】注文個数による並び替え
イメージ説明

【order_amount_counts.html.erb】注文回数による並び替え
イメージ説明

上手く個数をカウントし意図した並び替えを実現するためのアドバイスをいただけますと幸いです。

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

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

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

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

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

sazi

2020/10/11 01:39 編集

発行されているSQLを取得して、DBツールなど直接実行し並びが意図通りである事は確認されましたか? 意図通りでない場合、そのSQLも追記して下さい。
sazi

2020/10/11 01:43

railsは詳しくないのですが、表示されている内容と、並び替えでorderしている項目は全く同じものですか?
GenkiSugiyama

2020/10/12 03:33

コメントありがとうございます。 railsの機能で発行されたSQLの確認が不足していました。。 現在はSQLを確認して行いたい処理じゃないことが判明したので修正して期待していた動作を実装することができました!
sazi

2020/10/12 03:46

では、解決方法を回答して、自己解決にして下さい。
guest

回答1

0

自己解決

@users = User.joins("INNER JOIN (SELECT orders.user_id, orders.id, orders.amount, orders.order_completed, orders.created_at, count(order_items.id) AS rackets FROM orders INNER JOIN order_items ON order_items.order_id = orders.id GROUP BY orders.id) AS order_items ON order_rackets.user_id = users.id AND order_items.order_completed = TRUE").select("users.id, users.name, users.created_at, users.kit_shipped_date, count(order_rackets.id) as orders_count, sum(order_items.amount) as amounts, sum(items) AS items_count, MAX(order_items.created_at) AS latest_order").group(:id).where(del_flg: 1).order("items_count desc")

上記のようにサブクエリを直SQLをゴリゴリに書くことで取得したい結果を得ることができました。

が、もう少しスマートな方法があるような気がしてなりません。。。

投稿2020/10/15 02:35

GenkiSugiyama

総合スコア86

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問