Skip to content

Commit

Permalink
Uniqueness: Support UUID columns that end in "f"
Browse files Browse the repository at this point in the history
This commit fixes the uniqueness matcher so that when qualified with
`scoped_to` and one of the scopes is a UUID column that happens to end
in an "f", the matcher is able to generate a proper next value during
testing and doesn't error.
  • Loading branch information
mcmire committed Feb 12, 2015
1 parent 74fa081 commit 81034ea
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
10 changes: 10 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@
* `set_session['key'].to(nil)` will no longer pass when the key in question
has not been set yet.

### Bug fixes

* So far the tests for the gem have been running against only SQLite. Now they
run against PostgreSQL, too. As a result we were able to fix some
Postgres-related bugs:

* Fix `validate_uniqueness_of` + `scoped_to` so that when one of the scope
attributes is a UUID column that ends in an "f", the matcher is able to
generate a proper "next" value without erroring.

# 2.8.0

### Deprecations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,22 +393,29 @@ def validate_after_scope_change?
end

def correct_type_for_column(column)
if column.type == :string
column = column_for(scope)

case column.type
when :string
'0'
elsif column.type == :datetime
when :datetime
DateTime.now
elsif column.type == :uuid
when :uuid
SecureRandom.uuid
else
0
end
end

def next_value_for(scope, previous_value)
if @subject.class.respond_to?(:defined_enums) && @subject.defined_enums[scope.to_s]
column = column_for(scope)

if column.type == :uuid
SecureRandom.uuid
elsif defined_as_enum?(scope)
available_values = available_enum_values_for(scope, previous_value)
available_values.keys.last
elsif scope.to_s =~ /_type$/ && model_class?(previous_value)
elsif polymorphic_type_attribute?(scope, previous_value)
Uniqueness::TestModels.create(previous_value).to_s
elsif previous_value.respond_to?(:next)
previous_value.next
Expand All @@ -419,23 +426,36 @@ def next_value_for(scope, previous_value)
end
end

def defined_as_enum?(scope)
@subject.class.respond_to?(:defined_enums) &&
@subject.defined_enums[scope.to_s]
end

def polymorphic_type_attribute?(scope, previous_value)
scope.to_s =~ /_type$/ && model_class?(previous_value)
end

def available_enum_values_for(scope, previous_value)
@subject.defined_enums[scope.to_s].reject do |key, _|
key == previous_value
end
end

def class_name
@subject.class.name
end

def existing_value
value = existing_record.__send__(@attribute)
if @options[:case_insensitive] && value.respond_to?(:swapcase!)
value.swapcase!
end
value
end

def class_name
@subject.class.name
end

def column_for(scope)
@subject.class.columns_hash[scope.to_s]
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
context "when more than one record exists that has the next version of the attribute's value" do
it 'accepts' do
value1 = dummy_value_for(value_type)
value2 = next_version_of(value1)
value3 = next_version_of(value2)
value2 = next_version_of(value1, value_type)
value3 = next_version_of(value2, value_type)
model = define_model_validating_uniqueness(
scopes: [ build_attribute(name: :scope) ],
)
Expand Down Expand Up @@ -633,8 +633,10 @@ def dummy_value_for(attribute_type)
end
end

def next_version_of(value)
if value.is_a?(Time)
def next_version_of(value, value_type)
if value_type == :uuid
SecureRandom.uuid
elsif value_type == :time
value + 1
elsif value.respond_to?(:next)
value.next
Expand Down

0 comments on commit 81034ea

Please sign in to comment.