Skip to content
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

Detect enum fields as Selects rather than as Strings #1655

Merged
merged 3 commits into from
Jun 2, 2020
Merged

Detect enum fields as Selects rather than as Strings #1655

merged 3 commits into from
Jun 2, 2020

Conversation

tadeusz-niemiec
Copy link
Contributor

@tadeusz-niemiec tadeusz-niemiec commented May 18, 2020

Fixes #1629
Improve enum field definition in the dashboard generator

@tadeusz-niemiec
Copy link
Contributor Author

This fails due to the vulnerabilities found in 6.0.2.2 version of some action gems, not sure if it's ok to bump them in this PR.

@stevenbuccini
Copy link

Thanks for putting this up, just ran into this problem and it was really nice to see that someone had taken the time to make it better.

@pablobm
Copy link
Collaborator

pablobm commented May 21, 2020

Don't worry about the vulns. We just upgraded some gems, so a rebase might be enough.

@pablobm
Copy link
Collaborator

pablobm commented May 21, 2020

Regarding the PR, I think it could do the trick, although here's another potential idea.

Since #1589 (not yet released in the gem) it's possible to pass a call-able as collection, for example a lambda. Therefore I wonder if it would be possible to use ATTRIBUTE_TYPE_MAPPING, and then ATTRIBUTE_OPTIONS_MAPPING with something that generates the values.

There's one problem I see: at the moment, call doesn't pass any arguments, so it's not possible to know anything about the field inside the lambda. I think it would be reasonable to pass the field instance at the following location:

return maybe_proc.call if maybe_proc.respond_to? :call

Then we can have the field be something like this:

state: Field::Select.with_options(
  collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys) },
)

OK, I'm not 100% sure of what I'm saying... The good thing about your approach is that it impacts only the generator, so no interfaces have to change. I have to think about this.

Thoughts anyone? /cc @nickcharlton

@tadeusz-niemiec
Copy link
Contributor Author

tadeusz-niemiec commented May 22, 2020

@pablobm alright, I think I figured it out. The only problem here is that it's pretty tricky to fetch Proc's definition as a String. The easiest way is to read the definition line from a file and parse it, but this forces us to define Procs in one line (or write a really good parser for multi-liners). The other solution would be to add a external gem to handle this, but it's an additional dependency.

Please let me know what you think about this.

(I have to violate the line length rule in ATTRIBUTE_OPTIONS_MAPPING since I use one-line definition parser)

Copy link
Member

@nickcharlton nickcharlton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few style comments; I don't find myself with many implementation thoughts, so I'll defer to @pablobm here as he's already thinking about it.

remove_constants :Shipment, :ShipmentDashboard
end

it "properly handles collection procs option in the 'Select' field" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can drop "properly" on this descriptor.

enum: { searchable: false },
# procs must be defined in one line!
enum: { searchable: false,
collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys } },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little thing, but I wonder if we can use the lamdba do; end syntax here to achieve the same goal?

Copy link
Contributor Author

@tadeusz-niemiec tadeusz-niemiec May 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It all depends on how good the parser will be, because I fetch raw file line there and parse it using regexp. We'll see how this idea works out and I'll try to implement parser for all possible syntaxes if it's the way to go.

@@ -1,13 +1,12 @@
require "rails/generators/named_base"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the the deleted line back in?

@nickcharlton nickcharlton changed the title Fixes thoughtbot/administrate#1629 Detect enum fields as Selects rather than as Strings May 22, 2020
@nickcharlton nickcharlton added feature new functionality that’s not yet implemented fields new fields, displaying and editing data labels May 22, 2020
enum: { searchable: false },
# procs must be defined in one line!
enum: { searchable: false,
collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys } },
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metrics/LineLength: Line is too long. [108/80]

Copy link
Collaborator

@pablobm pablobm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I think I prefer your approach to what I mentioned. Your change only affects generators and doesn't change the internal APIs. It'll be safer particularly as we are starting to think about changing those APIs and we'll want to be careful about it.

If you can address that last couple of comments, I think we can merge this.

@tadeusz-niemiec
Copy link
Contributor Author

tadeusz-niemiec commented Jun 1, 2020

OK, I think I prefer your approach to what I mentioned. Your change only affects generators and don't change the internal APIs. It'll safer particularly as we are starting to think about changing those APIs and we'll want to be careful about it.

Do you mean that I should revert this to the previous version? Because actually it does what you mentioned, but imho it's pretty safe - the only difference in the select field is one ternary operator to check if proc requires any arguments.

I've upgraded my regexp so it will handle do |arg|; block end definitions in the current solution.

btw some vulns were found

@nickcharlton
Copy link
Member

Kaminari's update was merged in #1659 so if you rebase against current master it'll solve that vulnerability.

Copy link
Collaborator

@pablobm pablobm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see 😅 Sorry, I should have paid more attention.

Hm, I have to admit I'm easy. Your change (sending the field as an argument) actually looks good, and I think it's the reasonable thing to do. I don't think we'd have done differently in the future.

@pablobm pablobm merged commit db2b36c into thoughtbot:master Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature new functionality that’s not yet implemented fields new fields, displaying and editing data
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enum fields should be generated as Field::Select instead of Field::String
4 participants