Class: Tapioca::Compilers::Dsl::ActiveRecordRelations
- Extended by:
- T::Sig
- Defined in:
- lib/tapioca/compilers/dsl/active_record_relations.rb
Overview
Tapioca::Compilers::Dsl::ActiveRecordRelations decorates RBI files for subclasses of ActiveRecord::Base and adds [relation](api.rubyonrails.org/classes/ActiveRecord/Relation.html), [collection proxy](api.rubyonrails.org/classes/ActiveRecord/Associations/CollectionProxy.html), [query](api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html), [spawn](api.rubyonrails.org/classes/ActiveRecord/SpawnMethods.html), [finder](api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html), and [calculation](api.rubyonrails.org/classes/ActiveRecord/Calculations.html) methods.
The generator defines 3 (synthetic) modules and 3 (synthetic) classes to represent relations properly.
For a given model Model, we generate the following classes:
-
A
Model::PrivateRelationthat subclassesActiveRecord::Relation. This synthetic class represents
a relation on Model whose methods which return a relation always return a Model::PrivateRelation instance.
-
Model::PrivateAssocationRelationthat subclassesActiveRecord::AssociationRelation. This synthetic
class represents a relation on a singular association of type Model (e.g. foo.model) whose methods which return a relation will always return a Model::PrivateAssocationRelation instance. The difference between this class and the previous one is mainly that an association relation also keeps track of the resource association for this relation.
-
Model::PrivateCollectionProxythat subclasses fromActiveRecord::Associations::CollectionProxy.
This synthetic class represents a relation on a plural association of type Model (e.g. foo.models) whose methods which return a relation will always return a Model::PrivateAssocationRelation instance. This class represents a collection of Model instances with some extra methods to build, create, etc new Model instances in the collection.
and the following modules:
-
Model::GeneratedRelationMethodsholds all the relation methods with the return type of
Model::PrivateRelation. For example, calling all on the Model class or an instance of Model::PrivateRelation class will always return a Model::PrivateRelation instance, thus the signature of all is defined with that return type in this module.
-
Model::GeneratedAssociationRelationMethodsholds all the relation methods with the return type
of Model::PrivateAssociationRelation. For example, calling all on an instance of Model::PrivateAssociationRelation or an instance of Model::PrivateCollectionProxy class will always return a Model::PrivateAssociationRelation instance, thus the signature of all is defined with that return type in this module.
-
Model::CommonRelationMethodsholds all the relation methods that do not depend on the type of
relation in their return type. For example, find_by! will always return the same type (a Model instance), regardless of what kind of relation it is called on, and so belongs in this module. This module is used to reduce the replication of methods between the previous two modules.
Additionally, the actual Model class extends both Model::CommonRelationMethods and Model::PrivateRelation modules, so that, for example, find_by and all can be chained off of the Model class.
CAUTION: The generated relation classes are named PrivateXXX intentionally to reflect the fact that they represent private subconstants of the Active Record model. As such, these types do not exist at runtime, and their counterparts that do exist at runtime are marked private_constant anyway. For that reason, these types cannot be used in user code or in ‘sig`s inside Ruby files, since that will make the runtime checks fail.
For example, with the following ActiveRecord::Base subclass:
~~~rb class Post < ApplicationRecord end ~~~
this generator will produce the RBI file post.rbi with the following content: ~~~rbi # post.rbi # typed: true
class Post
extend CommonRelationMethods
extend GeneratedRelationMethods
module CommonRelationMethods
sig { params(block: T.nilable(T.proc.params(record: ::Post).returns(T.untyped))).returns(T::Boolean) }
def any?(&block); end
# ...
end
module GeneratedAssociationRelationMethods
sig { returns(PrivateAssociationRelation) }
def all; end
# ...
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateAssociationRelation) }
def where(*args, &blk); end
end
module GeneratedRelationMethods
sig { returns(PrivateRelation) }
def all; end
# ...
sig { params(args: T.untyped, blk: T.untyped).returns(PrivateRelation) }
def where(*args, &blk); end
end
class PrivateAssociationRelation < ::ActiveRecord::AssociationRelation
include CommonRelationMethods
include GeneratedAssociationRelationMethods
sig { returns(T::Array[::Post]) }
def to_ary; end
Elem = type_member(fixed: ::Post)
end
class PrivateCollectionProxy < ::ActiveRecord::Associations::CollectionProxy
include CommonRelationMethods
include GeneratedAssociationRelationMethods
sig do
params(records: T.any(::Post, T::Array[::Post], T::Array[PrivateCollectionProxy]))
.returns(PrivateCollectionProxy)
end
def <<(*records); end
# ...
end
class PrivateRelation < ::ActiveRecord::Relation
include CommonRelationMethods
include GeneratedRelationMethods
sig { returns(T::Array[::Post]) }
def to_ary; end
Elem = type_member(fixed: ::Post)
end
end ~~~
Defined Under Namespace
Classes: RelationGenerator
Constant Summary
Constants included from Reflection
Reflection::ANCESTORS_METHOD, Reflection::CLASS_METHOD, Reflection::CONSTANTS_METHOD, Reflection::EQUAL_METHOD, Reflection::METHOD_METHOD, Reflection::NAME_METHOD, Reflection::OBJECT_ID_METHOD, Reflection::PRIVATE_INSTANCE_METHODS_METHOD, Reflection::PROTECTED_INSTANCE_METHODS_METHOD, Reflection::PUBLIC_INSTANCE_METHODS_METHOD, Reflection::SINGLETON_CLASS_METHOD, Reflection::SUPERCLASS_METHOD
Instance Attribute Summary
Attributes inherited from Base
#errors, #processable_constants
Instance Method Summary collapse
Methods inherited from Base
#add_error, #generator_enabled?, #handles?, #initialize, resolve
Methods included from ParamHelper
#create_block_param, #create_kw_opt_param, #create_kw_param, #create_kw_rest_param, #create_opt_param, #create_param, #create_rest_param, #create_typed_param
Methods included from Reflection
#ancestors_of, #are_equal?, #class_of, #constantize, #constants_of, #descendants_of, #inherited_ancestors_of, #method_of, #name_of, #name_of_type, #object_id_of, #private_instance_methods_of, #protected_instance_methods_of, #public_instance_methods_of, #qualified_name_of, #signature_of, #singleton_class_of, #superclass_of
Constructor Details
This class inherits a constructor from Tapioca::Compilers::Dsl::Base
Instance Method Details
#decorate(root, constant) ⇒ Object
156 157 158 159 160 161 |
# File 'lib/tapioca/compilers/dsl/active_record_relations.rb', line 156 def decorate(root, constant) root.create_path(constant) do |model| constant_name = T.must(qualified_name_of(constant)) RelationGenerator.new(model, constant_name).generate end end |
#gather_constants ⇒ Object
164 165 166 |
# File 'lib/tapioca/compilers/dsl/active_record_relations.rb', line 164 def gather_constants ActiveRecord::Base.descendants.reject(&:abstract_class?) end |