Suggestion: Treat `ActiveModel::Attribute` as non-nilable if a PresenceValidator is present
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 873
- Forks
- 164
- Avg merge
- 4d 27m
- Merged PRs (30d)
- 9
Description
class Foo
include ActiveModel::Model
attribute :name, :string
validates :name, presence: true
end
Under normal circumstances, Foo#name should never be nil.
Yes, it's possible to get a nil like Foo.new.name, but I'd argue that returning a type error would make sense here.
I ended up implementing this tapioca extension in my codebase:
# sorbet/tapioca/compilers/active_model_presence_validator.rb
require "active_model/attributes"
require "tapioca/dsl/compilers/active_model_attributes"
module Tapioca
module Compilers
module ActiveModelPresenceValidator
def attribute_methods_for_constant
return super unless constant.is_a?(ActiveModel::Validations::ClassMethods)
attribute_methods = super.to_h # Convert to hash for easier manipulation
attribute_methods.each do |method, type|
has_unconditional_validator = constant
.validators_on(method)
.grep(ActiveModel::Validations::PresenceValidator)
# Skip if any options would mean that the attribute is not always non-nilable
.any? { |v| v.options.slice(:if, :unless, :on, :allow_nil, :allow_blank).empty? }
next unless has_unconditional_validator
type = as_non_nilable_type(type)
attribute_methods[method] = type
attribute_methods["#{method}="] = type
end
attribute_methods.to_a
end
end
Dsl::Compilers::ActiveModelAttributes.prepend(ActiveModelPresenceValidator)
end
end
It's hacky, but it works 😅
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with sorbet/tapioca/compilers/active_model_presence_validator.rb and the Tapioca::Dsl::Compilers::ActiveModelAttributes entry point shown in the issue. Inspect how validators and conditional options are represented, then verify generated RBI output for attributes with unconditional and conditional PresenceValidator instances. Done means unconditional presence validation produces non-nilable getter and setter types without changing conditional cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100