diff --git a/app/models/custom_attributes/custom_attribute_definition.rb b/app/models/custom_attributes/custom_attribute_definition.rb index 324ae3a..b5de77d 100644 --- a/app/models/custom_attributes/custom_attribute_definition.rb +++ b/app/models/custom_attributes/custom_attribute_definition.rb @@ -5,11 +5,16 @@ module CustomAttributeDefinition scope :by_sort_order, -> { order('sort_order ASC') } validates :attr_name, presence: true, format: { with: /^[a-zA-Z\_\s]+$/, multiline: true, message: 'cannot contain special characters.' } validates :default_value, format: { with: /^[\+\-]?\d*\.?\d*$/, multiline: true, message: 'should be a number.' }, if: :number_type? + validate :can_be_marked_as_unique def number_type? [CustomAttributes::CustomAttribute::TYPE_NUMBER, CustomAttributes::CustomAttribute::TYPE_DECIMAL].include?(attr_type) end + def text_type? + attr_type == CustomAttributes::CustomAttribute::TYPE_TEXT + end + def boolean_type? attr_type == CustomAttributes::CustomAttribute::TYPE_BOOLEAN end @@ -30,6 +35,7 @@ def save_custom_attribute(selected_option_label) begin transaction do self.custom_attribute_options = [] unless has_options? + default_value = "" if unique? save! if has_options? update! default_value: custom_attribute_options.find_by(label: selected_option_label).try(:id) @@ -44,6 +50,7 @@ def save_custom_attribute(selected_option_label) def update_custom_attribute(custom_attribute_params, selected_option_label) begin transaction do + custom_attribute_params[:default_value] = "" if unique? update!(custom_attribute_params) if has_options? update! default_value: custom_attribute_options.find_by(label: selected_option_label).try(:id) @@ -58,6 +65,32 @@ def update_custom_attribute(custom_attribute_params, selected_option_label) def default_option custom_attribute_options.find_by(id: default_value) end + + def can_be_marked_as_unique + if unique? + if !can_be_unique? + errors.add :base, 'Can not be made as unique!' + elsif has_duplicate_values? + errors.add :base, 'Remove duplicate values first to make is unique.' + end + end + errors.blank? + end + + def can_be_unique? + text_type? || number_type? + end + + def has_duplicate_values? + column = { + CustomAttributes::CustomAttribute::TYPE_TEXT => 'string_value', + CustomAttributes::CustomAttribute::TYPE_NUMBER => 'integer_value', + CustomAttributes::CustomAttribute::TYPE_DECIMAL => 'double_value', + }[attr_type] + return false if column.blank? + duplicate_cavs = custom_attribute_values.where("#{column} IS NOT NULL").select("#{column}, count(*) as values_count").group(column).having("count(*) > 1") + duplicate_cavs.present? + end end end end \ No newline at end of file diff --git a/app/models/custom_attributes/custom_attributes_utilities.rb b/app/models/custom_attributes/custom_attributes_utilities.rb new file mode 100644 index 0000000..7f7d19c --- /dev/null +++ b/app/models/custom_attributes/custom_attributes_utilities.rb @@ -0,0 +1,24 @@ +module CustomAttributes + module CustomAttributesUtilities + extend ActiveSupport::Concern + + included do + after_save :check_duplicate_custom_attributes + end + + def check_duplicate_custom_attributes + return unless self.custom_attribute_defn.unique? + column_maping = { + "#{self.owner.class.name}CustomAttributeStringValue" => 'string_value', + "#{self.owner.class.name}CustomAttributeIntegerValue" => 'integer_value', + "#{self.owner.class.name}CustomAttributeDoubleValue" => 'double_value', + } + + return if column_maping[self.class.name].blank? + if self.value.present? + duplicate_count = self.class.where("#{column_maping[self.class.name]} = ?", self.value).count + raise StandardError.new("Duplicate value for '#{self.custom_attribute_defn.attr_name}'") if duplicate_count > 1 + end + end + end +end \ No newline at end of file diff --git a/app/views/custom_attributes/custom_attribute_definitions/_form_fields_only.html.erb b/app/views/custom_attributes/custom_attribute_definitions/_form_fields_only.html.erb index f6462e6..05f38b0 100644 --- a/app/views/custom_attributes/custom_attribute_definitions/_form_fields_only.html.erb +++ b/app/views/custom_attributes/custom_attribute_definitions/_form_fields_only.html.erb @@ -57,4 +57,17 @@ <% if new_record %> <%= f.hidden_field :sort_order %> -<% end %> \ No newline at end of file +<% end %> + +
+