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

Bug/57508 custom fields with format string text bool link and date dont forbid multi select internally and have handling in ordering #16570

Merged
17 changes: 5 additions & 12 deletions app/models/custom_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def uniqueness_of_name_with_scope
validates :min_length, numericality: { less_than_or_equal_to: :max_length, message: :smaller_than_or_equal_to_max_length },
unless: Proc.new { |cf| cf.max_length.blank? }

validates :multi_value, absence: true, unless: :multi_value_possible?
validates :allow_non_open_versions, absence: true, unless: :allow_non_open_versions_possible?

before_validation :check_searchability
after_destroy :destroy_help_text

Expand Down Expand Up @@ -277,22 +280,12 @@ def boolean?
field_format == "bool"
end

def multi_value?
multi_value
end

def multi_value_possible?
%w[version user list].include?(field_format) &&
[ProjectCustomField, WorkPackageCustomField, TimeEntryCustomField, VersionCustomField].include?(self.class)
end

def allow_non_open_versions?
allow_non_open_versions
%w[version user list].include?(field_format)
Copy link
Contributor

Choose a reason for hiding this comment

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

You could also write it like this:

version? || user? || list?

which would be more in line with the implemenation of allow_non_open_versions_possible?. But that is just an idea and not a necessity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also noticed it, but too quickly ignored probably thinking about efficiency, but version? || user? || list? is also more explicit

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made me wonder, also not important in this case, but it is not even slower:

require 'benchmark/ips'

class CustomField
  attr_reader :field_format

  def initialize(field_format)
    @field_format = field_format
  end

  def list?
    field_format == "list"
  end

  def version?
    field_format == "version"
  end

  def user?
    field_format == "user"
  end

  def multi_value_possible1?
    %w[version user list].include?(field_format)
  end

  def multi_value_possible2?
    version? || user? || list?
  end
end

cfs = [
  CustomField.new('version'),
  CustomField.new('user'),
  CustomField.new('list'),
  CustomField.new('foobar'),
]

Benchmark.ips do |x|
  x.report('include?') { cfs.each(&:multi_value_possible1?) }

  x.report('x? || y? || z?') { cfs.each(&:multi_value_possible2?) }

  x.compare!
end

gives

Warming up --------------------------------------
            include?   173.006k i/100ms
      x? || y? || z?   185.909k i/100ms
Calculating -------------------------------------
            include?      1.731M (± 0.6%) i/s  (577.81 ns/i) -      8.823M in   5.098375s
      x? || y? || z?      1.851M (± 0.4%) i/s  (540.34 ns/i) -      9.295M in   5.022755s

Comparison:
      x? || y? || z?:  1850702.9 i/s
            include?:  1730668.9 i/s - 1.07x  slower

end

def allow_non_open_versions_possible?
version? &&
[ProjectCustomField, WorkPackageCustomField, TimeEntryCustomField, VersionCustomField].include?(self.class)
version?
end

##
Expand Down
8 changes: 2 additions & 6 deletions app/models/custom_field/order_statements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,8 @@ def order_statements
else
[select_custom_option_position]
end
when "string", "text", "date", "bool", "link"
if multi_value?
[select_custom_values_as_group]
else
[coalesce_select_custom_value_as_string]
end
when "string", "date", "bool", "link"
[coalesce_select_custom_value_as_string]
when "int", "float"
# Make the database cast values into numeric
# Postgresql will raise an error if a value can not be casted!
Expand Down
4 changes: 2 additions & 2 deletions app/views/custom_fields/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ See COPYRIGHT and LICENSE files for more details.
</span>
</div>

<% if @custom_field.new_record? || @custom_field.list? || @custom_field.multi_value_possible? %>
<% if @custom_field.new_record? || @custom_field.multi_value_possible? %>
<div class="form--field" <%= format_dependent.attributes(:multiSelect) %>>
<%= f.check_box :multi_value,
data: { action: 'admin--custom-fields#checkOnlyOne' } %>
Expand Down Expand Up @@ -118,7 +118,7 @@ See COPYRIGHT and LICENSE files for more details.
</fieldset>
<% end %>

<% if @custom_field.new_record? || @custom_field.version? || @custom_field.allow_non_open_versions_possible? %>
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the cleanup in here. It was confusing before.

<% if @custom_field.new_record? || @custom_field.allow_non_open_versions_possible? %>
<div class="form--field" <%= format_dependent.attributes(:allowNonOpenVersions) %>>
<%= f.check_box :allow_non_open_versions %>
</div>
Expand Down