-
Notifications
You must be signed in to change notification settings - Fork 71
Sorted tags alphabetically #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7b0ad6f
a429cfe
35d3c04
13f543b
1cd4e60
3bef7fc
32db336
f34e770
4784e80
8fae3e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,6 +8,15 @@ class Tag < ApplicationRecord | |||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| scope :alphabetically, -> { order(:name) } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| scope :sorted_naturally_db, -> { | ||||||||||||||||||||||||
| order( | ||||||||||||||||||||||||
| Arel.sql( | ||||||||||||||||||||||||
| "REGEXP_REPLACE(name, '\\d+$', '') ASC, " \ | ||||||||||||||||||||||||
| "CAST(REGEXP_REPLACE(name, '\\D+', '') AS INTEGER) ASC" | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| COLORS = %w[#e99537 #4da568 #6471eb #db5a54 #df4e92 #c44fe9 #eb5429 #61c9ea #805dee #6ad28a] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| UNCATEGORIZED_COLOR = "#737373" | ||||||||||||||||||||||||
|
|
@@ -23,4 +32,10 @@ def replace_and_destroy!(replacement) | |||||||||||||||||||||||
| destroy! | ||||||||||||||||||||||||
| end | ||||||||||||||||||||||||
| end | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def self.sorted_naturally | ||||||||||||||||||||||||
| all.to_a.sort_by do |tag| | ||||||||||||||||||||||||
| tag.name.to_s.scan(/\d+|\D+/).map { |s| s =~ /\d+/ ? s.to_i : s.downcase } | ||||||||||||||||||||||||
| end | ||||||||||||||||||||||||
| end | ||||||||||||||||||||||||
|
Comment on lines
+36
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Make natural sort chainable and consistent (avoid loading entire table and ambiguity between scope vs class method) self.sorted_naturally returns an Array (loads all records) and is a class method, not a scope. Calling Current.family.tags.sorted_naturally relies on Rails’ method_missing scoping semantics and returns a Ruby array, which:
Prefer a scope for use in relations and keep the Ruby method only as an explicit fallback. Two options: Option A (recommended): consolidate on DB scope and remove/rename the Ruby method. - def self.sorted_naturally
- all.to_a.sort_by do |tag|
- tag.name.to_s.scan(/\d+|\D+/).map { |s| s =~ /\d+/ ? s.to_i : s.downcase }
- end
- end
+ # Optional: keep a clearly named Ruby-only helper if ever needed explicitly
+ def self.sorted_naturally_ruby(collection = all)
+ collection.to_a.sort_by do |tag|
+ tag.name.to_s.scan(/\d+|\D+/).map { |s| s =~ /\d+/ ? s.to_i : s.downcase }
+ end
+ endOption B: keep both, but add a scope alias for consistent call sites: + scope :sorted_naturally, -> { sorted_naturally_db }If you’d like, I can follow through with a repo-wide rename to use sorted_naturally_db (or the alias) wherever relations are expected. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
| end | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -32,7 +32,7 @@ | |||||
| <%= render DS::Disclosure.new(title: t(".details")) do %> | ||||||
| <%= f.fields_for :entryable do |ef| %> | ||||||
| <%= ef.select :tag_ids, | ||||||
| Current.family.tags.alphabetically.pluck(:name, :id), | ||||||
| Current.family.tags.sorted_naturally.pluck(:name, :id), | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Prefer DB-level sort for options to avoid loading all records and to keep consistent ordering Using the scope keeps pluck on the database and avoids Ruby-level sorting overhead. - Current.family.tags.sorted_naturally.pluck(:name, :id),
+ Current.family.tags.sorted_naturally_db.pluck(:name, :id),📝 Committable suggestion
Suggested change
|
||||||
| { | ||||||
| include_blank: t(".none"), | ||||||
| multiple: true, | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -77,7 +77,7 @@ | |||||
| "data-auto-submit-form-target": "auto" %> | ||||||
|
|
||||||
| <%= ef.select :tag_ids, | ||||||
| Current.family.tags.alphabetically.pluck(:name, :id), | ||||||
| Current.family.tags.sorted_naturally.pluck(:name, :id), | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Align with DB scope for consistent, efficient natural ordering Same reasoning as in _form: keep sorting in SQL and let pluck run on the DB. - Current.family.tags.sorted_naturally.pluck(:name, :id),
+ Current.family.tags.sorted_naturally_db.pluck(:name, :id),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| { | ||||||
| include_blank: t(".none"), | ||||||
| multiple: true, | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use the scope to keep it relational (no eager loading)
Switch to the DB scope so this remains chainable and avoids loading into Ruby.
📝 Committable suggestion
🤖 Prompt for AI Agents