module HasUniqueAttribute
Constants
- VERSION
Public Instance Methods
has_unique_attribute(attribute_name, index: default_index_name_for_attribute(attribute_name), message: :taken)
click to toggle source
@param attribute_name [String] @param index [String] @param message [Symbol, String] @return [void]
# File lib/has_unique_attribute.rb, line 8 def has_unique_attribute(attribute_name, # rubocop:disable Naming/PredicateName index: default_index_name_for_attribute(attribute_name), message: :taken) assert_unique_index_defined!(index) handle_unique_attribute_on_save(attribute_name, index, message) handle_unique_attribute_on_save!(attribute_name, index, message) end
Private Instance Methods
assert_unique_index_defined!(index_name)
click to toggle source
@param index_name [String] @return [void]
# File lib/has_unique_attribute.rb, line 21 def assert_unique_index_defined!(index_name) index = connection.indexes(table_name).find { |index_definition| index_definition.name == index_name } raise ArgumentError, "#{name} does not have index: `#{index_name}`" if index.nil? raise ArgumentError, "#{name} defines an index `#{index_name}`, but it is not unique" unless index.unique end
default_index_name_for_attribute(attribute_name)
click to toggle source
@param attribute_name [String] @return [String]
# File lib/has_unique_attribute.rb, line 30 def default_index_name_for_attribute(attribute_name) "index_#{table_name}_on_#{attribute_name}" end
handle_unique_attribute_on_save(attribute_name, index_name, message)
click to toggle source
@param attribute_name [String] @param index_name [String] @param message [Symbol, String] @return [void]
# File lib/has_unique_attribute.rb, line 38 def handle_unique_attribute_on_save(attribute_name, index_name, message) existing_method = instance_method(:save) define_method(:save) do |*args, **kwargs| existing_method.bind(self).call(*args, **kwargs) rescue ActiveRecord::RecordNotUnique => error if error.message.include?(index_name) errors.add(attribute_name, message) return false end raise error end end
handle_unique_attribute_on_save!(attribute_name, index_name, message)
click to toggle source
@param attribute_name [String] @param index_name [String] @param message [Symbol, String] @return [void]
# File lib/has_unique_attribute.rb, line 58 def handle_unique_attribute_on_save!(attribute_name, index_name, message) existing_method = instance_method(:save!) define_method(:save!) do |*args, **kwargs| existing_method.bind(self).call(*args, **kwargs) rescue ActiveRecord::RecordNotUnique => error if error.message.include?(index_name) errors.add(attribute_name, message) raise ActiveRecord::RecordInvalid, self end raise error end end