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

Introduce support for the Attributes API typing #1159

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -818,9 +818,7 @@ def next_value_for(scope, previous_value)
end

def next_scalar_value_for(scope, previous_value)
column = column_for(scope)

if column.type == :uuid
if uuid?(scope)
SecureRandom.uuid
elsif defined_as_enum?(scope)
available_values = available_enum_values_for(scope, previous_value)
Expand All @@ -838,6 +836,13 @@ def next_scalar_value_for(scope, previous_value)
end
end

def uuid?(scope)
[
column_for(scope),
attribute_type_for(scope)
mcmire marked this conversation as resolved.
Show resolved Hide resolved
].compact.map(&:type).include? :uuid
end

def all_scopes_are_booleans?
@options[:scopes].all? do |scope|
@all_records.map(&scope).all? { |s| boolean_value?(s) }
Expand Down Expand Up @@ -931,6 +936,10 @@ def column_for(scope)
model.columns_hash[scope.to_s]
end

def attribute_type_for(scope)
return model.attribute_types[scope.to_s] if model.respond_to?(:attribute_types)
mcmire marked this conversation as resolved.
Show resolved Hide resolved
end

def column_limit_for(attribute)
column_for(attribute).try(:limit)
end
Expand Down
4 changes: 4 additions & 0 deletions spec/support/unit/helpers/active_model_versions.rb
Expand Up @@ -28,5 +28,9 @@ def active_model_supports_absence_validation?
def active_model_supports_strict?
active_model_version >= 3.2
end

def active_model_supports_attributes_api?
::ActiveModel::VERSION::MAJOR >= 5
end
end
end
Expand Up @@ -30,10 +30,10 @@
context 'when the subject is an existing record' do
it 'accepts' do
record = create_record_validating_uniqueness(
scopes: [
build_attribute(name: :scope1),
{ name: :scope2 }
]
scopes: [
mcmire marked this conversation as resolved.
Show resolved Hide resolved
build_attribute(name: :scope1),
{ name: :scope2 }
]
)

expect(record).to validate_uniqueness.scoped_to(:scope1, :scope2)
Expand Down Expand Up @@ -1475,6 +1475,41 @@ def name=(name)
end
end

if active_model_supports_attributes_api?
context 'Rails 5 attributes API' do
it 'builds uuid for attributes API type :uuid' do
model = define_model_validating_uniqueness(scopes: [
{ name: :foo,
mcmire marked this conversation as resolved.
Show resolved Hide resolved
column_type: :string,
value_type: :string,
options: { array: false }
mcmire marked this conversation as resolved.
Show resolved Hide resolved
}
mcmire marked this conversation as resolved.
Show resolved Hide resolved
])
mcmire marked this conversation as resolved.
Show resolved Hide resolved
module ActiveRecord
module Type
class Uuid < ActiveRecord::Type::String
def type
:uuid
end
end
end
end

ActiveRecord::Type.register(:uuid, ActiveRecord::Type::Uuid)
bsimpson marked this conversation as resolved.
Show resolved Hide resolved
model.attribute(:foo, :uuid)

value1 = SecureRandom.uuid
create_record_from(model, foo: value1)
record = build_record_from(model, foo: next_scalar_value_for(:foo, value1, model.new))
mcmire marked this conversation as resolved.
Show resolved Hide resolved

expect(SecureRandom).to receive(:uuid)

expect(record).to validate_uniqueness.scoped_to(:foo)
end
end

end

let(:model_attributes) { {} }

def default_attribute
Expand Down Expand Up @@ -1560,6 +1595,12 @@ def dummy_scalar_value_for(attribute_type)
end
end

def next_scalar_value_for(scope, previous_value, record)
subject = validate_uniqueness
subject.instance_variable_set(:@given_record, record)
subject.send(:next_scalar_value_for, scope, previous_value)
end

def next_version_of(value, value_type)
if value.is_a?(Array)
[ next_version_of(value[0], value_type) ]
Expand Down