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

[RFC] Do not render complex preference types as form fields #2394

Merged
merged 4 commits into from
Nov 30, 2017

Conversation

tvdeyen
Copy link
Member

@tvdeyen tvdeyen commented Nov 22, 2017

When rendering preference form fields we currently just render every
preference type defined on the preferable class.

Some classes - like solidus_paypal_braintree's Gateway - use complex types (Array and Hash) to store developer facing preferences.

Currently this leads to bugs because these preference field partials are not available.

As arrays and hashes won't represent well in a form field, we should not render them IMO.
The settings stored in these preferences are considered developer facing only.
Admins should not change these kind of values.

@kennyadsl
Copy link
Member

Great, I was thinking at what should I do if I need to show just one preference hash or array field, for example because I know it's safe in that point and I want admin to be able to change only that. Is this a scenario we want to support?

@kennyadsl
Copy link
Member

Great, I was thinking at what should I do if I need to show just one preference hash or array field, for example because I know it's safe in that point and I want admin to be able to change only that. Is this a scenario we want to support?

Ok, ignore it. I figured out I can just render another input in the view for that field outside the preferences partials code, so there's no need to support that in core.

@tvdeyen
Copy link
Member Author

tvdeyen commented Nov 23, 2017

Updated this PR so that it is now possible to overwrite the class method allowed_admin_form_preference_types on the extending class in order to change the allowed fields. One have to provide their own preference field partials if they do so.

@solidusio solidusio deleted a comment from houndci-bot Nov 23, 2017
@solidusio solidusio deleted a comment from houndci-bot Nov 23, 2017
Copy link
Contributor

@mamhoff mamhoff left a comment

Choose a reason for hiding this comment

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

I would like some naming changes to more clearly differentiate between preference and type. Otherwise, as always, great work. 👍

subject { C.new.admin_form_preference_field_types }

before do
class C
Copy link
Contributor

Choose a reason for hiding this comment

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

C is very short, and maybe someone else creates an example class C, with different behaviour. In order to avoid conflicts and possibly test order issues because of the conflict, you might want to consider naming the class ClassWithPreferences or the like.

Copy link
Contributor

Choose a reason for hiding this comment

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

Uh-oh, there's also A, B, and D. Not concern of this PR, but 🗡

<% @object.preferences.keys.each do |key| %>
<%= render "spree/admin/shared/preference_fields/#{@object.preference_type(key)}",
form: f, attribute: "preferred_#{key}", label: t(key, scope: 'spree') %>
<% @object.admin_form_preference_field_types.each do |type| %>
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems to me this is a wrong change. Given a class with preferable :color, type: :string, previously this would render the form with attribute preferred_color, whereas now it seems like it renders preferred_string, no?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, we're just not rendering a type here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, yes. You are right. Dang. Thanks for catching this!

# +app/views/spree/admin/shared/preference_fields/+
#
# @return [Array]
def admin_form_preference_field_types
Copy link
Contributor

@mamhoff mamhoff Nov 23, 2017

Choose a reason for hiding this comment

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

Previously, I misread code in a future commit because this method name includes types, prompting me to thing the result of this method is an array of type strings. Let's consider renaming it to admin_editable_preferences, so it communicates more clearly it returns an array of preferences?

@tvdeyen tvdeyen self-assigned this Nov 23, 2017
@tvdeyen tvdeyen force-pushed the hash-preference-field branch 2 times, most recently from cd14dff to 909fcf4 Compare November 24, 2017 07:41
@tvdeyen tvdeyen added the WIP label Nov 24, 2017
@tvdeyen
Copy link
Member Author

tvdeyen commented Nov 24, 2017

@mamhoff please review again

@tvdeyen tvdeyen removed the WIP label Nov 24, 2017
@tvdeyen tvdeyen removed their assignment Nov 24, 2017
Copy link
Contributor

@mamhoff mamhoff left a comment

Choose a reason for hiding this comment

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

The variables inside the forms are now inconsistent with the plural of the method name :(

<%= render "spree/admin/shared/preference_fields/#{calculator.preference_type(key)}",
name: "#{prefix}[calculator_attributes][preferred_#{key}]",
value: calculator.get_preference(key), label: t(key.to_s, scope: 'spree') %>
<% calculator.admin_form_preference_names.map do |type| %>
Copy link
Contributor

Choose a reason for hiding this comment

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

type should be name here.

@@ -19,9 +19,9 @@
<% if @object.preference_source.present? %>
<%= t('spree.preference_source_using', name: @object.preference_source) %>
<% elsif !@object.new_record? %>
<% @object.preferences.keys.each do |key| %>
<% @object.admin_form_preference_names.each do |key| %>
Copy link
Contributor

Choose a reason for hiding this comment

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

key should be name here.

<% calculator.preferences.keys.each do |key| %>
<%= render "spree/admin/shared/preference_fields/#{calculator.preference_type(key)}",
form: calculator_form, attribute: "preferred_#{key}", label: t(key, scope: 'spree') %>
<% calculator.admin_form_preference_names.each do |type| %>
Copy link
Contributor

Choose a reason for hiding this comment

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

type should be name here.

When rendering preference form fields we currently just render every
preference type defined on the preferable class. Some classes use
complex types (`Array` and `Hash`) to store developer facing preferences.
This leads to bugs where this preference field partial might not be available.

This collection helps to render only the preference form fields we have partials for.

It provides ability for the extending class to change this behavior by
overwriting the class method `allowed_admin_form_preference_types`.
…fields for

We do not ship preference form fields for Array and Hash preference types. Some extensions, like solidus_paypal_braintree, do use them to store very specific settings. As arrays and hashes won't represent well in a form field, we should not render them. The settings stored in these preferences are considered developer facing only. Admins should not change these kind of values.
…ence form fields for

We do not ship preference form fields for Array and Hash preference types. Some promotion actions might use them to store very specific settings. As arrays and hashes won't represent well in a form field, we should not render them.
We do not ship preference form fields for Array and Hash preference types. Some shipping or tax rate calculators might use them to store very specific settings. As arrays and hashes won't represent well in a form field, we should not render them.
@tvdeyen
Copy link
Member Author

tvdeyen commented Nov 25, 2017

@mamhoff addressed

@tvdeyen
Copy link
Member Author

tvdeyen commented Nov 29, 2017

@kennyadsl could you please re-review and give approval? Thanks

Copy link
Member

@kennyadsl kennyadsl left a comment

Choose a reason for hiding this comment

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

Great, everything seems fully customizable if needed. Thanks!

@tvdeyen tvdeyen merged commit b3d1491 into solidusio:master Nov 30, 2017
@tvdeyen tvdeyen deleted the hash-preference-field branch November 30, 2017 21:02
tvdeyen added a commit to tvdeyen/solidus that referenced this pull request Dec 1, 2017
After the merge of solidusio#2394
the admin promotion adjustment spec that got introduced by
solidusio#2400 broke.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants