class Tapioca::Dsl::Compilers::ActiveRecordScope
~~~
end
end
def public_kind(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(T.untyped) }
def private_kind(*args, &blk); end
sig { params(args: T.untyped, blk: T.untyped).returns(T.untyped) }
module GeneratedRelationMethods
extend GeneratedRelationMethods
class Post
# typed: true
# post.rbi
~~~rbi
this compiler will produce the RBI file ‘post.rbi` with the following content:
~~~
end
scope :private_kind, -> { where(kind: ’private’) }
scope :public_kind, -> { where.not(kind: ‘private’) }
class Post < ApplicationRecord
~~~rb
For example, with the following ‘ActiveRecord::Base` subclass:
[`scope` fields](api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope).
subclasses of `ActiveRecord::Base` which declare
`Tapioca::Dsl::Compilers::ActiveRecordScope` decorates RBI files for
def decorate
def decorate method_names = scope_method_names return if method_names.empty? root.create_path(constant) do |model| relations_enabled = compiler_enabled?("ActiveRecordRelations") relation_methods_module = model.create_module(RelationMethodsModuleName) assoc_relation_methods_mod = model.create_module(AssociationRelationMethodsModuleName) if relations_enabled method_names.each do |scope_method| generate_scope_method( relation_methods_module, scope_method.to_s, relations_enabled ? RelationClassName : "T.untyped", ) next unless relations_enabled generate_scope_method( assoc_relation_methods_mod, scope_method.to_s, AssociationRelationClassName, ) end model.create_extend(RelationMethodsModuleName) end end
def gather_constants
def gather_constants descendants_of(::ActiveRecord::Base).reject(&:abstract_class?) end
def generate_scope_method(mod, scope_method, return_type)
def generate_scope_method(mod, scope_method, return_type) mod.create_method( scope_method, parameters: [ create_rest_param("args", type: "T.untyped"), create_block_param("blk", type: "T.untyped"), ], return_type: return_type, ) end
def scope_method_names
def scope_method_names scope_methods = T.let([], T::Array[Symbol]) constant = self.constant # Keep gathering scope methods until we hit "ActiveRecord::Base" until constant == ActiveRecord::Base scope_methods.concat(constant.send(:generated_relation_methods).instance_methods(false)) superclass = superclass_of(constant) break unless superclass # we are guaranteed to have a superclass that is of type "ActiveRecord::Base" constant = T.cast(superclass, T.class_of(ActiveRecord::Base)) end scope_methods.uniq end