From 3b5c1147ac596e193c7f7ec4a1dd5e8e087c0db6 Mon Sep 17 00:00:00 2001 From: Oleg Valter Date: Fri, 31 Jul 2026 02:24:49 +0300 Subject: [PATCH 1/5] Minor fixes to YARD according to the tool's output --- app/helpers/abilities_helper.rb | 2 +- app/models/comment_thread.rb | 2 +- app/models/subscription.rb | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/helpers/abilities_helper.rb b/app/helpers/abilities_helper.rb index cf8bcedb1..30094bc62 100644 --- a/app/helpers/abilities_helper.rb +++ b/app/helpers/abilities_helper.rb @@ -1,6 +1,6 @@ module AbilitiesHelper # Gets a maybe_ability to the specified ability - # @param ability [Ability, String] ability or its internal id to link to + # @param maybe_ability [Ability, String] ability or its internal id to link to # @return [ActiveSupport::SafeBuffer] def ability_link(maybe_ability) ability = maybe_ability.is_a?(String) ? Ability.find_by(internal_id: maybe_ability) : maybe_ability diff --git a/app/models/comment_thread.rb b/app/models/comment_thread.rb index 05f81d6ed..7d5b5fcbc 100644 --- a/app/models/comment_thread.rb +++ b/app/models/comment_thread.rb @@ -19,7 +19,7 @@ class CommentThread < ApplicationRecord # Gets threads appropriately scoped for a given user & post # @param user [User, nil] user to check - # @para post [Post] post to check + # @param post [Post] post to check # @return [ActiveRecord::Relation] def self.accessible_to(user, post) if user&.at_least_moderator? || user&.post_privilege?('flag_curate', post) diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 2cb0376f9..a3a52e155 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -48,7 +48,6 @@ def questions end # Is the subscription's type qualified (bound to an entity)? - # @param type [String] type to check # @return [Boolean] check result def qualified? QUALIFIED_TYPES.include?(type) From e3634b205ac4525466a64975351b1a67a8fab1ee Mon Sep 17 00:00:00 2001 From: Oleg Valter Date: Fri, 31 Jul 2026 02:51:46 +0300 Subject: [PATCH 2/5] Make UserSortable a proper concern It confuses the heck out of YARD + aligns it with other model concerns + removed the need to disable the "1 class per file" rule of Rubocop --- app/models/application_record.rb | 35 ---------------------------- app/models/audit_log.rb | 1 + app/models/concerns/user_sortable.rb | 27 +++++++++++++++++++++ app/models/post.rb | 1 + 4 files changed, 29 insertions(+), 35 deletions(-) create mode 100644 app/models/concerns/user_sortable.rb diff --git a/app/models/application_record.rb b/app/models/application_record.rb index fcdb164f3..73e7b811f 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -158,38 +158,3 @@ def self.useful_err_msg end # rubocop:enable Metrics/MethodLength end - -module UserSortable - # Sort a collection according to a user selection, by mapping user selectable values to column names. - # SQL injection safe. - # @param term_opts Hash of search term options - # @param field_mappings Hash of user-selectable values to column names: +{ age: :created_at, rep: :threshold }+ - # @option term_opts :term [String] A user-provided search term to apply - usually from +params+, e.g. +params[:sort]+. - # Should be one of the keys in +field_mappings+. - # @option term_opts :default [Symbol] A column name to apply as the default sort ordering. - # @return [ActiveRecord::Relation] A relation of the current type, with the sort ordering applied. - def user_sort(term_opts, **field_mappings) - default = term_opts[:default] || :created_at - requested = term_opts[:term] - direction = term_opts[:direction] || :desc - if requested.nil? || field_mappings.exclude?(requested.to_sym) - $active_search_param = default - default.is_a?(Symbol) ? order(default => direction) : order(default) - else - requested_val = field_mappings[requested.to_sym] - $active_search_param = requested_val - requested_val.is_a?(Symbol) ? order(requested_val => direction) : order(requested_val) - end - end -end - -klasses = [ActiveRecord::Relation] -klasses << if defined? ActiveRecord::Associations::CollectionProxy - ActiveRecord::Associations::CollectionProxy - else - ActiveRecord::Associations::AssociationCollection - end - -ActiveRecord::Base.extend UserSortable -klasses.each { |klass| klass.send(:include, UserSortable) } -# rubocop:enable Style/OneClassPerFile diff --git a/app/models/audit_log.rb b/app/models/audit_log.rb index dfecac249..024d1515f 100644 --- a/app/models/audit_log.rb +++ b/app/models/audit_log.rb @@ -1,6 +1,7 @@ class AuditLog < ApplicationRecord include CommunityRelated include Timestamped + include UserSortable belongs_to :related, polymorphic: true, optional: true belongs_to :user, optional: true diff --git a/app/models/concerns/user_sortable.rb b/app/models/concerns/user_sortable.rb new file mode 100644 index 000000000..ea14c1204 --- /dev/null +++ b/app/models/concerns/user_sortable.rb @@ -0,0 +1,27 @@ +module UserSortable + extend ActiveSupport::Concern + + class_methods do + # Sort a collection according to a user selection, by mapping user selectable values to column names. + # SQL injection safe. + # @param term_opts Hash of search term options + # @param field_mappings Hash of user-selectable values to column names: +{ age: :created_at, rep: :threshold }+ + # @option term_opts :term [String] A user-provided search term to apply - usually from +params+, e.g. +params[:sort]+. + # Should be one of the keys in +field_mappings+. + # @option term_opts :default [Symbol] A column name to apply as the default sort ordering. + # @return [ActiveRecord::Relation] A relation of the current type, with the sort ordering applied. + def user_sort(term_opts, **field_mappings) + default = term_opts[:default] || :created_at + requested = term_opts[:term] + direction = term_opts[:direction] || :desc + if requested.nil? || field_mappings.exclude?(requested.to_sym) + $active_search_param = default + default.is_a?(Symbol) ? order(default => direction) : order(default) + else + requested_val = field_mappings[requested.to_sym] + $active_search_param = requested_val + requested_val.is_a?(Symbol) ? order(requested_val => direction) : order(requested_val) + end + end + end +end diff --git a/app/models/post.rb b/app/models/post.rb index 60a4505d7..2327df5b8 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -4,6 +4,7 @@ class Post < ApplicationRecord include PostValidations include SoftDeletable include Timestamped + include UserSortable belongs_to :user, optional: true belongs_to :post_type From bfcafba9c13e1806ad8bed46eb522741ee69016c Mon Sep 17 00:00:00 2001 From: Oleg Valter Date: Fri, 31 Jul 2026 02:53:40 +0300 Subject: [PATCH 3/5] Rubocop fixes --- app/models/application_record.rb | 1 - app/models/concerns/user_sortable.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 73e7b811f..24d4ef204 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -1,4 +1,3 @@ -# rubocop:disable Style/OneClassPerFile class ApplicationRecord < ActiveRecord::Base self.abstract_class = true diff --git a/app/models/concerns/user_sortable.rb b/app/models/concerns/user_sortable.rb index ea14c1204..4552963d4 100644 --- a/app/models/concerns/user_sortable.rb +++ b/app/models/concerns/user_sortable.rb @@ -6,7 +6,7 @@ module UserSortable # SQL injection safe. # @param term_opts Hash of search term options # @param field_mappings Hash of user-selectable values to column names: +{ age: :created_at, rep: :threshold }+ - # @option term_opts :term [String] A user-provided search term to apply - usually from +params+, e.g. +params[:sort]+. + # @option term_opts :term [String] A user-provided search term - usually from +params+, e.g. +params[:sort]+. # Should be one of the keys in +field_mappings+. # @option term_opts :default [Symbol] A column name to apply as the default sort ordering. # @return [ActiveRecord::Relation] A relation of the current type, with the sort ordering applied. From 5cc6bcd3faf3ab7ebc1b8c6de65c287fc34d8d9c Mon Sep 17 00:00:00 2001 From: Oleg Valter Date: Fri, 31 Jul 2026 03:30:45 +0300 Subject: [PATCH 4/5] More YARD fixes --- lib/namespaced_env_cache.rb | 2 +- lib/redis_cache_hash_methods.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/namespaced_env_cache.rb b/lib/namespaced_env_cache.rb index 68473e58f..75fbd1831 100644 --- a/lib/namespaced_env_cache.rb +++ b/lib/namespaced_env_cache.rb @@ -93,7 +93,7 @@ def write_collection(name, value, **opts) # no selects or joins applied. # @param name [String] cache key name # @param opts [Hash] options hash - any unlisted options will be passed to the underlying cache - # @options opts [Boolean] :include_community whether to include the community ID in the cache key + # @option opts [Boolean] :include_community whether to include the community ID in the cache key # @return [ActiveRecord::Relation, nil] def read_collection(name, **opts) namespaced = construct_ns_key(name, include_community: include_community(opts)) diff --git a/lib/redis_cache_hash_methods.rb b/lib/redis_cache_hash_methods.rb index c75ec35a1..8b9bd8716 100644 --- a/lib/redis_cache_hash_methods.rb +++ b/lib/redis_cache_hash_methods.rb @@ -41,7 +41,7 @@ def hget(hash_key, key) ## # Get multiple hash values. # @param hash_key [String] The name of the hash - # @param *keys [String] Keys within the hash to retrieve + # @param keys [Array] Keys to retrieve # @return [Hash] Keys and values from the hash def hmget(hash_key, *keys) with_redis do |rd| @@ -63,7 +63,7 @@ def hgetall(hash_key) ## # Delete a hash value, or the entire hash. # @param hash_key [String] The name of the hash - # @param *keys [String] Keys within the hash to delete. If none are provided, the entire hash is deleted. + # @param keys [Array] Keys to delete. If none are provided, the entire hash is deleted. # @return [Integer] The number of keys that were removed from the hash def hdel(hash_key, *keys) with_redis do |rd| From 2f7861169cd5c4d112e9d9d5ac662eafb48948a8 Mon Sep 17 00:00:00 2001 From: Oleg Valter Date: Fri, 31 Jul 2026 05:29:16 +0300 Subject: [PATCH 5/5] Switch README badges to markdown image links --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 774efdd62..583ad0ee6 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,12 @@ Q&A by the community, for the community
-

- Pipeline status - Coverage Status - DOI -

+
+ + [![Pipeline status](https://github.com/codidact/qpixel/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/codidact/qpixel/actions/workflows/ci-cd.yml) + [![Coverage status](https://codecov.io/gh/codidact/qpixel/graph/badge.svg?token=RM60WJLP1V)](https://codecov.io/gh/codidact/qpixel) + [![DOI](https://zenodo.org/badge/237078806.svg)](https://zenodo.org/badge/latestdoi/237078806) +
Rails-based version of our core software, powering [codidact.com](https://codidact.com). Currently under active development towards MVP.