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

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

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

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

Ruby on Rails

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

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

1回答

5301閲覧

Ruby on Rails & Ransackでの関連テーブルのソート方法

gesorein

総合スコア101

MySQL

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

Ruby on Rails

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

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

1グッド

0クリップ

投稿2017/03/16 04:03

編集2017/03/16 06:31

Ruby on Rails 4.2.6(MySQL)を使用して、
各企業が各登録者のステータスを管理するようなシステムを開発しています。
今回は「自社の管理している登録者の得点をソートする方法」について質問させていただきたいです。

システムの仕様は以下のようになってます。

###システムの仕様
データベース

  • 各管理者は必ず企業に所属するようになっています。
  • 登録者のステータスは各企業ごとに管理されています。
users - ユーザーテーブル id:integer email:string role:integer members - 登録者テーブル id:integer user_id:integer name:string managers - 管理者テーブル id:integer user_id:integer company_id:integer name:string companies - 企業テーブル id:integer name:string member_statuses - 登録者ステータス id:integer member_id:integer company_id:integer points:integer

ActiveRecordのアソシエーション

class User < ActiveRecord::Base has_one :member has_one :manager end class Member < ActiveRecord::Base belongs_to :user has_many :member_statuses end class Manager < ActiveRecord::Base belongs_to :user belongs_to :company end class Company < ActiveRecord::Base has_many :managers has_many :member_statuses end class MemberStatus < ActiveRecord::Base belongs_to :member belongs_to :company end

###問題点
検索機能はRansackのgemを使用しています。
登録者の得点(points)でソートして一覧表示したいので、
MembersControllerのコードは以下のようになっています。

Ruby

1class MembersController < ApplicationController 2 def index 3 @q = Member.ransack(params[:q]) # params = {"q"=>{"s"=>"member_statuses_points desc"}} 4 @members = @q.result(ditinct: true).includes(:member_statuses) 5 end 6end

こちらのコードでソートして一覧表示すると以下のような結果になってしまい、
企業ID1と企業ID2それぞれが管理する登録者の得点が干渉してしまいます。

[各企業が管理する各登録者の得点] 企業ID1が管理する各登録者の得点:ID1: 0点, ID2: 100点, ID3: 0点, ID4: 0点 企業ID2が管理する各登録者の得点:ID1: 10点, ID2: 0点, ID3: 0点, ID4: 20点 [実際のソート結果] 企業ID1でのソート(降順):ID2, ID4, ID1, ID3 企業ID2でのソート(降順):ID2, ID4, ID1, ID3 [理想のソート結果] 企業ID1でのソート(降順):ID2, ID1, ID3, ID4 企業ID2でのソート(降順):ID4, ID1, ID2, ID3

発行されるSQL

SQL

1SELECT DISTINCT members.id, member_statuses.points FROM members INNER JOIN member_statuses ON member_statuses.member_id = members.id ORDER BY member_statuses.points DESC;

もちろん発行されるSQLを見てもcompany_idは含まれていないので、
この結果になるのは理解できますが、良い解決方法が思い付きません。

もしかしたらデータベースの設計自体もあまり良くないのかもしれませんが、
何かしらアドバイスをいただけると幸いです。

mhashi👍を押しています

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

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

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

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

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

guest

回答1

0

自己解決

こちらの件ですが、自己解決いたしました。
以下のように、直接パラメータの検索クエリに関連モデルの企業IDを代入することで、
意図した結果を得ることができました。

Ruby

1def index 2 params[:q][:member_statuses_company_id_eq] = current_user.manager.company_id if params[:q] 3 @q = Member.ransack(params[:q]) 4 @members = @q.result(distinct: true).includes(:member_statuses) 5end

閲覧なさってくださった方々ありがとうございます!

投稿2017/03/16 06:29

編集2017/11/27 00:44
gesorein

総合スコア101

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問