diff --git a/lib/topic_query.rb b/lib/topic_query.rb index cdd5abbb4..1c061107c 100644 --- a/lib/topic_query.rb +++ b/lib/topic_query.rb @@ -401,6 +401,11 @@ class TopicQuery return result.includes(:first_post).order("(SELECT like_count FROM posts p3 WHERE p3.topic_id = topics.id AND p3.post_number = 1) #{sort_dir}") end + if sort_column.start_with?('custom_fields') + field = sort_column.split('.')[1] + return result.order("(SELECT CASE WHEN EXISTS (SELECT true FROM topic_custom_fields tcf WHERE tcf.topic_id::integer = topics.id::integer AND tcf.name = '#{field}') THEN (SELECT value::integer FROM topic_custom_fields tcf WHERE tcf.topic_id::integer = topics.id::integer AND tcf.name = '#{field}') ELSE 0 END) #{sort_dir}") + end + result.order("topics.#{sort_column} #{sort_dir}") end diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb index fad4faaea..276ee7656 100644 --- a/spec/components/topic_query_spec.rb +++ b/spec/components/topic_query_spec.rb @@ -232,6 +232,33 @@ describe TopicQuery do # returns the topics in reverse posters order if requested" do expect(ids_in_order('posters', false)).to eq([archived_topic, closed_topic, invisible_topic, future_topic, regular_topic, pinned_topic].map(&:id)) + + # sets a custom field for each topic to emulate a plugin + regular_topic.custom_fields["sheep"] = 26 + pinned_topic.custom_fields["sheep"] = 47 + archived_topic.custom_fields["sheep"] = 69 + invisible_topic.custom_fields["sheep"] = 12 + closed_topic.custom_fields["sheep"] = 31 + future_topic.custom_fields["sheep"] = 53 + + regular_topic.save + pinned_topic.save + archived_topic.save + invisible_topic.save + closed_topic.save + future_topic.save + + # adds the custom field as a viable sort option + class ::TopicQuery + SORTABLE_MAPPING["sheep"] = "custom_fields.sheep" + end + # returns the topics in the sheep order if requested" do + expect(ids_in_order('sheep')).to eq([archived_topic, future_topic, pinned_topic, closed_topic, regular_topic, invisible_topic].map(&:id)) + + # returns the topics in reverse sheep order if requested" do + expect(ids_in_order('sheep', false)).to eq([invisible_topic, regular_topic, closed_topic, pinned_topic, future_topic, archived_topic].map(&:id)) + + end end