Reputation: 10812
I have a table that displays student test scores. I have these classes:
class Student < ApplicationRecord
has_many :tests
end
class Test < ApplicationRecord
belongs_to :student
end
The table displays the students' 3 major test scores:
+-------+--------+--------+--------+
| Name | Test 1 | Test 2 | Test 3 |
+-------+--------+--------+--------+
| Jeff | 60.5 | 45.9 | 100.0 |
| Cindy | 50.0 | 99.0 | 88.5 |
+-------+--------+--------+--------+
I want to be able to order the students by specific test scores. So I might order desc by the test scores on Test 1 (resulting in [Jeff, Cindy]
) or Test 2 (resulting in [Cindy, Jeff]
).
I'm not really sure how to incorporate the test name into the query.
Upvotes: 1
Views: 109
Reputation: 341
joins
actually by default is inner join
i.e. it'll remove all students who haven't given a test, and all tests without students.
You can try the below code.
# for rails version < 5
Student.joins('LEFT OUTER JOIN "tests" ON "tests"."student_id" = "students"."id"')
.where(tests: { id: test1_record_id }).order('tests.score desc')
# for rails version >= 5
Student.left_outer_joins(:tests)
.where(tests: { id: test1_record_id }).order('tests.score desc')
I haven't tested it, but you should get the idea.
EDIT:
You can use the following query:
(SELECT students.*,
tests.marks,
tests.NAME
FROM students
LEFT OUTER JOIN tests
ON tests.student_id = students.id
WHERE tests.NAME = 'test3'
ORDER BY tests.marks DESC)
UNION ALL
(SELECT students.*,
tests.marks,
tests.NAME
FROM students
LEFT OUTER JOIN tests
ON tests.student_id = students.id
WHERE tests.NAME != 'test3');
And execute it like ActiveRecord::Base.connection.execute(query).entries
Upvotes: 1
Reputation: 4709
You can sort students like this:
Student.joins(:tests).where(tests: { id: test1_record_id }).order('tests.score desc')
Upvotes: 0