-
-
Notifications
You must be signed in to change notification settings - Fork 62
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
Refactor how Rails handles filter categories passed to and from Vue #546
Conversation
2d217cf
to
cf69d4f
Compare
cf69d4f
to
9bb4c30
Compare
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.
This is now functional
TODO:
- add tests
- check if everyone feels this is legible enough
- add additional filters (maybe in a separate PR)
- discuss sorting results on the Vue side
I added a bunch of comments. Please suggest cleanup/rewording/etc. of them, whatever would help you understand the code better
Sorry, @maebeale, for the flipping back and forth about what goes in instances and what goes in classes. I added on to your work some of the structure I thought @exbinary was interested in, but I might have misremembered that whole conversation
def scopes | ||
classes = parameters.blank? ? ALL_ALLOWED_TYPES : parameters.keys | ||
classes.intersection(ALL_ALLOWED_TYPES).map do |type| | ||
type.constantize.matchable |
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.
Is this right — that matchable
is what we want here?
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.
yes. we'll need to add that scope to CommunityResource
to return objects that are still published
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 great, @h-m-m ! A few comments inline but overall really like how this is shaping.
app/filters/contact_method_filter.rb
Outdated
|
||
def filter(scope) | ||
return super unless parameters | ||
scope.joins(:person).where(people: { preferred_contact_method: parameters.keys }) |
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.
I'm noticing all the filters use parameters.keys
. Could we get the keys in BrowseFilter
or BaseFilter.new
and make just the keys available to individual filters?
Relatedly, the shape of parameters
is not clear from looking at the code. Could be solved by looking at specs, or maybe a comment describing how params will come in?
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.
the shape of parameters is not clear from looking at the code
This is really the key point here. Thanks for surfacing this, because this point is helping me find the most confusing points.
I started writing some tests around this and got stuck because it was hard. I think I've introduced a small, modest mess in BrowseFilter#contributions
and cleaning up the parameters structure here is dependent on cleaning that up, too.
There's a part of me that wants to get this PR out first and then focus on cleaning up that problem. I want to do that because this PR has taken a very long time and not directly for any code-specific reasons. This PR seems so big to me already, and I'd really like to focus on the refactor I'll need here as a separate thing from the other changes in this PR.
I'm open to suggestions. Let me know what you think
app/filters/category_filter.rb
Outdated
{ | ||
name: "Categories", | ||
# Currently only filtering by top-level categories | ||
filters: FilterOptionsBlueprint.render_as_hash(Category.roots) | ||
} |
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.
Serializing inside the filters doesn't feel quite right. Is it possible to have options
return a relation as the value of filters
and let the controller handle serialization?
{ | |
name: "Categories", | |
# Currently only filtering by top-level categories | |
filters: FilterOptionsBlueprint.render_as_hash(Category.roots) | |
} | |
{ | |
name: "Categories", | |
# Currently only filtering by top-level categories | |
filters: Category.roots | |
} |
This might require introducing another blueprint at the level of a filter that then has an association :filters
.
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 only issue with your suggestion is that the Ask/Offer distinction is one I'm doing manually:
mutual-aid/app/filters/contribution_type_filter.rb
Lines 1 to 7 in 39a0d09
class ContributionTypeFilter | |
def self.filter_group | |
{ name: 'Contribution Types', filter_options: [ | |
{ id: 'ContributionType[Ask]', name: 'Ask' }, | |
{ id: 'ContributionType[Offer]', name: 'Offer' } | |
]} | |
end |
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.
Ah yes, i see the challenge. I had a go at extracting the serialization out in 8b8c8a9, curious your thoughts?
In any case, i don't think this question should hold up this PR.
8799453
to
39a0d09
Compare
We may want to later check the Vue side so that they're both consistent
0b47685
to
5062a99
Compare
Conflicts: * CHANGELOG.md * app/controllers/contributions_controller.rb * app/models/browse_filter.rb * app/models/category.rb * app/models/contribution_type.rb * spec/blueprints/contribution_blueprint_spec.rb * spec/blueprints/filter_type_blueprint_spec.rb
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.
@h-m-m , i merged main, resolved conflicts and pushed to this branch.
Should be good to merge once you give it a quick look.
Notes on what we're thinking of following up on as a subsequent refactoring:
|
Why
The contribution filtering works nicely, but difficult to understand. We'd like to add new filters, and that's hard at the moment. I wrote the original code and am unhappy with how confusing it is. Its confusing complexity is what makes adding or editing filters more difficult for us, and also slows down bringing people into the project and up to speed on how all this stuff works.
What
The big change is making each type of filter its own class.
Each class
Also used this opportunity to:
And hopefully this will make adding new filters easier in the future
Testing
Updated some tests. Could probably use more work in this regard
Next Steps
Some next steps are already called out in the comments when this PR was in Draft status.
Also: add a filter for Date now that it should be easier to do so
Accessibility
We were very careful to leave the existing UI unchanged in any visible way, so this should be accessibility-neutral
Security
Hopefully this improves the security what with less dynamic/functional code and code that's easier for future devs to maintain
Pre-Merge Checklist