lib/tapioca/dsl/compilers/active_model_validations_confirmation.rb
# typed: strict # frozen_string_literal: true return unless defined?(ActiveModel::Validations) module Tapioca module Dsl module Compilers # `Tapioca::Dsl::Compilers::ActiveModelValidationsConfirmation` decorates RBI files for all # classes that use [`ActiveModel::Validates::Confirmation`](https://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html#method-i-validates_confirmation_of). # # For example, with the following class: # # ~~~rb # class User # include ActiveModel::Validations # # validates_confirmation_of :password # # validates :email, confirmation: true # end # ~~~ # # this compiler will produce an RBI file with the following content: # ~~~rbi # # typed: true # # class User # # sig { returns(T.untyped) } # def email_confirmation; end # # sig { params(email_confirmation=: T.untyped).returns(T.untyped) } # def email_confirmation=(email_confirmation); end # # sig { returns(T.untyped) } # def password_confirmation; end # # sig { params(password_confirmation=: T.untyped).returns(T.untyped) } # def password_confirmation=(password_confirmation); end # end # ~~~ #: [ConstantType = (Class[ActiveModel::Validations] & ActiveModel::Validations::HelperMethods & ActiveModel::Validations::ClassMethods)] class ActiveModelValidationsConfirmation < Compiler extend T::Sig class << self # @override #: -> T::Enumerable[Module] def gather_constants # Collect all the classes that include ActiveModel::Validations all_classes.select { |c| ActiveModel::Validations > c } end end # @override #: -> void def decorate confirmation_validators = constant.validators.grep(ActiveModel::Validations::ConfirmationValidator) return if confirmation_validators.empty? # Create a RBI definition for each class that includes Active::Model::Validations root.create_path(constant) do |klass| # Create RBI definitions for all the attributes that use confirmation validation confirmation_validators.each do |validator| validator.attributes.each do |attr_name| klass.create_method("#{attr_name}_confirmation", return_type: "T.untyped") klass.create_method( "#{attr_name}_confirmation=", parameters: [create_param("#{attr_name}_confirmation", type: "T.untyped")], return_type: "T.untyped", ) end end end end end end end end