-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Fix Active Filter Labeling and Record Not Found #5223
Fix Active Filter Labeling and Record Not Found #5223
Conversation
@@ -19,7 +19,7 @@ def initialize(resource, condition) | |||
def values | |||
condition_values = condition.values.map(&:value) | |||
if related_class | |||
related_class.find(condition_values) | |||
related_class.where(id: condition_values) |
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.
Using id
here isn't ideal because the primary key column may be some other field on the record.
Other locations dynamically lookup the primary key:
activeadmin/lib/active_admin/resource.rb
Line 197 in 5b711b6
[:find_by, { resource_class.primary_key => id }] |
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.
Yup. Great catch. 🙈
@varyonic @zorab47 The coverage failure for the last commit looks like a false positive to me. But if the ✅ is desired, I can rejig that line so it is "covered" by codecov pov. Just let me know. |
Right, CodeCov doesn't get it when you split a method chain across more than two lines. |
c17be84
to
76c5e68
Compare
I amended the commit to put that method chain on one line then. 👍 |
@zorab47 I think you'll need to re-approve these changes (since I added the association primary key support). Also let me know if a rebase is necessary. |
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.
Good catch on primary key
reject { |r| r.options[:polymorphic] }. #skip polymorphic | ||
detect { |r| r.foreign_key.to_s == name.to_s } | ||
assoc.class_name.constantize if assoc | ||
predicate_association.class_name.constantize if predicate_association |
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.
Should this become an elsif
for easier reading?
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.
It was like that previously, so I didn't know if it was convention to avoid if - elsif statements with no else.
if predicate_association | ||
predicate_association.active_record_primary_key | ||
else | ||
related_class.primary_key if related_class |
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.
Should this become an elsif
for easier reading?
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.
Like line 93, since a there were other places where it seemed that dangling if - elsif weren't preferred, I stuck with the if - else. But IMHO I agree that it should just be an if - elsif block
end | ||
end | ||
|
||
def predicate_association |
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.
@wspurgin maybe you can add cashing this method using instance_variable_defined?
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.
Would you prefer instance_variable_defined?
or just:
def predicate_association
@predicate_association ||= find_predicate_association
end
def find_predicate_association
#...
end
|
||
filter[:label] | ||
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.
def filter_label
filter && filter[:label]
end
if predicate_association | ||
predicate_association.active_record_primary_key | ||
elsif related_class | ||
related_class.primary_key |
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.
Personally I like terse boolean operators over if/else:
def related_primary_key
predicate_association && predicate_association.active_record_primary_key ||
related_class && related_class.primary_key
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.
Hurts readability though. You'll still need a block to return the proper primary key (as that only returns a . Scratch that. It returns the proper value, but I still think it hurts readability.true
or false
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.
It's a personal preference, maybe from writing too much C or perl. :-)
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.
Definitely understand. I think I leave it as is for now though. It'll help me understand what's going on more quickly if I look at in a month than chained binary operators. 🙈
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 reasonable, though I've not worked on this before. Yes, a rebase and squash corrections would be good.
end | ||
end | ||
|
||
def predicate_association | ||
@predicate_association ||= find_predicate_association |
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.
@wspurgin since find_predicate_association can return nil,
method can look like
return @predicate_association if defined? @predicate_association
@predicate_association ||= find_predicate_association
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.
Gotcha. That way we don't iterate every time if their is no predicate association. I'll make that update.
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 sufficient if you know it's not defined. Alternately:
@predicate_association = find_predicate_association unless defined?(@predicate_association)
@predicate_association
32308be
to
ab9ca47
Compare
@varyonic Rebased. |
Use label on the filter as the prefix (if given) Also move other prefixes' logic into separate methods for cleanliness. Support rails 4.2 in specs Use related class' primary key
Use association primary key when possible Closes activeadmin#5164 Use elsif to enhance readability Cache predicate_association Only search for predicate once
ab9ca47
to
3b154b1
Compare
@varyonic rebased and squashed. Thanks for the fixing the builds! 💯 |
👋
ActiveFilter
was added to make the current filter sidebar a bit more humanized. It adds some cool things like smart, humanized filter names and, where possible, link to related resources with human readable names! Very cool. However, there's a few issues I saw when messing around a bit.ActiveFilter
defines it) is given conditions that have no matching records in the related class,ActiveFilter
produces anActiveRecord::RecordNotFound
when trying to generate a set of values to display in the "Current Filters" sidebar.ActiveFilter
ignores it in favor of pulling fromi18n
. This doesn't seem too terrible but can pose problems to the developer (see below)The first issue I believe to be a regression. Even though, truthfully, there is no related record matching the filter criteria (and thus no resource records either), AA would display a blank slate in all other cases where a filter(s) produces no matching records.
The second issue, is more subtle. Most cases of custom labels are covered by the current implementation of
ActiveFilter
. After all, if you want the label ofPost#title
to be something other than "Title" just put it inside ofen.yml
, andActiveFilter
will do as you command. Here's the rub, imagine a more complex translation situation:In this example, we have an interpolation within our translation because the translation changes based on who's bought our super shiny app. In this situation,
ActiveFilter
would produce aI18n::MissingInterpolationArgument
when trying to render the Current Filter sidebar with this attribute.While this example is a bit contrived, IMHO it's better to go with whatever the developer specifies as the attribute name. If the label on the filter is set, then that's takes precedence. If not, then the translations are certainly the next best thing.
Related issues: