Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ def detect
when ActiveModel::Validations::InclusionValidator
validator_items = inclusion_or_exclusion_validator_items(validator)
(validator.attributes & attribute_names).present? &&
(validator_items.is_a?(Proc) || validator_items.exclude?(nil))
(dynamic_validator_items?(validator_items) || validator_items.exclude?(nil))

# An exclusion validator ensures the column is not nil if it covers
# the column and excludes nil as an allowed value explicitly.
when ActiveModel::Validations::ExclusionValidator
validator_items = inclusion_or_exclusion_validator_items(validator)
(validator.attributes & attribute_names).present? &&
(validator_items.is_a?(Proc) || validator_items.include?(nil))
(dynamic_validator_items?(validator_items) || validator_items.include?(nil))

end
end
Expand Down Expand Up @@ -172,6 +172,12 @@ def inclusion_or_exclusion_validator_items(validator)
validator.options[:in] || validator.options[:within] || []
end

# The allowed values can be a Proc or a method name (Symbol) that's resolved
# at validation time, so the set of values isn't known statically.
def dynamic_validator_items?(validator_items)
validator_items.is_a?(Proc) || validator_items.is_a?(Symbol)
end

# Determines whether the given column is used as a counter cache column by
# a has_many association on the model.
def counter_cache_column?(model, column)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,20 @@ def test_non_null_boolean_is_not_reported_if_inclusion_is_proc
refute_problems
end

def test_non_null_is_not_reported_if_inclusion_in_is_a_method
Context.create_table(:users) do |t|
t.string :role, null: false
end.define_model do
validates :role, inclusion: { in: :allowed_roles }

def allowed_roles
["admin", "user"]
end
end

refute_problems
end

def test_non_null_boolean_is_reported_if_nil_not_excluded
Context.create_table(:users) do |t|
t.boolean :active, null: false
Expand Down