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
-
-
-
-
-
+
+
+ [](https://github.com/codidact/qpixel/actions/workflows/ci-cd.yml)
+ [](https://codecov.io/gh/codidact/qpixel)
+ [](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.
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/application_record.rb b/app/models/application_record.rb
index fcdb164f3..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
@@ -158,38 +157,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/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/concerns/user_sortable.rb b/app/models/concerns/user_sortable.rb
new file mode 100644
index 000000000..4552963d4
--- /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 - 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
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)
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|