-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Move category dropdown menu content into a turbo frame #782
Move category dropdown menu content into a turbo frame #782
Conversation
@jakubkottnauer nice idea on the lazy loaded turbo frame, I definitely agree that we should be utilizing that for this scenario. I don't mind the slight delay, but I think we could probably add some sort of "skeleton" loader, maybe something like this?
Also, the
|
be740f8
to
c9f30f7
Compare
@zachgoll Thank you for the review! Though I ended up defining the route differently; your suggestion results in path Let me know if there's a nicer way to define such a route, I'm still quite new to RoR :) |
c9f30f7
to
a620ba0
Compare
d9259d1
to
96eff4d
Compare
@jakubkottnauer let me start by saying that the following suggestions are not necessarily 100% related to this specific PR, so if you'd like to get this change in and ignore these for now, I'm fine with that. Just let me know and I'll get it merged. But I think why we're having such a hard time with this one is because our existing routing structure for transactions and categories doesn't fit the "singular" nature of a transaction category (i.e. a transaction can have a max of 1 category). We've currently got it setup like so: resources :transactions do
match "search" => "transactions#search", on: :collection, via: %i[ get post ], as: :search
collection do
scope module: :transactions do
resources :categories, as: :transaction_categories do
resources :deletions, only: %i[ new create ], module: :categories
end
resources :rules, only: %i[ index ], as: :transaction_rules
resources :merchants, only: %i[ index new create edit update destroy ], as: :transaction_merchants
end
end
end If I'm not mistaken here, I think a better way to express all of this would be: resources :transactions do
match "search" => "transactions#search", on: :collection, via: %i[ get post ], as: :search
resources :rules, only: %i[ index ], module: :transactions
resources :merchants, only: %i[ index new create edit update destroy ], module: :transactions
resource :category, module: :transactions do
resource :dropdown, only: %i[ new ], module: :categories
resource :deletion, only: %i[ new create ], module: :categories
end
end The routes this produces are fairly similar to what we have already, but feel a little more natural to me and expose the transaction ID that we need by default: To implement this we'd need to rename a few folders, but IMO this would be a good improvement to what we currently have. Would be happy to hear other ideas and critiques to this. We'd also need a separate routing structure to independently manage these categories (i.e. in the Settings view), but I think that would be okay to have both the general editing and transaction-specific editing? |
@josefarias no worries if you're busy with other things, but curious to hear if you'd agree with the comment above? |
@jakubkottnauer @josefarias disregard my comment above about the singular resources. I wasn't reading things correctly before and see why we need the "collection" (to edit these outside the context of a transaction). Wondering if we just add this above the existing route structure? resources :transactions do
# new_transaction_category_dropdown -> /transactions/:transaction_id/category/dropdown/new
namespace :category, module: :transactions do
resource :dropdown, only: %i[ new ], module: :categories
end
... existing routes
end |
Hey @zachgoll @jakubkottnauer, great work here! Here's how I'd suggest modeling this: diff --git a/config/routes.rb b/config/routes.rb
index 909870a..b4ff237 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -44,6 +44,10 @@ Rails.application.routes.draw do
scope module: :transactions do
resources :categories, as: :transaction_categories do
resources :deletions, only: %i[ new create ], module: :categories
+
+ collection do
+ resource :dropdown, only: :show, module: :categories, as: :transaction_categories_dropdown
+ end
end
resources :rules, only: %i[ index ], as: :transaction_rules Could also do Here's the reasoning behind that:
As far as rendering the actual dropdown, I'd do something like this in the controller (pseudocode, not tested): class Transactions::Categories::DropdownsController < ApplicationController
before_action :set_selected_category
def show
@categories = categories_scope.excluding(@selected_category).prepend(@selected_category).compact
end
private
def set_selected_category
if params[:selection_id]
@selected_category = categories_scope.find(params[:selection_id])
end
end
def categories_scope
Current.family.transaction_categories.alphabetically
end
end |
@josefarias appreciate the help here! I think what you've outlined makes sense and I'd agree that The helper name you came up with makes sense to me as well. As I was playing around with the routes, came up with the following, which attempts to leverage auto-generated path helper names a bit more: resources :transactions do
collection do
match "search" => "transactions#search", via: %i[ get post ]
scope module: :transactions, as: :transaction do
resources :categories do
resources :deletions, only: %i[ new create ], module: :categories
resource :dropdown, only: :show, on: :collection, module: :categories
end
resources :rules, only: %i[ index ]
resources :merchants, only: %i[ index new create edit update destroy ]
end
end
end The only change that would be required to get tests passing again is update the Any objections to this? |
No objections! I like that better as well |
@josefarias awesome, thanks again for the assist here! @jakubkottnauer if you're good with the discussion and proposed changes above, I think we've got a path forward? Looks like you've got all the pieces here, just need a slight rework of the routing and the update to |
87d830c
to
49c04cd
Compare
@josefarias @zachgoll Thank you both for the great suggestions, I think we've gotten something really nice out of it 👍 I have implemented the changes. I ended up doing collection do
resource :dropdown, only: :show, module: :categories, as: :category_dropdown
end
# -> /transactions/categories/dropdown instead of resource :dropdown, only: :show, on: :collection, module: :categories
# -> /transactions/categories/:category_id/dropdown because the latter doesn't work when no category is selected on a transaction. I'm a bit surprised that just wrapping the resource with |
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.
Looks good! Thanks for the iterations on this.
And to your question about the collection
block—that's my bad, resource
and resources
do not accept an on
option. It was just silently failing there. So I think your solution is the right one!
db/schema.rb
Outdated
@@ -87,7 +87,7 @@ | |||
t.uuid "accountable_id" | |||
t.decimal "balance", precision: 19, scale: 4, default: "0.0" | |||
t.string "currency", default: "USD" | |||
t.virtual "classification", type: :string, as: "\nCASE\n WHEN ((accountable_type)::text = ANY ((ARRAY['Account::Loan'::character varying, 'Account::Credit'::character varying, 'Account::OtherLiability'::character varying])::text[])) THEN 'liability'::text\n ELSE 'asset'::text\nEND", stored: true | |||
t.virtual "classification", type: :string, as: "\nCASE\n WHEN ((accountable_type)::text = ANY (ARRAY[('Account::Loan'::character varying)::text, ('Account::Credit'::character varying)::text, ('Account::OtherLiability'::character varying)::text])) THEN 'liability'::text\n ELSE 'asset'::text\nEND", stored: 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.
You had updated to v16.x right? Maybe this isn't related to the PG version after all.
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.
My bad, I haven't noticed this has snuck in again, reverted. But yes, I had upgraded to 16.3 and still get this schema change when I run bin/setup
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.
Interesting, I'll have to look into this again and see if there's a way to avoid in the future.
This PR fixes (or at least improves by a large margin) the performance issues reported in #739.
Each transaction row comes with a huge amount of HTML representing the contents of the category dropdown, 99% of which will never viewed by the user. Moving the dropdown contents into a lazily loaded turbo frame makes an account page with 1k transaction about 20x smaller (2.5 MB instead of 51 MB).
Before
After
After this change there is a slight delay when you click a category badge before the dropdown contents are loaded, but it seems ok with a reasonable amount of categories. This can be further improved in the future by prefetching the dropdown contents when the badge is hovered.