-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add support for editing polymorphic fields #984
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
Conversation
spec/lib/fields/polymorphic_spec.rb
Outdated
|
||
describe '#selected_global_id' do | ||
it "returns the global ID of the data" do | ||
item = double('SomeModel', to_global_id: "gid://myapp/SomeModel/1") |
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.
Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
spec/lib/fields/polymorphic_spec.rb
Outdated
@@ -37,4 +38,16 @@ def display_resource(*) | |||
end | |||
end | |||
end | |||
|
|||
describe '#selected_global_id' do |
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.
Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
spec/lib/fields/polymorphic_spec.rb
Outdated
@@ -37,4 +38,16 @@ def display_resource(*) | |||
end | |||
end | |||
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.
Trailing whitespace detected.
def candidate_resources(klass) | ||
order ? klass.order(order) : klass.all | ||
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.
Trailing whitespace detected.
def order | ||
@_order ||= options.delete(:order) | ||
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.
Trailing whitespace detected.
def self.permitted_attribute(attr) | ||
attr | ||
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.
Trailing whitespace detected.
end ] | ||
end | ||
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.
Trailing whitespace detected.
classes.map do |klass| | ||
[ klass.to_s, candidate_resources(klass).map do |resource| | ||
[display_candidate_resource(resource), resource.to_global_id] | ||
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.
Space inside square brackets detected.
class Polymorphic < BelongsTo | ||
def associated_resource_grouped_options | ||
classes.map do |klass| | ||
[ klass.to_s, candidate_resources(klass).map do |resource| |
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.
Space inside square brackets detected.
@@ -120,7 +120,7 @@ def resource_includes | |||
|
|||
def resource_params | |||
params.require(resource_class.model_name.param_key). | |||
permit(dashboard.permitted_attributes) | |||
permit(dashboard.permitted_attributes).transform_values {|v| v.respond_to?(:starts_with?) && v.starts_with?("gid://") ? GlobalID::Locator.locate(v) : v } |
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.
Space between { and | missing.
Line is too long. [162/80]
permit(dashboard.permitted_attributes) | ||
permit(dashboard.permitted_attributes). | ||
transform_values do |v| | ||
(v.respond_to?(:starts_with?) && v.starts_with?("gid://")) ? |
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.
Avoid multi-line ternary operators, use if or unless instead.
Omit parentheses for ternary conditions.
d772304
to
0956238
Compare
any plans to implement this? or any polymorphic field solution? |
@pedantic-git - Thank you for your PR. I've been having a look at this and I like the general direction. You are right that the implementation of The main change is in how to deal with this global id. Instead of relying on the global id only, I split the field in two:
Then Something to note is that the Additionally, I added some tests. I may add a couple more, but this does pretty well for now. Closing this as it's superseded by the new PR. |
This adds support for editing polymorphic fields. Props go to @pedantic-git, on whose work this is based. This PR supersedes #984. An important aspect of this PR is how it handles the polymorphic value. At heart, polymorphic values are split in two: an id and a type. Using [the `globalid` gem](https://github.com/rails/globalid) we can obtain a string that represents both. However, we still need to tell that this string is indeed a globalid and not a literal value when we get to `Administrate::ApplicationController#resource_params`. I handle this by splitting the field in two: * `my_field[value]`: the global id, which includes both type and instance id. * `my_field[type]`: literally `"Administrate::Field::Polymorphic"` Then `#resource_params` can look at the param values and treat them appropriately. If it's a simple value such a string, it does nothing special. However, if it comes in this value/type form, we treat it as polymorphic, reading the global id.
This adds support for editing polymorphic fields. Props go to @pedantic-git, on whose work this is based. This PR supersedes thoughtbot/administrate#984. An important aspect of this PR is how it handles the polymorphic value. At heart, polymorphic values are split in two: an id and a type. Using [the `globalid` gem](https://github.com/rails/globalid) we can obtain a string that represents both. However, we still need to tell that this string is indeed a globalid and not a literal value when we get to `Administrate::ApplicationController#resource_params`. I handle this by splitting the field in two: * `my_field[value]`: the global id, which includes both type and instance id. * `my_field[type]`: literally `"Administrate::Field::Polymorphic"` Then `#resource_params` can look at the param values and treat them appropriately. If it's a simple value such a string, it does nothing special. However, if it comes in this value/type form, we treat it as polymorphic, reading the global id.
This adds support for editing polymorphic fields. Props go to @pedantic-git, on whose work this is based. This PR supersedes thoughtbot/administrate#984. An important aspect of this PR is how it handles the polymorphic value. At heart, polymorphic values are split in two: an id and a type. Using [the `globalid` gem](https://github.com/rails/globalid) we can obtain a string that represents both. However, we still need to tell that this string is indeed a globalid and not a literal value when we get to `Administrate::ApplicationController#resource_params`. I handle this by splitting the field in two: * `my_field[value]`: the global id, which includes both type and instance id. * `my_field[type]`: literally `"Administrate::Field::Polymorphic"` Then `#resource_params` can look at the param values and treat them appropriately. If it's a simple value such a string, it does nothing special. However, if it comes in this value/type form, we treat it as polymorphic, reading the global id.
This PR allows users to edit
Field::Polymorphic
fields (previously they were just told this was not possible).The
<select>
is a grouped select, populated using the contents of zero-or-more model classes specified in the:classes
option.I appreciate I haven't really added much in the way of testing for this, but I think it's comparable with the amount of testing the other complex built-in types already have (e.g.
Field::HasMany
).The one place in the core that's changed here and might be controversial, is that
#resource_params
now auto-converts anything that looks like a GlobalID. This is necessary for a polymorphic field without JavaScript as GlobalIDs are the only IDs that work across multiple models. Let me know if you need this implementing a different way.