module ActiveRecord
class AdvisoryLockBase < ActiveRecord::Base
def self._internal?: () -> ::TrueClass
end
end
module ActiveRecord
# See ActiveRecord::Aggregations::ClassMethods for documentation
module Aggregations
def initialize_dup: () -> untyped
def reload: () -> untyped
def clear_aggregation_cache: () -> untyped
def init_internals: () -> untyped
# Active Record implements aggregation through a macro-like class method called #composed_of
# for representing attributes as value objects. It expresses relationships like "Account [is]
# composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
# to the macro adds a description of how the value objects are created from the attributes of
# the entity object (when the entity is initialized either as a new object or from finding an
# existing object) and how it can be turned back into attributes (when the entity is saved to
# the database).
#
# class Customer < ActiveRecord::Base
# composed_of :balance, class_name: "Money", mapping: %w(balance amount)
# composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
# end
#
# The customer class now has the following methods to manipulate the value objects:
# * Customer#balance, Customer#balance=(money)
# * Customer#address, Customer#address=(address)
#
# These methods will operate with value objects like the ones described below:
#
# class Money
# include Comparable
# attr_reader :amount, :currency
# EXCHANGE_RATES = { "USD_TO_DKK" => 6 }
#
# def initialize(amount, currency = "USD")
# @amount, @currency = amount, currency
# end
#
# def exchange_to(other_currency)
# exchanged_amount = (amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor
# Money.new(exchanged_amount, other_currency)
# end
#
# def ==(other_money)
# amount == other_money.amount && currency == other_money.currency
# end
#
# def <=>(other_money)
# if currency == other_money.currency
# amount <=> other_money.amount
# else
# amount <=> other_money.exchange_to(currency).amount
# end
# end
# end
#
# class Address
# attr_reader :street, :city
# def initialize(street, city)
# @street, @city = street, city
# end
#
# def close_to?(other_address)
# city == other_address.city
# end
#
# def ==(other_address)
# city == other_address.city && street == other_address.street
# end
# end
#
# Now it's possible to access attributes from the database through the value objects instead. If
# you choose to name the composition the same as the attribute's name, it will be the only way to
# access that attribute. That's the case with our +balance+ attribute. You interact with the value
# objects just like you would with any other attribute:
#
# customer.balance = Money.new(20) # sets the Money value object and the attribute
# customer.balance # => Money value object
# customer.balance.exchange_to("DKK") # => Money.new(120, "DKK")
# customer.balance > Money.new(10) # => true
# customer.balance == Money.new(20) # => true
# customer.balance < Money.new(5) # => false
#
# Value objects can also be composed of multiple attributes, such as the case of Address. The order
# of the mappings will determine the order of the parameters.
#
# customer.address_street = "Hyancintvej"
# customer.address_city = "Copenhagen"
# customer.address # => Address.new("Hyancintvej", "Copenhagen")
#
# customer.address = Address.new("May Street", "Chicago")
# customer.address_street # => "May Street"
# customer.address_city # => "Chicago"
#
# == Writing value objects
#
# Value objects are immutable and interchangeable objects that represent a given value, such as
# a Money object representing $5. Two Money objects both representing $5 should be equal (through
# methods such as == and <=> from Comparable if ranking makes sense). This is
# unlike entity objects where equality is determined by identity. An entity class such as Customer can
# easily have two different objects that both have an address on Hyancintvej. Entity identity is
# determined by object or relational unique identifiers (such as primary keys). Normal
# ActiveRecord::Base classes are entity objects.
#
# It's also important to treat the value objects as immutable. Don't allow the Money object to have
# its amount changed after creation. Create a new Money object with the new value instead. The
# Money#exchange_to method is an example of this. It returns a new value object instead of changing
# its own values. Active Record won't persist value objects that have been changed through means
# other than the writer method.
#
# The immutable requirement is enforced by Active Record by freezing any object assigned as a value
# object. Attempting to change it afterwards will result in a +RuntimeError+.
#
# Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not
# keeping value objects immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
#
# == Custom constructors and converters
#
# By default value objects are initialized by calling the new constructor of the value
# class passing each of the mapped attributes, in the order specified by the :mapping
# option, as arguments. If the value class doesn't support this convention then #composed_of allows
# a custom constructor to be specified.
#
# When a new value is assigned to the value object, the default assumption is that the new value
# is an instance of the value class. Specifying a custom converter allows the new value to be automatically
# converted to an instance of value class if necessary.
#
# For example, the +NetworkResource+ model has +network_address+ and +cidr_range+ attributes that should be
# aggregated using the +NetAddr::CIDR+ value class (http://www.rubydoc.info/gems/netaddr/1.5.0/NetAddr/CIDR).
# The constructor for the value class is called +create+ and it expects a CIDR address string as a parameter.
# New values can be assigned to the value object using either another +NetAddr::CIDR+ object, a string
# or an array. The :constructor and :converter options can be used to meet
# these requirements:
#
# class NetworkResource < ActiveRecord::Base
# composed_of :cidr,
# class_name: 'NetAddr::CIDR',
# mapping: [ %w(network_address network), %w(cidr_range bits) ],
# allow_nil: true,
# constructor: Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
# converter: Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
# end
#
# # This calls the :constructor
# network_resource = NetworkResource.new(network_address: '192.168.0.1', cidr_range: 24)
#
# # These assignments will both use the :converter
# network_resource.cidr = [ '192.168.2.1', 8 ]
# network_resource.cidr = '192.168.0.1/24'
#
# # This assignment won't use the :converter as the value is already an instance of the value class
# network_resource.cidr = NetAddr::CIDR.create('192.168.2.1/8')
#
# # Saving and then reloading will use the :constructor on reload
# network_resource.save
# network_resource.reload
#
# == Finding records by a value object
#
# Once a #composed_of relationship is specified for a model, records can be loaded from the database
# by specifying an instance of the value object in the conditions hash. The following example
# finds all customers with +address_street+ equal to "May Street" and +address_city+ equal to "Chicago":
#
# Customer.where(address: Address.new("May Street", "Chicago"))
#
module ClassMethods
# Adds reader and writer methods for manipulating a value object:
# composed_of :address adds address and address=(new_address) methods.
#
# Options are:
# * :class_name - Specifies the class name of the association. Use it only if that name
# can't be inferred from the part id. So composed_of :address will by default be linked
# to the Address class, but if the real class name is +CompanyAddress+, you'll have to specify it
# with this option.
# * :mapping - Specifies the mapping of entity attributes to attributes of the value
# object. Each mapping is represented as an array where the first item is the name of the
# entity attribute and the second item is the name of the attribute in the value object. The
# order in which mappings are defined determines the order in which attributes are sent to the
# value class constructor.
# * :allow_nil - Specifies that the value object will not be instantiated when all mapped
# attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all
# mapped attributes.
# This defaults to +false+.
# * :constructor - A symbol specifying the name of the constructor method or a Proc that
# is called to initialize the value object. The constructor is passed all of the mapped attributes,
# in the order that they are defined in the :mapping option, as arguments and uses them
# to instantiate a :class_name object.
# The default is :new.
# * :converter - A symbol specifying the name of a class method of :class_name
# or a Proc that is called when a new value is assigned to the value object. The converter is
# passed the single value that is used in the assignment and is only called if the new value is
# not an instance of :class_name. If :allow_nil is set to true, the converter
# can return +nil+ to skip the assignment.
#
# Option examples:
# composed_of :temperature, mapping: %w(reading celsius)
# composed_of :balance, class_name: "Money", mapping: %w(balance amount)
# composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
# composed_of :gps_location
# composed_of :gps_location, allow_nil: true
# composed_of :ip_address,
# class_name: 'IPAddr',
# mapping: %w(ip to_i),
# constructor: Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
# converter: Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
#
def composed_of: (untyped part_id, ?::Hash[untyped, untyped] options) -> untyped
def reader_method: (untyped name, untyped class_name, untyped mapping, untyped allow_nil, untyped constructor) -> untyped
def writer_method: (untyped name, untyped class_name, untyped mapping, untyped allow_nil, untyped converter) -> untyped
end
end
end
module ActiveRecord
class AssociationRelation < Relation
def initialize: (untyped klass, untyped association) -> untyped
def proxy_association: () -> untyped
def ==: (untyped other) -> untyped
def build: (?untyped? attributes) { () -> untyped } -> untyped
def create: (?untyped? attributes) { () -> untyped } -> untyped
def create!: (?untyped? attributes) { () -> untyped } -> untyped
def exec_queries: () { (untyped) -> untyped } -> untyped
end
end
module ActiveRecord
module Associations
class AliasTracker
# Keeps track of table aliases for ActiveRecord::Associations::JoinDependency
# :nodoc:
def self.create: (untyped connection, untyped initial_table, untyped joins) -> untyped
def self.initial_count_for: (untyped connection, untyped name, untyped table_joins) -> untyped
# table_joins is an array of arel joins which might conflict with the aliases we assign here
def initialize: (untyped connection, untyped aliases) -> untyped
def aliased_table_for: (untyped table_name, untyped aliased_name, untyped type_caster) -> untyped
attr_reader aliases: untyped
def truncate: (untyped name) -> untyped
end
end
end
module ActiveRecord
module Associations
class Association
# = Active Record Associations
#
# This is the root class of all associations ('+ Foo' signifies an included module Foo):
#
# Association
# SingularAssociation
# HasOneAssociation + ForeignAssociation
# HasOneThroughAssociation + ThroughAssociation
# BelongsToAssociation
# BelongsToPolymorphicAssociation
# CollectionAssociation
# HasManyAssociation + ForeignAssociation
# HasManyThroughAssociation + ThroughAssociation
#
# Associations in Active Record are middlemen between the object that
# holds the association, known as the owner, and the associated
# result set, known as the target. Association metadata is available in
# reflection, which is an instance of ActiveRecord::Reflection::AssociationReflection.
#
# For example, given
#
# class Blog < ActiveRecord::Base
# has_many :posts
# end
#
# blog = Blog.first
#
# The association of blog.posts has the object +blog+ as its
# owner, the collection of its posts as target, and
# the reflection object represents a :has_many macro.
# nodoc:
attr_reader owner: untyped
# = Active Record Associations
#
# This is the root class of all associations ('+ Foo' signifies an included module Foo):
#
# Association
# SingularAssociation
# HasOneAssociation + ForeignAssociation
# HasOneThroughAssociation + ThroughAssociation
# BelongsToAssociation
# BelongsToPolymorphicAssociation
# CollectionAssociation
# HasManyAssociation + ForeignAssociation
# HasManyThroughAssociation + ThroughAssociation
#
# Associations in Active Record are middlemen between the object that
# holds the association, known as the owner, and the associated
# result set, known as the target. Association metadata is available in
# reflection, which is an instance of ActiveRecord::Reflection::AssociationReflection.
#
# For example, given
#
# class Blog < ActiveRecord::Base
# has_many :posts
# end
#
# blog = Blog.first
#
# The association of blog.posts has the object +blog+ as its
# owner, the collection of its posts as target, and
# the reflection object represents a :has_many macro.
# nodoc:
attr_reader target: untyped
# = Active Record Associations
#
# This is the root class of all associations ('+ Foo' signifies an included module Foo):
#
# Association
# SingularAssociation
# HasOneAssociation + ForeignAssociation
# HasOneThroughAssociation + ThroughAssociation
# BelongsToAssociation
# BelongsToPolymorphicAssociation
# CollectionAssociation
# HasManyAssociation + ForeignAssociation
# HasManyThroughAssociation + ThroughAssociation
#
# Associations in Active Record are middlemen between the object that
# holds the association, known as the owner, and the associated
# result set, known as the target. Association metadata is available in
# reflection, which is an instance of ActiveRecord::Reflection::AssociationReflection.
#
# For example, given
#
# class Blog < ActiveRecord::Base
# has_many :posts
# end
#
# blog = Blog.first
#
# The association of blog.posts has the object +blog+ as its
# owner, the collection of its posts as target, and
# the reflection object represents a :has_many macro.
# nodoc:
attr_reader reflection: untyped
def initialize: (untyped owner, untyped reflection) -> untyped
# Resets the \loaded flag to +false+ and sets the \target to +nil+.
def reset: () -> untyped
# Reloads the \target and returns +self+ on success.
# The QueryCache is cleared if +force+ is true.
def reload: (?bool force) -> untyped
# Has the \target been already \loaded?
def loaded?: () -> untyped
# Asserts the \target has been loaded setting the \loaded flag to +true+.
def loaded!: () -> untyped
# The target is stale if the target no longer points to the record(s) that the
# relevant foreign_key(s) refers to. If stale, the association accessor method
# on the owner will reload the target. It's up to subclasses to implement the
# stale_state method if relevant.
#
# Note that if the target has not been loaded, it is not considered stale.
def stale_target?: () -> untyped
# Sets the target of this association to \target, and the \loaded flag to +true+.
def target=: (untyped target) -> untyped
def scope: () -> untyped
def reset_scope: () -> untyped
# Set the inverse association, if possible
def set_inverse_instance: (untyped record) -> untyped
def set_inverse_instance_from_queries: (untyped record) -> untyped
# Remove the inverse association, if possible
def remove_inverse_instance: (untyped record) -> untyped
def inversed_from: (untyped record) -> untyped
# Returns the class of the target. belongs_to polymorphic overrides this to look at the
# polymorphic_type field on the owner.
def klass: () -> untyped
def extensions: () -> untyped
# Loads the \target if needed and returns it.
#
# This method is abstract in the sense that it relies on +find_target+,
# which is expected to be provided by descendants.
#
# If the \target is already \loaded it is just returned. Thus, you can call
# +load_target+ unconditionally to get the \target.
#
# ActiveRecord::RecordNotFound is rescued within the method, and it is
# not reraised. The proxy is \reset and +nil+ is the return value.
def load_target: () -> untyped
# We can't dump @reflection and @through_reflection since it contains the scope proc
def marshal_dump: () -> ::Array[untyped]
def marshal_load: (untyped data) -> untyped
def initialize_attributes: (untyped record, ?untyped? except_from_scope_attributes) -> untyped
def create: (?::Hash[untyped, untyped] attributes) { () -> untyped } -> untyped
def create!: (?::Hash[untyped, untyped] attributes) { () -> untyped } -> untyped
def find_target: () -> untyped
# The scope for this association.
#
# Note that the association_scope is merged into the target_scope only when the
# scope method is called. This is because at that point the call may be surrounded
# by scope.scoping { ... } or unscoped { ... } etc, which affects the scope which
# actually gets built.
def association_scope: () -> untyped
# Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
# through association's scope)
def target_scope: () -> untyped
def scope_for_create: () -> untyped
def find_target?: () -> untyped
def creation_attributes: () -> untyped
# Sets the owner attributes on the given record
def set_owner_attributes: (untyped record) -> untyped
# Returns true if there is a foreign key present on the owner which
# references the target. This is used to determine whether we can load
# the target if the owner is currently a new record (and therefore
# without a key). If the owner is a new record then foreign_key must
# be present in order to load target.
#
# Currently implemented by belongs_to (vanilla and polymorphic) and
# has_one/has_many :through associations which go through a belongs_to.
def foreign_key_present?: () -> ::FalseClass
# Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of
# the kind of the class of the associated objects. Meant to be used as
# a sanity check when you are about to assign an associated record.
def raise_on_type_mismatch!: (untyped record) -> untyped
def inverse_association_for: (untyped record) -> untyped
# Can be redefined by subclasses, notably polymorphic belongs_to
# The record parameter is necessary to support polymorphic inverses as we must check for
# the association in the specific class of the record.
def inverse_reflection_for: (untyped record) -> untyped
# Returns true if inverse association on the given record needs to be set.
# This method is redefined by subclasses.
def invertible_for?: (untyped record) -> untyped
# Returns true if record contains the foreign_key
def foreign_key_for?: (untyped record) -> untyped
# This should be implemented to return the values of the relevant key(s) on the owner,
# so that when stale_state is different from the value stored on the last find_target,
# the target is stale.
#
# This is only relevant to certain associations, which is why it returns +nil+ by default.
def stale_state: () -> nil
def build_record: (untyped attributes) { (untyped) -> untyped } -> untyped
# Returns true if statement cache should be skipped on the association reader.
def skip_statement_cache?: (untyped scope) -> untyped
end
end
end
module ActiveRecord
module Associations
class AssociationScope
# nodoc:
def self.scope: (untyped association) -> untyped
def self.create: () { () -> untyped } -> untyped
def initialize: (untyped value_transformation) -> untyped
INSTANCE: untyped
def scope: (untyped association) -> untyped
def self.get_bind_values: (untyped owner, untyped chain) -> untyped
attr_reader value_transformation: untyped
def join: (untyped table, untyped constraint) -> untyped
def last_chain_scope: (untyped scope, untyped reflection, untyped owner) -> untyped
def transform_value: (untyped value) -> untyped
def next_chain_scope: (untyped scope, untyped reflection, untyped next_reflection) -> untyped
class ReflectionProxy < SimpleDelegator
# :nodoc:
attr_reader aliased_table: untyped
def initialize: (untyped reflection, untyped aliased_table) -> untyped
def all_includes: () -> nil
end
def get_chain: (untyped reflection, untyped association, untyped tracker) -> untyped
def add_constraints: (untyped scope, untyped owner, untyped chain) -> untyped
def apply_scope: (untyped scope, untyped table, untyped key, untyped value) -> untyped
def eval_scope: (untyped reflection, untyped scope, untyped owner) -> untyped
end
end
end
module ActiveRecord
module Associations
class BelongsToAssociation < SingularAssociation
# = Active Record Belongs To Association
# nodoc:
def handle_dependency: () -> (nil | untyped)
def inversed_from: (untyped record) -> untyped
def default: () { () -> untyped } -> untyped
def reset: () -> untyped
def updated?: () -> untyped
def decrement_counters: () -> untyped
def increment_counters: () -> untyped
def decrement_counters_before_last_save: () -> untyped
def target_changed?: () -> untyped
def replace: (untyped record) -> untyped
def update_counters: (untyped by) -> untyped
def update_counters_via_scope: (untyped klass, untyped foreign_key, untyped by) -> untyped
def find_target?: () -> untyped
def require_counter_update?: () -> untyped
def replace_keys: (untyped record) -> untyped
def primary_key: (untyped klass) -> untyped
def foreign_key_present?: () -> untyped
# NOTE - for now, we're only supporting inverse setting from belongs_to back onto
# has_one associations.
def invertible_for?: (untyped record) -> untyped
def stale_state: () -> untyped
end
end
end
module ActiveRecord
module Associations
class BelongsToPolymorphicAssociation < BelongsToAssociation
# = Active Record Belongs To Polymorphic Association
# nodoc:
def klass: () -> untyped
def target_changed?: () -> untyped
def replace_keys: (untyped record) -> untyped
def inverse_reflection_for: (untyped record) -> untyped
def raise_on_type_mismatch!: (untyped record) -> nil
def stale_state: () -> untyped
end
end
end
module ActiveRecord::Associations::Builder
class Association
attr_accessor extensions: untyped
VALID_OPTIONS: ::Array[untyped]
def self.build: (untyped model, untyped name, untyped scope, untyped options) { () -> untyped } -> untyped
def self.create_reflection: (untyped model, untyped name, untyped scope, untyped options) { () -> untyped } -> untyped
def self.build_scope: (untyped scope) -> untyped
def self.macro: () -> untyped
def self.valid_options: (untyped options) -> untyped
def self.validate_options: (untyped options) -> untyped
def self.define_extensions: (untyped model, untyped name) -> nil
def self.define_callbacks: (untyped model, untyped reflection) -> untyped
# Defines the setter and getter methods for the association
# class Post < ActiveRecord::Base
# has_many :comments
# end
#
# Post.first.comments and Post.first.comments= methods are defined by this method...
def self.define_accessors: (untyped model, untyped reflection) -> untyped
def self.define_readers: (untyped mixin, untyped name) -> untyped
def self.define_writers: (untyped mixin, untyped name) -> untyped
def self.define_validations: (untyped model, untyped reflection) -> nil
def self.valid_dependent_options: () -> untyped
def self.check_dependent_options: (untyped dependent) -> untyped
def self.add_destroy_callbacks: (untyped model, untyped reflection) -> untyped
end
end
module ActiveRecord::Associations::Builder
class BelongsTo < SingularAssociation
# :nodoc:
# nodoc:
def self.macro: () -> :belongs_to
def self.valid_options: (untyped options) -> untyped
def self.valid_dependent_options: () -> ::Array[:destroy | :delete]
def self.define_callbacks: (untyped model, untyped reflection) -> untyped
def self.add_counter_cache_callbacks: (untyped model, untyped reflection) -> untyped
def self.touch_record: (untyped o, untyped changes, untyped foreign_key, untyped name, untyped touch, untyped touch_method) -> untyped
def self.add_touch_callbacks: (untyped model, untyped reflection) -> untyped
def self.add_default_callbacks: (untyped model, untyped reflection) -> untyped
def self.add_destroy_callbacks: (untyped model, untyped reflection) -> untyped
def self.define_validations: (untyped model, untyped reflection) -> untyped
end
end
module ActiveRecord::Associations::Builder
class CollectionAssociation < Association
# :nodoc:
# nodoc:
CALLBACKS: ::Array[untyped]
def self.valid_options: (untyped options) -> untyped
def self.define_callbacks: (untyped model, untyped reflection) -> untyped
def self.define_extensions: (untyped model, untyped name) { () -> untyped } -> untyped
def self.define_callback: (untyped model, untyped callback_name, untyped name, untyped options) -> untyped
# Defines the setter and getter methods for the collection_singular_ids.
def self.define_readers: (untyped mixin, untyped name) -> untyped
def self.define_writers: (untyped mixin, untyped name) -> untyped
end
end
module ActiveRecord::Associations::Builder
class HasAndBelongsToMany
# :nodoc:
# :nodoc:
attr_reader lhs_model: untyped
# :nodoc:
# :nodoc:
attr_reader association_name: untyped
# :nodoc:
# :nodoc:
attr_reader options: untyped
def initialize: (untyped association_name, untyped lhs_model, untyped options) -> untyped
def through_model: () -> untyped
def middle_reflection: (untyped join_model) -> untyped
def middle_options: (untyped join_model) -> untyped
def table_name: () -> untyped
def belongs_to_options: (untyped options) -> untyped
end
end
module ActiveRecord::Associations::Builder
class HasMany < CollectionAssociation
# :nodoc:
# nodoc:
def self.macro: () -> :has_many
def self.valid_options: (untyped options) -> untyped
def self.valid_dependent_options: () -> ::Array[:destroy | :delete_all | :nullify | :restrict_with_error | :restrict_with_exception]
end
end
module ActiveRecord::Associations::Builder
class HasOne < SingularAssociation
# :nodoc:
# nodoc:
def self.macro: () -> :has_one
def self.valid_options: (untyped options) -> untyped
def self.valid_dependent_options: () -> ::Array[:destroy | :delete | :nullify | :restrict_with_error | :restrict_with_exception]
def self.define_callbacks: (untyped model, untyped reflection) -> untyped
def self.add_destroy_callbacks: (untyped model, untyped reflection) -> untyped
def self.define_validations: (untyped model, untyped reflection) -> untyped
def self.touch_record: (untyped o, untyped name, untyped touch) -> (nil | untyped)
def self.add_touch_callbacks: (untyped model, untyped reflection) -> untyped
end
end
module ActiveRecord::Associations::Builder
class SingularAssociation < Association
# :nodoc:
# nodoc:
def self.valid_options: (untyped options) -> untyped
def self.define_accessors: (untyped model, untyped reflection) -> untyped
# Defines the (build|create)_association methods for belongs_to or has_one association
def self.define_constructors: (untyped mixin, untyped name) -> untyped
end
end
module ActiveRecord
module Associations
class CollectionAssociation < Association
# = Active Record Association Collection
#
# CollectionAssociation is an abstract class that provides common stuff to
# ease the implementation of association proxies that represent
# collections. See the class hierarchy in Association.
#
# CollectionAssociation:
# HasManyAssociation => has_many
# HasManyThroughAssociation + ThroughAssociation => has_many :through
#
# The CollectionAssociation class provides common methods to the collections
# defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with
# the +:through association+ option.
#
# You need to be careful with assumptions regarding the target: The proxy
# does not fetch records from the database until it needs them, but new
# ones created with +build+ are added to the target. So, the target may be
# non-empty and still lack children waiting to be read from the database.
# If you look directly to the database you cannot assume that's the entire
# collection because new records may have been added to the target, etc.
#
# If you need to work on all current children, new and existing records,
# +load_target+ and the +loaded+ flag are your friends.
# nodoc:
# Implements the reader method, e.g. foo.items for Foo.has_many :items
def reader: () -> untyped
# Implements the writer method, e.g. foo.items= for Foo.has_many :items
def writer: (untyped records) -> untyped
# Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
def ids_reader: () -> untyped
# Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items
def ids_writer: (untyped ids) -> untyped
def reset: () -> untyped
def find: (*untyped args) -> untyped
def build: (?::Hash[untyped, untyped] attributes) { () -> untyped } -> untyped
# Add +records+ to this association. Since +<<+ flattens its argument list
# and inserts each record, +push+ and +concat+ behave identically.
def concat: (*untyped records) -> untyped
# Starts a transaction in the association class's database connection.
#
# class Author < ActiveRecord::Base
# has_many :books
# end
#
# Author.first.books.transaction do
# # same effect as calling Book.transaction
# end
def transaction: (*untyped args) { () -> untyped } -> untyped
# Removes all records from the association without calling callbacks
# on the associated records. It honors the +:dependent+ option. However
# if the +:dependent+ value is +:destroy+ then in that case the +:delete_all+
# deletion strategy for the association is applied.
#
# You can force a particular deletion strategy by passing a parameter.
#
# Example:
#
# @author.books.delete_all(:nullify)
# @author.books.delete_all(:delete_all)
#
# See delete for more info.
def delete_all: (?untyped? dependent) -> untyped
# Destroy all the records from this association.
#
# See destroy for more info.
def destroy_all: () -> untyped
# Removes +records+ from this association calling +before_remove+ and
# +after_remove+ callbacks.
#
# This method is abstract in the sense that +delete_records+ has to be
# provided by descendants. Note this method does not imply the records
# are actually removed from the database, that depends precisely on
# +delete_records+. They are in any case removed from the collection.
def delete: (*untyped records) -> untyped
# Deletes the +records+ and removes them from this association calling
# +before_remove+ , +after_remove+ , +before_destroy+ and +after_destroy+ callbacks.
#
# Note that this method removes records from the database ignoring the
# +:dependent+ option.
def destroy: (*untyped records) -> untyped
# Returns the size of the collection by executing a SELECT COUNT(*)
# query if the collection hasn't been loaded, and calling
# collection.size if it has.
#
# If the collection has been already loaded +size+ and +length+ are
# equivalent. If not and you are going to need the records anyway
# +length+ will take one less query. Otherwise +size+ is more efficient.
#
# This method is abstract in the sense that it relies on
# +count_records+, which is a method descendants have to provide.
def size: () -> untyped
# Returns true if the collection is empty.
#
# If the collection has been loaded
# it is equivalent to collection.size.zero?. If the
# collection has not been loaded, it is equivalent to
# collection.exists?. If the collection has not already been
# loaded and you are going to fetch the records anyway it is better to
# check collection.length.zero?.
def empty?: () -> untyped
# Replace this collection with +other_array+. This will perform a diff
# and delete/add only records that have changed.
def replace: (untyped other_array) -> untyped
def include?: (untyped record) -> untyped
def load_target: () -> untyped
def add_to_target: (untyped record, ?bool skip_callbacks) { () -> untyped } -> untyped
def scope: () -> untyped
def null_scope?: () -> untyped
def find_from_target?: () -> untyped
# We have some records loaded from the database (persisted) and some that are
# in-memory (memory). The same record may be represented in the persisted array
# and in the memory array.
#
# So the task of this method is to merge them according to the following rules:
#
# * The final array must not have duplicates
# * The order of the persisted array is to be preserved
# * Any changes made to attributes on objects in the memory array are to be preserved
# * Otherwise, attributes should have the value found in the database
def merge_target_lists: (untyped persisted, untyped memory) -> untyped
def _create_record: (untyped attributes, ?bool raise) { () -> untyped } -> untyped
# Do the relevant stuff to insert the given record into the association collection.
def insert_record: (untyped record, ?bool validate, ?bool raise) { () -> untyped } -> untyped
def delete_or_destroy: (untyped records, untyped method) -> (nil | untyped)
def remove_records: (untyped existing_records, untyped records, untyped method) -> (nil | untyped)
# Delete the given records from the association,
# using one of the methods +:destroy+, +:delete_all+
# or +:nullify+ (or +nil+, in which case a default is used).
def delete_records: (untyped records, untyped method) -> untyped
def replace_records: (untyped new_target, untyped original_target) -> untyped
def replace_common_records_in_memory: (untyped new_target, untyped original_target) -> untyped
def concat_records: (untyped records, ?bool raise) -> untyped
def replace_on_target: (untyped record, untyped index, untyped skip_callbacks) { (untyped) -> untyped } -> untyped
def callback: (untyped method, untyped record) -> untyped
def callbacks_for: (untyped callback_name) -> untyped
def include_in_memory?: (untyped record) -> untyped
# If the :inverse_of option has been
# specified, then #find scans the entire collection.
def find_by_scan: (*untyped args) -> untyped
end
end
end
module ActiveRecord
module Associations
# Collection proxies in Active Record are middlemen between an
# association, and its target result set.
#
# For example, given
#
# class Blog < ActiveRecord::Base
# has_many :posts
# end
#
# blog = Blog.first
#
# The collection proxy returned by blog.posts is built from a
# :has_many association, and delegates to a collection
# of posts as the target.
#
# This class delegates unknown methods to the association's
# relation class via a delegate cache.
#
# The target result set is not loaded until needed. For example,
#
# blog.posts.count
#
# is computed directly through SQL and does not trigger by itself the
# instantiation of the actual post records.
class CollectionProxy < Relation
def initialize: (untyped klass, untyped association) -> untyped
def target: () -> untyped
def load_target: () -> untyped
# Returns +true+ if the association has been loaded, otherwise +false+.
#
# person.pets.loaded? # => false
# person.pets
# person.pets.loaded? # => true
def loaded?: () -> untyped
# Finds an object in the collection responding to the +id+. Uses the same
# rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound
# error if the object cannot be found.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.find(1) # => #
# person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
#
# person.pets.find(2) { |pet| pet.name.downcase! }
# # => #
#
# person.pets.find(2, 3)
# # => [
# # #,
# # #
# # ]
def find: (*untyped args) -> untyped
# Returns the last record, or the last +n+ records, from the collection.
# If the collection is empty, the first form returns +nil+, and the second
# form returns an empty array.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.last # => #
#
# person.pets.last(2)
# # => [
# # #,
# # #
# # ]
#
# another_person_without.pets # => []
# another_person_without.pets.last # => nil
# another_person_without.pets.last(3) # => []
def last: (?untyped? limit) -> untyped
# Gives a record (or N records if a parameter is supplied) from the collection
# using the same rules as ActiveRecord::Base.take.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.take # => #
#
# person.pets.take(2)
# # => [
# # #,
# # #
# # ]
#
# another_person_without.pets # => []
# another_person_without.pets.take # => nil
# another_person_without.pets.take(2) # => []
def take: (?untyped? limit) -> untyped
# Returns a new object of the collection type that has been instantiated
# with +attributes+ and linked to this object, but have not yet been saved.
# You can pass an array of attributes hashes, this will return an array
# with the new objects.
#
# class Person
# has_many :pets
# end
#
# person.pets.build
# # => #
#
# person.pets.build(name: 'Fancy-Fancy')
# # => #
#
# person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.size # => 5 # size of the collection
# person.pets.count # => 0 # count from database
def build: (?::Hash[untyped, untyped] attributes) { () -> untyped } -> untyped
# Returns a new object of the collection type that has been instantiated with
# attributes, linked to this object and that has already been saved (if it
# passes the validations).
#
# class Person
# has_many :pets
# end
#
# person.pets.create(name: 'Fancy-Fancy')
# # => #
#
# person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])
# # => [
# # #,
# # #
# # ]
#
# person.pets.size # => 3
# person.pets.count # => 3
#
# person.pets.find(1, 2, 3)
# # => [
# # #,
# # #,
# # #
# # ]
def create: (?::Hash[untyped, untyped] attributes) { () -> untyped } -> untyped
# Like #create, except that if the record is invalid, raises an exception.
#
# class Person
# has_many :pets
# end
#
# class Pet
# validates :name, presence: true
# end
#
# person.pets.create!(name: nil)
# # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
def create!: (?::Hash[untyped, untyped] attributes) { () -> untyped } -> untyped
# Replaces this collection with +other_array+. This will perform a diff
# and delete/add only records that have changed.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets
# # => [#]
#
# other_pets = [Pet.new(name: 'Puff', group: 'celebrities']
#
# person.pets.replace(other_pets)
#
# person.pets
# # => [#]
#
# If the supplied array has an incorrect association type, it raises
# an ActiveRecord::AssociationTypeMismatch error:
#
# person.pets.replace(["doo", "ggie", "gaga"])
# # => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
def replace: (untyped other_array) -> untyped
# Deletes all the records from the collection according to the strategy
# specified by the +:dependent+ option. If no +:dependent+ option is given,
# then it will follow the default strategy.
#
# For has_many :through associations, the default deletion strategy is
# +:delete_all+.
#
# For +has_many+ associations, the default deletion strategy is +:nullify+.
# This sets the foreign keys to +NULL+.
#
# class Person < ActiveRecord::Base
# has_many :pets # dependent: :nullify option by default
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.delete_all
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.size # => 0
# person.pets # => []
#
# Pet.find(1, 2, 3)
# # => [
# # #,
# # #,
# # #
# # ]
#
# Both +has_many+ and has_many :through dependencies default to the
# +:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
# Records are not instantiated and callbacks will not be fired.
#
# class Person < ActiveRecord::Base
# has_many :pets, dependent: :destroy
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.delete_all
#
# Pet.find(1, 2, 3)
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
#
# If it is set to :delete_all, all the objects are deleted
# *without* calling their +destroy+ method.
#
# class Person < ActiveRecord::Base
# has_many :pets, dependent: :delete_all
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.delete_all
#
# Pet.find(1, 2, 3)
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
def delete_all: (?untyped? dependent) -> untyped
# Deletes the records of the collection directly from the database
# ignoring the +:dependent+ option. Records are instantiated and it
# invokes +before_remove+, +after_remove+ , +before_destroy+ and
# +after_destroy+ callbacks.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.destroy_all
#
# person.pets.size # => 0
# person.pets # => []
#
# Pet.find(1) # => Couldn't find Pet with id=1
def destroy_all: () -> untyped
# Deletes the +records+ supplied from the collection according to the strategy
# specified by the +:dependent+ option. If no +:dependent+ option is given,
# then it will follow the default strategy. Returns an array with the
# deleted records.
#
# For has_many :through associations, the default deletion strategy is
# +:delete_all+.
#
# For +has_many+ associations, the default deletion strategy is +:nullify+.
# This sets the foreign keys to +NULL+.
#
# class Person < ActiveRecord::Base
# has_many :pets # dependent: :nullify option by default
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.delete(Pet.find(1))
# # => [#]
#
# person.pets.size # => 2
# person.pets
# # => [
# # #,
# # #
# # ]
#
# Pet.find(1)
# # => #
#
# If it is set to :destroy all the +records+ are removed by calling
# their +destroy+ method. See +destroy+ for more information.
#
# class Person < ActiveRecord::Base
# has_many :pets, dependent: :destroy
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.delete(Pet.find(1), Pet.find(3))
# # => [
# # #,
# # #
# # ]
#
# person.pets.size # => 1
# person.pets
# # => [#]
#
# Pet.find(1, 3)
# # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
#
# If it is set to :delete_all, all the +records+ are deleted
# *without* calling their +destroy+ method.
#
# class Person < ActiveRecord::Base
# has_many :pets, dependent: :delete_all
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.delete(Pet.find(1))
# # => [#]
#
# person.pets.size # => 2
# person.pets
# # => [
# # #,
# # #
# # ]
#
# Pet.find(1)
# # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
#
# You can pass +Integer+ or +String+ values, it finds the records
# responding to the +id+ and executes delete on them.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.delete("1")
# # => [#]
#
# person.pets.delete(2, 3)
# # => [
# # #,
# # #
# # ]
def delete: (*untyped records) -> untyped
# Destroys the +records+ supplied and removes them from the collection.
# This method will _always_ remove record from the database ignoring
# the +:dependent+ option. Returns an array with the removed records.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.destroy(Pet.find(1))
# # => [#]
#
# person.pets.size # => 2
# person.pets
# # => [
# # #,
# # #
# # ]
#
# person.pets.destroy(Pet.find(2), Pet.find(3))
# # => [
# # #,
# # #
# # ]
#
# person.pets.size # => 0
# person.pets # => []
#
# Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
#
# You can pass +Integer+ or +String+ values, it finds the records
# responding to the +id+ and then deletes them from the database.
#
# person.pets.size # => 3
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.destroy("4")
# # => #
#
# person.pets.size # => 2
# person.pets
# # => [
# # #,
# # #
# # ]
#
# person.pets.destroy(5, 6)
# # => [
# # #,
# # #
# # ]
#
# person.pets.size # => 0
# person.pets # => []
#
# Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
def destroy: (*untyped records) -> untyped
# -
def calculate: (untyped operation, untyped column_name) -> untyped
def pluck: (*untyped column_names) -> untyped
# Returns the size of the collection. If the collection hasn't been loaded,
# it executes a SELECT COUNT(*) query. Else it calls collection.size.
#
# If the collection has been already loaded +size+ and +length+ are
# equivalent. If not and you are going to need the records anyway
# +length+ will take one less query. Otherwise +size+ is more efficient.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets.size # => 3
# # executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1
#
# person.pets # This will execute a SELECT * FROM query
# # => [
# # #,
# # #,
# # #
# # ]
#
# person.pets.size # => 3
# # Because the collection is already loaded, this will behave like
# # collection.size and no SQL count query is executed.
def size: () -> untyped
# Returns +true+ if the collection is empty. If the collection has been
# loaded it is equivalent
# to collection.size.zero?. If the collection has not been loaded,
# it is equivalent to !collection.exists?. If the collection has
# not already been loaded and you are going to fetch the records anyway it
# is better to check collection.length.zero?.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets.count # => 1
# person.pets.empty? # => false
#
# person.pets.delete_all
#
# person.pets.count # => 0
# person.pets.empty? # => true
def empty?: () -> untyped
# Returns +true+ if the given +record+ is present in the collection.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets # => [#]
#
# person.pets.include?(Pet.find(20)) # => true
# person.pets.include?(Pet.find(21)) # => false
def include?: (untyped record) -> untyped
def proxy_association: () -> untyped
# Returns a Relation object for the records in this association
def scope: () -> untyped
# Equivalent to Array#==. Returns +true+ if the two arrays
# contain the same number of elements and if each element is equal
# to the corresponding element in the +other+ array, otherwise returns
# +false+.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets
# # => [
# # #,
# # #
# # ]
#
# other = person.pets.to_ary
#
# person.pets == other
# # => true
#
# other = [Pet.new(id: 1), Pet.new(id: 2)]
#
# person.pets == other
# # => false
def ==: (untyped other) -> untyped
def records: () -> untyped
# Adds one or more +records+ to the collection by setting their foreign keys
# to the association's primary key. Since << flattens its argument list and
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
# so several appends may be chained together.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets.size # => 0
# person.pets << Pet.new(name: 'Fancy-Fancy')
# person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')]
# person.pets.size # => 3
#
# person.id # => 1
# person.pets
# # => [
# # #,
# # #,
# # #
# # ]
def <<: (*untyped records) -> untyped
def `prepend`: (*untyped args) -> untyped
# Equivalent to +delete_all+. The difference is that returns +self+, instead
# of an array with the deleted objects, so methods can be chained. See
# +delete_all+ for more information.
# Note that because +delete_all+ removes records by directly
# running an SQL query into the database, the +updated_at+ column of
# the object is not changed.
def clear: () -> untyped
# Reloads the collection from the database. Returns +self+.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets # fetches pets from the database
# # => [#]
#
# person.pets # uses the pets cache
# # => [#]
#
# person.pets.reload # fetches pets from the database
# # => [#]
def reload: () -> untyped
# Unloads the association. Returns +self+.
#
# class Person < ActiveRecord::Base
# has_many :pets
# end
#
# person.pets # fetches pets from the database
# # => [#]
#
# person.pets # uses the pets cache
# # => [#]
#
# person.pets.reset # clears the pets cache
#
# person.pets # fetches pets from the database
# # => [#]
def reset: () -> untyped
def reset_scope: () -> untyped
def find_nth_with_limit: (untyped index, untyped limit) -> untyped
def find_nth_from_last: (untyped index) -> untyped
def null_scope?: () -> untyped
def find_from_target?: () -> untyped
def exec_queries: () -> untyped
end
end
end
module ActiveRecord::Associations
module ForeignAssociation
# :nodoc:
def foreign_key_present?: () -> untyped
def nullified_owner_attributes: () -> untyped
end
end
module ActiveRecord
module Associations
class HasManyAssociation < CollectionAssociation
# = Active Record Has Many Association
# This is the proxy that handles a has many association.
#
# If the association has a :through option further specialization
# is provided by its child HasManyThroughAssociation.
# nodoc:
include ForeignAssociation
def handle_dependency: () -> untyped
def insert_record: (untyped record, ?bool validate, ?bool raise) -> untyped
# Returns the number of records in this collection.
#
# If the association has a counter cache it gets that value. Otherwise
# it will attempt to do a count via SQL, bounded to :limit if
# there's one. Some configuration options like :group make it impossible
# to do an SQL count, in those cases the array count will be used.
#
# That does not depend on whether the collection has already been loaded
# or not. The +size+ method is the one that takes the loaded flag into
# account and delegates to +count_records+ if needed.
#
# If the collection is empty the target is set to an empty array and
# the loaded flag is set to true as well.
def count_records: () -> untyped
def update_counter: (untyped difference, ?untyped reflection) -> untyped
def update_counter_in_memory: (untyped difference, ?untyped reflection) -> untyped
def delete_count: (untyped method, untyped scope) -> untyped
def delete_or_nullify_all_records: (untyped method) -> untyped
# Deletes the records according to the :dependent option.
def delete_records: (untyped records, untyped method) -> untyped
def concat_records: (untyped records) -> untyped
def _create_record: (untyped attributes) -> untyped
def update_counter_if_success: (untyped saved_successfully, untyped difference) -> untyped
def difference: (untyped a, untyped b) -> untyped
def intersection: (untyped a, untyped b) -> untyped
end
end
end
module ActiveRecord
module Associations
class HasManyThroughAssociation < HasManyAssociation
# = Active Record Has Many Through Association
# nodoc:
include ThroughAssociation
def initialize: (untyped owner, untyped reflection) -> untyped
def concat: (*untyped records) -> untyped
def insert_record: (untyped record, ?bool validate, ?bool raise) -> (nil | untyped)
def concat_records: (untyped records) -> untyped
# The through record (built with build_record) is temporarily cached
# so that it may be reused if insert_record is subsequently called.
#
# However, after insert_record has been called, the cache is cleared in
# order to allow multiple instances of the same record in an association.
def build_through_record: (untyped record) -> untyped
def through_scope_attributes: () -> untyped
def save_through_record: (untyped record) -> untyped
def build_record: (untyped attributes) -> untyped
def remove_records: (untyped existing_records, untyped records, untyped method) -> untyped
def target_reflection_has_associated_record?: () -> untyped
def update_through_counter?: (untyped method) -> untyped
def delete_or_nullify_all_records: (untyped method) -> untyped
def delete_records: (untyped records, untyped method) -> untyped
def difference: (untyped a, untyped b) -> untyped
def intersection: (untyped a, untyped b) -> untyped
def mark_occurrence: (untyped distribution, untyped record) -> untyped
def distribution: (untyped array) -> untyped
def through_records_for: (untyped record) -> untyped
def delete_through_records: (untyped records) -> untyped
def find_target: () -> (::Array[untyped] | untyped)
# NOTE - not sure that we can actually cope with inverses here
def invertible_for?: (untyped record) -> ::FalseClass
end
end
end
module ActiveRecord
module Associations
class HasOneAssociation < SingularAssociation
# = Active Record Has One Association
# nodoc:
include ForeignAssociation
def handle_dependency: () -> untyped
def delete: (?untyped method) -> untyped
def replace: (untyped record, ?bool save) -> untyped
# The reason that the save param for replace is false, if for create (not just build),
# is because the setting of the foreign keys is actually handled by the scoping when
# the record is instantiated, and so they are set straight away and do not need to be
# updated within replace.
def set_new_record: (untyped record) -> untyped
def remove_target!: (untyped method) -> untyped
def nullify_owner_attributes: (untyped record) -> untyped
def transaction_if: (untyped value) { () -> untyped } -> untyped
def _create_record: (untyped attributes, ?bool raise_error) { () -> untyped } -> untyped
end
end
end
module ActiveRecord
module Associations
class HasOneThroughAssociation < HasOneAssociation
# = Active Record Has One Through Association
# nodoc:
include ThroughAssociation
def replace: (untyped record, ?bool save) -> untyped
def create_through_record: (untyped record, untyped save) -> untyped
end
end
end
module ActiveRecord
module Associations
class JoinDependency
class JoinAssociation < JoinPart
# :nodoc:
# :nodoc:
attr_reader reflection: untyped
# :nodoc:
# :nodoc:
attr_reader tables: untyped
attr_accessor table: untyped
def initialize: (untyped reflection, untyped children) -> untyped
def match?: (untyped other) -> (::TrueClass | untyped)
def join_constraints: (untyped foreign_table, untyped foreign_klass, untyped join_type, untyped alias_tracker) -> untyped
def tables=: (untyped tables) -> untyped
def readonly?: () -> untyped
def append_constraints: (untyped join, untyped constraints) -> untyped
end
end
end
end
module ActiveRecord
module Associations
class JoinDependency
class JoinBase < JoinPart
# :nodoc:
# :nodoc:
attr_reader table: untyped
def initialize: (untyped base_klass, untyped table, untyped children) -> untyped
def match?: (untyped other) -> (::TrueClass | untyped)
end
end
end
end
module ActiveRecord
module Associations
class JoinDependency
class JoinPart
# :nodoc:
# A JoinPart represents a part of a JoinDependency. It is inherited
# by JoinBase and JoinAssociation. A JoinBase represents the Active Record which
# everything else is being joined onto. A JoinAssociation represents an association which
# is joining to the base. A JoinAssociation may result in more than one actual join
# operations (for example a has_and_belongs_to_many JoinAssociation would result in
# two; one for the join table and one for the target table).
# :nodoc:
include Enumerable[untyped, untyped]
# The Active Record class which this join part is associated 'about'; for a JoinBase
# this is the actual base model, for a JoinAssociation this is the target model of the
# association.
attr_reader base_klass: untyped
# The Active Record class which this join part is associated 'about'; for a JoinBase
# this is the actual base model, for a JoinAssociation this is the target model of the
# association.
attr_reader children: untyped
def initialize: (untyped base_klass, untyped children) -> untyped
def match?: (untyped other) -> untyped
def each: () { (untyped) -> untyped } -> untyped
def each_children: () { (untyped, untyped) -> untyped } -> untyped
# An Arel::Table for the active_record
def table: () -> untyped
def extract_record: (untyped row, untyped column_names_with_alias) -> untyped
def instantiate: (untyped row, untyped aliases) { () -> untyped } -> untyped
end
end
end
end
module ActiveRecord
module Associations
class JoinDependency
class Aliases
# :nodoc:
def initialize: (untyped tables) -> untyped
def columns: () -> untyped
def column_aliases: (untyped node) -> untyped
def column_alias: (untyped node, untyped column) -> untyped
class Table < ::Struct[untyped]
attr_accessor node(): untyped
attr_accessor columns(): untyped
# :nodoc:
def column_aliases: () -> untyped
end
class Column < ::Struct[untyped]
attr_accessor name(): untyped
attr_accessor alias(): untyped
end
end
def self.make_tree: (untyped associations) -> untyped
def self.walk_tree: (untyped associations, untyped hash) -> untyped
def initialize: (untyped base, untyped table, untyped associations, untyped join_type) -> untyped
def base_klass: () -> untyped
def reflections: () -> untyped
def join_constraints: (untyped joins_to_add, untyped alias_tracker) -> untyped
def instantiate: (untyped result_set) { () -> untyped } -> untyped
def apply_column_aliases: (untyped relation) -> untyped
attr_reader join_root: untyped
attr_reader join_type: untyped
attr_reader alias_tracker: untyped
def explicit_selections: (untyped root_column_aliases, untyped result_set) -> untyped
def aliases: () -> untyped
def construct_tables!: (untyped join_root) -> untyped
def make_join_constraints: (untyped join_root, untyped join_type) -> untyped
def make_constraints: (untyped parent, untyped child, untyped join_type) -> untyped
def table_aliases_for: (untyped parent, untyped node) -> untyped
def table_alias_for: (untyped reflection, untyped parent, untyped join) -> untyped
def walk: (untyped left, untyped right, untyped join_type) -> untyped
def find_reflection: (untyped klass, untyped name) -> untyped
def build: (untyped associations, untyped base_klass) -> untyped
def construct: (untyped ar_parent, untyped parent, untyped row, untyped seen, untyped model_cache) -> (nil | untyped)
def construct_model: (untyped record, untyped node, untyped row, untyped model_cache, untyped id) -> untyped
end
end
end
module ActiveRecord
module Associations
class Preloader
class Association
# nodoc:
def initialize: (untyped klass, untyped owners, untyped reflection, untyped preload_scope) -> untyped
def run: () -> untyped
def records_by_owner: () -> untyped
def preloaded_records: () -> untyped
attr_reader owners: untyped
attr_reader reflection: untyped
attr_reader preload_scope: untyped
attr_reader model: untyped
attr_reader klass: untyped
# The name of the key on the associated records
def association_key_name: () -> untyped
# The name of the key on the model which declares the association
def owner_key_name: () -> untyped
def associate_records_to_owner: (untyped owner, untyped records) -> untyped
def owner_keys: () -> untyped
def owners_by_key: () -> untyped
def key_conversion_required?: () -> untyped
def convert_key: (untyped key) -> untyped
def association_key_type: () -> untyped
def owner_key_type: () -> untyped
def records_for: (untyped ids) -> untyped
def scope: () -> untyped
def reflection_scope: () -> untyped
def build_scope: () -> untyped
end
end
end
end
module ActiveRecord
module Associations
class Preloader
# Implements the details of eager loading of Active Record associations.
#
# Suppose that you have the following two Active Record models:
#
# class Author < ActiveRecord::Base
# # columns: name, age
# has_many :books
# end
#
# class Book < ActiveRecord::Base
# # columns: title, sales, author_id
# end
#
# When you load an author with all associated books Active Record will make
# multiple queries like this:
#
# Author.includes(:books).where(name: ['bell hooks', 'Homer']).to_a
#
# => SELECT `authors`.* FROM `authors` WHERE `name` IN ('bell hooks', 'Homer')
# => SELECT `books`.* FROM `books` WHERE `author_id` IN (2, 5)
#
# Active Record saves the ids of the records from the first query to use in
# the second. Depending on the number of associations involved there can be
# arbitrarily many SQL queries made.
#
# However, if there is a WHERE clause that spans across tables Active
# Record will fall back to a slightly more resource-intensive single query:
#
# Author.includes(:books).where(books: {title: 'Illiad'}).to_a
# => SELECT `authors`.`id` AS t0_r0, `authors`.`name` AS t0_r1, `authors`.`age` AS t0_r2,
# `books`.`id` AS t1_r0, `books`.`title` AS t1_r1, `books`.`sales` AS t1_r2
# FROM `authors`
# LEFT OUTER JOIN `books` ON `authors`.`id` = `books`.`author_id`
# WHERE `books`.`title` = 'Illiad'
#
# This could result in many rows that contain redundant data and it performs poorly at scale
# and is therefore only used when necessary.
#
# nodoc:
extend ActiveSupport::Autoload
# Eager loads the named associations for the given Active Record record(s).
#
# In this description, 'association name' shall refer to the name passed
# to an association creation method. For example, a model that specifies
# belongs_to :author, has_many :buyers has association
# names +:author+ and +:buyers+.
#
# == Parameters
# +records+ is an array of ActiveRecord::Base. This array needs not be flat,
# i.e. +records+ itself may also contain arrays of records. In any case,
# +preload_associations+ will preload the all associations records by
# flattening +records+.
#
# +associations+ specifies one or more associations that you want to
# preload. It may be:
# - a Symbol or a String which specifies a single association name. For
# example, specifying +:books+ allows this method to preload all books
# for an Author.
# - an Array which specifies multiple association names. This array
# is processed recursively. For example, specifying [:avatar, :books]
# allows this method to preload an author's avatar as well as all of his
# books.
# - a Hash which specifies multiple association names, as well as
# association names for the to-be-preloaded association objects. For
# example, specifying { author: :avatar } will preload a
# book's author, as well as that author's avatar.
#
# +:associations+ has the same format as the +:include+ option for
# ActiveRecord::Base.find. So +associations+ could look like this:
#
# :books
# [ :books, :author ]
# { author: :avatar }
# [ :books, { author: :avatar } ]
def preload: (untyped records, untyped associations, ?untyped? preload_scope) -> untyped
# Loads all the given data into +records+ for the +association+.
def preloaders_on: (untyped association, untyped records, untyped scope, ?bool polymorphic_parent) -> untyped
def preloaders_for_hash: (untyped association, untyped records, untyped scope, untyped polymorphic_parent) -> untyped
# Loads all the given data into +records+ for a singular +association+.
#
# Functions by instantiating a preloader class such as Preloader::Association and
# call the +run+ method for each passed in class in the +records+ argument.
#
# Not all records have the same class, so group then preload group on the reflection
# itself so that if various subclass share the same association then we do not split
# them unnecessarily
#
# Additionally, polymorphic belongs_to associations can have multiple associated
# classes, depending on the polymorphic_type field. So we group by the classes as
# well.
def preloaders_for_one: (untyped association, untyped records, untyped scope, untyped polymorphic_parent) -> untyped
def preloaders_for_reflection: (untyped reflection, untyped records, untyped scope) -> untyped
def grouped_records: (untyped association, untyped records, untyped polymorphic_parent) -> untyped
class AlreadyLoaded
# :nodoc:
def initialize: (untyped klass, untyped owners, untyped reflection, untyped preload_scope) -> untyped
def run: () -> untyped
def preloaded_records: () -> untyped
def records_by_owner: () -> untyped
attr_reader owners: untyped
attr_reader reflection: untyped
end
# Returns a class containing the logic needed to load preload the data
# and attach it to a relation. The class returned implements a `run` method
# that accepts a preloader.
def preloader_for: (untyped reflection, untyped owners) -> untyped
end
end
end
module ActiveRecord
module Associations
class Preloader
class ThroughAssociation < Association
# :nodoc:
PRELOADER: untyped
def initialize: () -> untyped
def preloaded_records: () -> untyped
def records_by_owner: () -> untyped
def source_preloaders: () -> untyped
def middle_records: () -> untyped
def through_preloaders: () -> untyped
def through_reflection: () -> untyped
def source_reflection: () -> untyped
def preload_index: () -> untyped
def through_scope: () -> untyped
end
end
end
end
module ActiveRecord
class AssociationNotFoundError < ConfigurationError
# nodoc:
def initialize: (?untyped? record, ?untyped? association_name) -> untyped
end
class InverseOfAssociationNotFoundError < ActiveRecordError
# nodoc:
def initialize: (?untyped? reflection, ?untyped? associated_class) -> untyped
end
class HasManyThroughAssociationNotFoundError < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner_class_name, ?untyped? reflection) -> untyped
end
class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner_class_name, ?untyped? reflection, ?untyped? source_reflection) -> untyped
end
class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner_class_name, ?untyped? reflection) -> untyped
end
class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner_class_name, ?untyped? reflection, ?untyped? source_reflection) -> untyped
end
class HasOneThroughCantAssociateThroughCollection < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner_class_name, ?untyped? reflection, ?untyped? through_reflection) -> untyped
end
class HasOneAssociationPolymorphicThroughError < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner_class_name, ?untyped? reflection) -> untyped
end
class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError
# nodoc:
def initialize: (?untyped? reflection) -> untyped
end
class HasManyThroughOrderError < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner_class_name, ?untyped? reflection, ?untyped? through_reflection) -> untyped
end
class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner, ?untyped? reflection) -> untyped
end
class AmbiguousSourceReflectionForThroughAssociation < ActiveRecordError
# :nodoc:
def initialize: (untyped klass, untyped macro, untyped association_name, untyped options, untyped possible_sources) -> untyped
end
class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection
end
class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection
end
class ThroughNestedAssociationsAreReadonly < ActiveRecordError
# nodoc:
def initialize: (?untyped? owner, ?untyped? reflection) -> untyped
end
class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly
end
class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly
end
# This error is raised when trying to eager load a polymorphic association using a JOIN.
# Eager loading polymorphic associations is only possible with
# {ActiveRecord::Relation#preload}[rdoc-ref:QueryMethods#preload].
class EagerLoadPolymorphicError < ActiveRecordError
def initialize: (?untyped? reflection) -> untyped
end
class DeleteRestrictionError < ActiveRecordError
# This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
# (has_many, has_one) when there is at least 1 child associated instance.
# ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
# nodoc:
def initialize: (?untyped? name) -> untyped
end
module Associations
# See ActiveRecord::Associations::ClassMethods for documentation.
# :nodoc:
extend ActiveSupport::Autoload
extend ActiveSupport::Concern
module Builder
end
def self.eager_load!: () -> untyped
def association: (untyped name) -> untyped
def association_cached?: (untyped name) -> untyped
def initialize_dup: () -> untyped
def reload: () -> untyped
# Clears out the association cache.
def clear_association_cache: () -> untyped
def init_internals: () -> untyped
# Returns the specified association instance if it exists, +nil+ otherwise.
def association_instance_get: (untyped name) -> untyped
# Set the specified association instance.
def association_instance_set: (untyped name, untyped association) -> untyped
# \Associations are a set of macro-like class methods for tying objects together through
# foreign keys. They express relationships like "Project has one Project Manager"
# or "Project belongs to a Portfolio". Each macro adds a number of methods to the
# class which are specialized according to the collection or association symbol and the
# options hash. It works much the same way as Ruby's own attr*
# methods.
#
# class Project < ActiveRecord::Base
# belongs_to :portfolio
# has_one :project_manager
# has_many :milestones
# has_and_belongs_to_many :categories
# end
#
# The project class now has the following methods (and more) to ease the traversal and
# manipulation of its relationships:
# * Project#portfolio, Project#portfolio=(portfolio), Project#reload_portfolio
# * Project#project_manager, Project#project_manager=(project_manager), Project#reload_project_manager
# * Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),
# Project#milestones.delete(milestone), Project#milestones.destroy(milestone), Project#milestones.find(milestone_id),
# Project#milestones.build, Project#milestones.create
# * Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),
# Project#categories.delete(category1), Project#categories.destroy(category1)
#
# === A word of warning
#
# Don't create associations that have the same name as {instance methods}[rdoc-ref:ActiveRecord::Core] of
# ActiveRecord::Base. Since the association adds a method with that name to
# its model, using an association with the same name as one provided by ActiveRecord::Base will override the method inherited through ActiveRecord::Base and will break things.
# For instance, +attributes+ and +connection+ would be bad choices for association names, because those names already exist in the list of ActiveRecord::Base instance methods.
#
# == Auto-generated methods
# See also Instance Public methods below for more details.
#
# === Singular associations (one-to-one)
# | | belongs_to |
# generated methods | belongs_to | :polymorphic | has_one
# ----------------------------------+------------+--------------+---------
# other | X | X | X
# other=(other) | X | X | X
# build_other(attributes={}) | X | | X
# create_other(attributes={}) | X | | X
# create_other!(attributes={}) | X | | X
# reload_other | X | X | X
#
# === Collection associations (one-to-many / many-to-many)
# | | | has_many
# generated methods | habtm | has_many | :through
# ----------------------------------+-------+----------+----------
# others | X | X | X
# others=(other,other,...) | X | X | X
# other_ids | X | X | X
# other_ids=(id,id,...) | X | X | X
# others<< | X | X | X
# others.push | X | X | X
# others.concat | X | X | X
# others.build(attributes={}) | X | X | X
# others.create(attributes={}) | X | X | X
# others.create!(attributes={}) | X | X | X
# others.size | X | X | X
# others.length | X | X | X
# others.count | X | X | X
# others.sum(*args) | X | X | X
# others.empty? | X | X | X
# others.clear | X | X | X
# others.delete(other,other,...) | X | X | X
# others.delete_all | X | X | X
# others.destroy(other,other,...) | X | X | X
# others.destroy_all | X | X | X
# others.find(*args) | X | X | X
# others.exists? | X | X | X
# others.distinct | X | X | X
# others.reset | X | X | X
# others.reload | X | X | X
#
# === Overriding generated methods
#
# Association methods are generated in a module included into the model
# class, making overrides easy. The original generated method can thus be
# called with +super+:
#
# class Car < ActiveRecord::Base
# belongs_to :owner
# belongs_to :old_owner
#
# def owner=(new_owner)
# self.old_owner = self.owner
# super
# end
# end
#
# The association methods module is included immediately after the
# generated attributes methods module, meaning an association will
# override the methods for an attribute with the same name.
#
# == Cardinality and associations
#
# Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
# relationships between models. Each model uses an association to describe its role in
# the relation. The #belongs_to association is always used in the model that has
# the foreign key.
#
# === One-to-one
#
# Use #has_one in the base, and #belongs_to in the associated model.
#
# class Employee < ActiveRecord::Base
# has_one :office
# end
# class Office < ActiveRecord::Base
# belongs_to :employee # foreign key - employee_id
# end
#
# === One-to-many
#
# Use #has_many in the base, and #belongs_to in the associated model.
#
# class Manager < ActiveRecord::Base
# has_many :employees
# end
# class Employee < ActiveRecord::Base
# belongs_to :manager # foreign key - manager_id
# end
#
# === Many-to-many
#
# There are two ways to build a many-to-many relationship.
#
# The first way uses a #has_many association with the :through option and a join model, so
# there are two stages of associations.
#
# class Assignment < ActiveRecord::Base
# belongs_to :programmer # foreign key - programmer_id
# belongs_to :project # foreign key - project_id
# end
# class Programmer < ActiveRecord::Base
# has_many :assignments
# has_many :projects, through: :assignments
# end
# class Project < ActiveRecord::Base
# has_many :assignments
# has_many :programmers, through: :assignments
# end
#
# For the second way, use #has_and_belongs_to_many in both models. This requires a join table
# that has no corresponding model or primary key.
#
# class Programmer < ActiveRecord::Base
# has_and_belongs_to_many :projects # foreign keys in the join table
# end
# class Project < ActiveRecord::Base
# has_and_belongs_to_many :programmers # foreign keys in the join table
# end
#
# Choosing which way to build a many-to-many relationship is not always simple.
# If you need to work with the relationship model as its own entity,
# use #has_many :through. Use #has_and_belongs_to_many when working with legacy schemas or when
# you never work directly with the relationship itself.
#
# == Is it a #belongs_to or #has_one association?
#
# Both express a 1-1 relationship. The difference is mostly where to place the foreign
# key, which goes on the table for the class declaring the #belongs_to relationship.
#
# class User < ActiveRecord::Base
# # I reference an account.
# belongs_to :account
# end
#
# class Account < ActiveRecord::Base
# # One user references me.
# has_one :user
# end
#
# The tables for these classes could look something like:
#
# CREATE TABLE users (
# id bigint NOT NULL auto_increment,
# account_id bigint default NULL,
# name varchar default NULL,
# PRIMARY KEY (id)
# )
#
# CREATE TABLE accounts (
# id bigint NOT NULL auto_increment,
# name varchar default NULL,
# PRIMARY KEY (id)
# )
#
# == Unsaved objects and associations
#
# You can manipulate objects and associations before they are saved to the database, but
# there is some special behavior you should be aware of, mostly involving the saving of
# associated objects.
#
# You can set the :autosave option on a #has_one, #belongs_to,
# #has_many, or #has_and_belongs_to_many association. Setting it
# to +true+ will _always_ save the members, whereas setting it to +false+ will
# _never_ save the members. More details about :autosave option is available at
# AutosaveAssociation.
#
# === One-to-one associations
#
# * Assigning an object to a #has_one association automatically saves that object and
# the object being replaced (if there is one), in order to update their foreign
# keys - except if the parent object is unsaved (new_record? == true).
# * If either of these saves fail (due to one of the objects being invalid), an
# ActiveRecord::RecordNotSaved exception is raised and the assignment is
# cancelled.
# * If you wish to assign an object to a #has_one association without saving it,
# use the #build_association method (documented below). The object being
# replaced will still be saved to update its foreign key.
# * Assigning an object to a #belongs_to association does not save the object, since
# the foreign key field belongs on the parent. It does not save the parent either.
#
# === Collections
#
# * Adding an object to a collection (#has_many or #has_and_belongs_to_many) automatically
# saves that object, except if the parent object (the owner of the collection) is not yet
# stored in the database.
# * If saving any of the objects being added to a collection (via push or similar)
# fails, then push returns +false+.
# * If saving fails while replacing the collection (via association=), an
# ActiveRecord::RecordNotSaved exception is raised and the assignment is
# cancelled.
# * You can add an object to a collection without automatically saving it by using the
# collection.build method (documented below).
# * All unsaved (new_record? == true) members of the collection are automatically
# saved when the parent is saved.
#
# == Customizing the query
#
# \Associations are built from Relation objects, and you can use the Relation syntax
# to customize them. For example, to add a condition:
#
# class Blog < ActiveRecord::Base
# has_many :published_posts, -> { where(published: true) }, class_name: 'Post'
# end
#
# Inside the -> { ... } block you can use all of the usual Relation methods.
#
# === Accessing the owner object
#
# Sometimes it is useful to have access to the owner object when building the query. The owner
# is passed as a parameter to the block. For example, the following association would find all
# events that occur on the user's birthday:
#
# class User < ActiveRecord::Base
# has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
# end
#
# Note: Joining, eager loading and preloading of these associations is not possible.
# These operations happen before instance creation and the scope will be called with a +nil+ argument.
#
# == Association callbacks
#
# Similar to the normal callbacks that hook into the life cycle of an Active Record object,
# you can also define callbacks that get triggered when you add an object to or remove an
# object from an association collection.
#
# class Project
# has_and_belongs_to_many :developers, after_add: :evaluate_velocity
#
# def evaluate_velocity(developer)
# ...
# end
# end
#
# It's possible to stack callbacks by passing them as an array. Example:
#
# class Project
# has_and_belongs_to_many :developers,
# after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
# end
#
# Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
#
# If any of the +before_add+ callbacks throw an exception, the object will not be
# added to the collection.
#
# Similarly, if any of the +before_remove+ callbacks throw an exception, the object
# will not be removed from the collection.
#
# == Association extensions
#
# The proxy objects that control the access to associations can be extended through anonymous
# modules. This is especially beneficial for adding new finders, creators, and other
# factory-type methods that are only used as part of this association.
#
# class Account < ActiveRecord::Base
# has_many :people do
# def find_or_create_by_name(name)
# first_name, last_name = name.split(" ", 2)
# find_or_create_by(first_name: first_name, last_name: last_name)
# end
# end
# end
#
# person = Account.first.people.find_or_create_by_name("David Heinemeier Hansson")
# person.first_name # => "David"
# person.last_name # => "Heinemeier Hansson"
#
# If you need to share the same extensions between many associations, you can use a named
# extension module.
#
# module FindOrCreateByNameExtension
# def find_or_create_by_name(name)
# first_name, last_name = name.split(" ", 2)
# find_or_create_by(first_name: first_name, last_name: last_name)
# end
# end
#
# class Account < ActiveRecord::Base
# has_many :people, -> { extending FindOrCreateByNameExtension }
# end
#
# class Company < ActiveRecord::Base
# has_many :people, -> { extending FindOrCreateByNameExtension }
# end
#
# Some extensions can only be made to work with knowledge of the association's internals.
# Extensions can access relevant state using the following methods (where +items+ is the
# name of the association):
#
# * record.association(:items).owner - Returns the object the association is part of.
# * record.association(:items).reflection - Returns the reflection object that describes the association.
# * record.association(:items).target - Returns the associated object for #belongs_to and #has_one, or
# the collection of associated objects for #has_many and #has_and_belongs_to_many.
#
# However, inside the actual extension code, you will not have access to the record as
# above. In this case, you can access proxy_association. For example,
# record.association(:items) and record.items.proxy_association will return
# the same object, allowing you to make calls like proxy_association.owner inside
# association extensions.
#
# == Association Join Models
#
# Has Many associations can be configured with the :through option to use an
# explicit join model to retrieve the data. This operates similarly to a
# #has_and_belongs_to_many association. The advantage is that you're able to add validations,
# callbacks, and extra attributes on the join model. Consider the following schema:
#
# class Author < ActiveRecord::Base
# has_many :authorships
# has_many :books, through: :authorships
# end
#
# class Authorship < ActiveRecord::Base
# belongs_to :author
# belongs_to :book
# end
#
# @author = Author.first
# @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
# @author.books # selects all books by using the Authorship join model
#
# You can also go through a #has_many association on the join model:
#
# class Firm < ActiveRecord::Base
# has_many :clients
# has_many :invoices, through: :clients
# end
#
# class Client < ActiveRecord::Base
# belongs_to :firm
# has_many :invoices
# end
#
# class Invoice < ActiveRecord::Base
# belongs_to :client
# end
#
# @firm = Firm.first
# @firm.clients.flat_map { |c| c.invoices } # select all invoices for all clients of the firm
# @firm.invoices # selects all invoices by going through the Client join model
#
# Similarly you can go through a #has_one association on the join model:
#
# class Group < ActiveRecord::Base
# has_many :users
# has_many :avatars, through: :users
# end
#
# class User < ActiveRecord::Base
# belongs_to :group
# has_one :avatar
# end
#
# class Avatar < ActiveRecord::Base
# belongs_to :user
# end
#
# @group = Group.first
# @group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group
# @group.avatars # selects all avatars by going through the User join model.
#
# An important caveat with going through #has_one or #has_many associations on the
# join model is that these associations are *read-only*. For example, the following
# would not work following the previous example:
#
# @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around
# @group.avatars.delete(@group.avatars.last) # so would this
#
# == Setting Inverses
#
# If you are using a #belongs_to on the join model, it is a good idea to set the
# :inverse_of option on the #belongs_to, which will mean that the following example
# works correctly (where tags is a #has_many :through association):
#
# @post = Post.first
# @tag = @post.tags.build name: "ruby"
# @tag.save
#
# The last line ought to save the through record (a Tagging). This will only work if the
# :inverse_of is set:
#
# class Tagging < ActiveRecord::Base
# belongs_to :post
# belongs_to :tag, inverse_of: :taggings
# end
#
# If you do not set the :inverse_of record, the association will
# do its best to match itself up with the correct inverse. Automatic
# inverse detection only works on #has_many, #has_one, and
# #belongs_to associations.
#
# Extra options on the associations, as defined in the
# AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS
# constant, or a custom scope, will also prevent the association's inverse
# from being found automatically.
#
# The automatic guessing of the inverse association uses a heuristic based
# on the name of the class, so it may not work for all associations,
# especially the ones with non-standard names.
#
# You can turn off the automatic detection of inverse associations by setting
# the :inverse_of option to false like so:
#
# class Tagging < ActiveRecord::Base
# belongs_to :tag, inverse_of: false
# end
#
# == Nested \Associations
#
# You can actually specify *any* association with the :through option, including an
# association which has a :through option itself. For example:
#
# class Author < ActiveRecord::Base
# has_many :posts
# has_many :comments, through: :posts
# has_many :commenters, through: :comments
# end
#
# class Post < ActiveRecord::Base
# has_many :comments
# end
#
# class Comment < ActiveRecord::Base
# belongs_to :commenter
# end
#
# @author = Author.first
# @author.commenters # => People who commented on posts written by the author
#
# An equivalent way of setting up this association this would be:
#
# class Author < ActiveRecord::Base
# has_many :posts
# has_many :commenters, through: :posts
# end
#
# class Post < ActiveRecord::Base
# has_many :comments
# has_many :commenters, through: :comments
# end
#
# class Comment < ActiveRecord::Base
# belongs_to :commenter
# end
#
# When using a nested association, you will not be able to modify the association because there
# is not enough information to know what modification to make. For example, if you tried to
# add a Commenter in the example above, there would be no way to tell how to set up the
# intermediate Post and Comment objects.
#
# == Polymorphic \Associations
#
# Polymorphic associations on models are not restricted on what types of models they
# can be associated with. Rather, they specify an interface that a #has_many association
# must adhere to.
#
# class Asset < ActiveRecord::Base
# belongs_to :attachable, polymorphic: true
# end
#
# class Post < ActiveRecord::Base
# has_many :assets, as: :attachable # The :as option specifies the polymorphic interface to use.
# end
#
# @asset.attachable = @post
#
# This works by using a type column in addition to a foreign key to specify the associated
# record. In the Asset example, you'd need an +attachable_id+ integer column and an
# +attachable_type+ string column.
#
# Using polymorphic associations in combination with single table inheritance (STI) is
# a little tricky. In order for the associations to work as expected, ensure that you
# store the base model for the STI models in the type column of the polymorphic
# association. To continue with the asset example above, suppose there are guest posts
# and member posts that use the posts table for STI. In this case, there must be a +type+
# column in the posts table.
#
# Note: The attachable_type= method is being called when assigning an +attachable+.
# The +class_name+ of the +attachable+ is passed as a String.
#
# class Asset < ActiveRecord::Base
# belongs_to :attachable, polymorphic: true
#
# def attachable_type=(class_name)
# super(class_name.constantize.base_class.to_s)
# end
# end
#
# class Post < ActiveRecord::Base
# # because we store "Post" in attachable_type now dependent: :destroy will work
# has_many :assets, as: :attachable, dependent: :destroy
# end
#
# class GuestPost < Post
# end
#
# class MemberPost < Post
# end
#
# == Caching
#
# All of the methods are built on a simple caching principle that will keep the result
# of the last query around unless specifically instructed not to. The cache is even
# shared across methods to make it even cheaper to use the macro-added methods without
# worrying too much about performance at the first go.
#
# project.milestones # fetches milestones from the database
# project.milestones.size # uses the milestone cache
# project.milestones.empty? # uses the milestone cache
# project.milestones.reload.size # fetches milestones from the database
# project.milestones # uses the milestone cache
#
# == Eager loading of associations
#
# Eager loading is a way to find objects of a certain class and a number of named associations.
# It is one of the easiest ways to prevent the dreaded N+1 problem in which fetching 100
# posts that each need to display their author triggers 101 database queries. Through the
# use of eager loading, the number of queries will be reduced from 101 to 2.
#
# class Post < ActiveRecord::Base
# belongs_to :author
# has_many :comments
# end
#
# Consider the following loop using the class above:
#
# Post.all.each do |post|
# puts "Post: " + post.title
# puts "Written by: " + post.author.name
# puts "Last comment on: " + post.comments.first.created_on
# end
#
# To iterate over these one hundred posts, we'll generate 201 database queries. Let's
# first just optimize it for retrieving the author:
#
# Post.includes(:author).each do |post|
#
# This references the name of the #belongs_to association that also used the :author
# symbol. After loading the posts, +find+ will collect the +author_id+ from each one and load
# all of the referenced authors with one query. Doing so will cut down the number of queries
# from 201 to 102.
#
# We can improve upon the situation further by referencing both associations in the finder with:
#
# Post.includes(:author, :comments).each do |post|
#
# This will load all comments with a single query. This reduces the total number of queries
# to 3. In general, the number of queries will be 1 plus the number of associations
# named (except if some of the associations are polymorphic #belongs_to - see below).
#
# To include a deep hierarchy of associations, use a hash:
#
# Post.includes(:author, { comments: { author: :gravatar } }).each do |post|
#
# The above code will load all the comments and all of their associated
# authors and gravatars. You can mix and match any combination of symbols,
# arrays, and hashes to retrieve the associations you want to load.
#
# All of this power shouldn't fool you into thinking that you can pull out huge amounts
# of data with no performance penalty just because you've reduced the number of queries.
# The database still needs to send all the data to Active Record and it still needs to
# be processed. So it's no catch-all for performance problems, but it's a great way to
# cut down on the number of queries in a situation as the one described above.
#
# Since only one table is loaded at a time, conditions or orders cannot reference tables
# other than the main one. If this is the case, Active Record falls back to the previously
# used LEFT OUTER JOIN based strategy. For example:
#
# Post.includes([:author, :comments]).where(['comments.approved = ?', true])
#
# This will result in a single SQL query with joins along the lines of:
# LEFT OUTER JOIN comments ON comments.post_id = posts.id and
# LEFT OUTER JOIN authors ON authors.id = posts.author_id. Note that using conditions
# like this can have unintended consequences.
# In the above example, posts with no approved comments are not returned at all because
# the conditions apply to the SQL statement as a whole and not just to the association.
#
# You must disambiguate column references for this fallback to happen, for example
# order: "author.name DESC" will work but order: "name DESC" will not.
#
# If you want to load all posts (including posts with no approved comments), then write
# your own LEFT OUTER JOIN query using ON:
#
# Post.joins("LEFT OUTER JOIN comments ON comments.post_id = posts.id AND comments.approved = '1'")
#
# In this case, it is usually more natural to include an association which has conditions defined on it:
#
# class Post < ActiveRecord::Base
# has_many :approved_comments, -> { where(approved: true) }, class_name: 'Comment'
# end
#
# Post.includes(:approved_comments)
#
# This will load posts and eager load the +approved_comments+ association, which contains
# only those comments that have been approved.
#
# If you eager load an association with a specified :limit option, it will be ignored,
# returning all the associated objects:
#
# class Picture < ActiveRecord::Base
# has_many :most_recent_comments, -> { order('id DESC').limit(10) }, class_name: 'Comment'
# end
#
# Picture.includes(:most_recent_comments).first.most_recent_comments # => returns all associated comments.
#
# Eager loading is supported with polymorphic associations.
#
# class Address < ActiveRecord::Base
# belongs_to :addressable, polymorphic: true
# end
#
# A call that tries to eager load the addressable model
#
# Address.includes(:addressable)
#
# This will execute one query to load the addresses and load the addressables with one
# query per addressable type.
# For example, if all the addressables are either of class Person or Company, then a total
# of 3 queries will be executed. The list of addressable types to load is determined on
# the back of the addresses loaded. This is not supported if Active Record has to fallback
# to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
# The reason is that the parent model's type is a column value so its corresponding table
# name cannot be put in the +FROM+/+JOIN+ clauses of that query.
#
# == Table Aliasing
#
# Active Record uses table aliasing in the case that a table is referenced multiple times
# in a join. If a table is referenced only once, the standard table name is used. The
# second time, the table is aliased as #{reflection_name}_#{parent_table_name}.
# Indexes are appended for any more successive uses of the table name.
#
# Post.joins(:comments)
# # => SELECT ... FROM posts INNER JOIN comments ON ...
# Post.joins(:special_comments) # STI
# # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
# Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
# # => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
#
# Acts as tree example:
#
# TreeMixin.joins(:children)
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
# TreeMixin.joins(children: :parent)
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
# INNER JOIN parents_mixins ...
# TreeMixin.joins(children: {parent: :children})
# # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
# INNER JOIN parents_mixins ...
# INNER JOIN mixins childrens_mixins_2
#
# Has and Belongs to Many join tables use the same idea, but add a _join suffix:
#
# Post.joins(:categories)
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
# Post.joins(categories: :posts)
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
# Post.joins(categories: {posts: :categories})
# # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
# INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
#
# If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
# names will take precedence over the eager associations:
#
# Post.joins(:comments).joins("inner join comments ...")
# # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
# Post.joins(:comments, :special_comments).joins("inner join comments ...")
# # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
# INNER JOIN comments special_comments_posts ...
# INNER JOIN comments ...
#
# Table aliases are automatically truncated according to the maximum length of table identifiers
# according to the specific database.
#
# == Modules
#
# By default, associations will look for objects within the current module scope. Consider:
#
# module MyApplication
# module Business
# class Firm < ActiveRecord::Base
# has_many :clients
# end
#
# class Client < ActiveRecord::Base; end
# end
# end
#
# When Firm#clients is called, it will in turn call
# MyApplication::Business::Client.find_all_by_firm_id(firm.id).
# If you want to associate with a class in another module scope, this can be done by
# specifying the complete class name.
#
# module MyApplication
# module Business
# class Firm < ActiveRecord::Base; end
# end
#
# module Billing
# class Account < ActiveRecord::Base
# belongs_to :firm, class_name: "MyApplication::Business::Firm"
# end
# end
# end
#
# == Bi-directional associations
#
# When you specify an association, there is usually an association on the associated model
# that specifies the same relationship in reverse. For example, with the following models:
#
# class Dungeon < ActiveRecord::Base
# has_many :traps
# has_one :evil_wizard
# end
#
# class Trap < ActiveRecord::Base
# belongs_to :dungeon
# end
#
# class EvilWizard < ActiveRecord::Base
# belongs_to :dungeon
# end
#
# The +traps+ association on +Dungeon+ and the +dungeon+ association on +Trap+ are
# the inverse of each other, and the inverse of the +dungeon+ association on +EvilWizard+
# is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
# Active Record can guess the inverse of the association based on the name
# of the class. The result is the following:
#
# d = Dungeon.first
# t = d.traps.first
# d.object_id == t.dungeon.object_id # => true
#
# The +Dungeon+ instances +d+ and t.dungeon in the above example refer to
# the same in-memory instance since the association matches the name of the class.
# The result would be the same if we added +:inverse_of+ to our model definitions:
#
# class Dungeon < ActiveRecord::Base
# has_many :traps, inverse_of: :dungeon
# has_one :evil_wizard, inverse_of: :dungeon
# end
#
# class Trap < ActiveRecord::Base
# belongs_to :dungeon, inverse_of: :traps
# end
#
# class EvilWizard < ActiveRecord::Base
# belongs_to :dungeon, inverse_of: :evil_wizard
# end
#
# For more information, see the documentation for the +:inverse_of+ option.
#
# == Deleting from associations
#
# === Dependent associations
#
# #has_many, #has_one, and #belongs_to associations support the :dependent option.
# This allows you to specify that associated records should be deleted when the owner is
# deleted.
#
# For example:
#
# class Author
# has_many :posts, dependent: :destroy
# end
# Author.find(1).destroy # => Will destroy all of the author's posts, too
#
# The :dependent option can have different values which specify how the deletion
# is done. For more information, see the documentation for this option on the different
# specific association types. When no option is given, the behavior is to do nothing
# with the associated records when destroying a record.
#
# Note that :dependent is implemented using Rails' callback
# system, which works by processing callbacks in order. Therefore, other
# callbacks declared either before or after the :dependent option
# can affect what it does.
#
# Note that :dependent option is ignored for #has_one :through associations.
#
# === Delete or destroy?
#
# #has_many and #has_and_belongs_to_many associations have the methods destroy,
# delete, destroy_all and delete_all.
#
# For #has_and_belongs_to_many, delete and destroy are the same: they
# cause the records in the join table to be removed.
#
# For #has_many, destroy and destroy_all will always call the destroy method of the
# record(s) being removed so that callbacks are run. However delete and delete_all will either
# do the deletion according to the strategy specified by the :dependent option, or
# if no :dependent option is given, then it will follow the default strategy.
# The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for
# #has_many :through, where the default strategy is delete_all (delete
# the join records, without running their callbacks).
#
# There is also a clear method which is the same as delete_all, except that
# it returns the association rather than the records which have been deleted.
#
# === What gets deleted?
#
# There is a potential pitfall here: #has_and_belongs_to_many and #has_many :through
# associations have records in join tables, as well as the associated records. So when we
# call one of these deletion methods, what exactly should be deleted?
#
# The answer is that it is assumed that deletion on an association is about removing the
# link between the owner and the associated object(s), rather than necessarily the
# associated objects themselves. So with #has_and_belongs_to_many and #has_many
# :through, the join records will be deleted, but the associated records won't.
#
# This makes sense if you think about it: if you were to call post.tags.delete(Tag.find_by(name: 'food'))
# you would want the 'food' tag to be unlinked from the post, rather than for the tag itself
# to be removed from the database.
#
# However, there are examples where this strategy doesn't make sense. For example, suppose
# a person has many projects, and each project has many tasks. If we deleted one of a person's
# tasks, we would probably not want the project to be deleted. In this scenario, the delete method
# won't actually work: it can only be used if the association on the join model is a
# #belongs_to. In other situations you are expected to perform operations directly on
# either the associated records or the :through association.
#
# With a regular #has_many there is no distinction between the "associated records"
# and the "link", so there is only one choice for what gets deleted.
#
# With #has_and_belongs_to_many and #has_many :through, if you want to delete the
# associated records themselves, you can always do something along the lines of
# person.tasks.each(&:destroy).
#
# == Type safety with ActiveRecord::AssociationTypeMismatch
#
# If you attempt to assign an object to an association that doesn't match the inferred
# or specified :class_name, you'll get an ActiveRecord::AssociationTypeMismatch.
#
# == Options
#
# All of the association macros can be specialized through options. This makes cases
# more complex than the simple and guessable ones possible.
module ClassMethods
# Specifies a one-to-many association. The following methods for retrieval and query of
# collections of associated objects will be added:
#
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
# has_many :clients would add among others clients.empty?.
#
# [collection]
# Returns a Relation of all the associated objects.
# An empty Relation is returned if none are found.
# [collection<<(object, ...)]
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
# parent object, unless the parent object is a new record.
# This will also run validations and callbacks of associated object(s).
# [collection.delete(object, ...)]
# Removes one or more objects from the collection by setting their foreign keys to +NULL+.
# Objects will be in addition destroyed if they're associated with dependent: :destroy,
# and deleted if they're associated with dependent: :delete_all.
#
# If the :through option is used, then the join records are deleted (rather than
# nullified) by default, but you can specify dependent: :destroy or
# dependent: :nullify to override this.
# [collection.destroy(object, ...)]
# Removes one or more objects from the collection by running destroy on
# each record, regardless of any dependent option, ensuring callbacks are run.
#
# If the :through option is used, then the join records are destroyed
# instead, not the objects themselves.
# [collection=objects]
# Replaces the collections content by deleting and adding objects as appropriate. If the :through
# option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
# direct by default. You can specify dependent: :destroy or
# dependent: :nullify to override this.
# [collection_singular_ids]
# Returns an array of the associated objects' ids
# [collection_singular_ids=ids]
# Replace the collection with the objects identified by the primary keys in +ids+. This
# method loads the models and calls collection=. See above.
# [collection.clear]
# Removes every object from the collection. This destroys the associated objects if they
# are associated with dependent: :destroy, deletes them directly from the
# database if dependent: :delete_all, otherwise sets their foreign keys to +NULL+.
# If the :through option is true no destroy callbacks are invoked on the join models.
# Join models are directly deleted.
# [collection.empty?]
# Returns +true+ if there are no associated objects.
# [collection.size]
# Returns the number of associated objects.
# [collection.find(...)]
# Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
# [collection.exists?(...)]
# Checks whether an associated object with the given conditions exists.
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
# [collection.build(attributes = {}, ...)]
# Returns one or more new objects of the collection type that have been instantiated
# with +attributes+ and linked to this object through a foreign key, but have not yet
# been saved.
# [collection.create(attributes = {})]
# Returns a new object of the collection type that has been instantiated
# with +attributes+, linked to this object through a foreign key, and that has already
# been saved (if it passed the validation). *Note*: This only works if the base model
# already exists in the DB, not if it is a new (unsaved) record!
# [collection.create!(attributes = {})]
# Does the same as collection.create, but raises ActiveRecord::RecordInvalid
# if the record is invalid.
# [collection.reload]
# Returns a Relation of all of the associated objects, forcing a database read.
# An empty Relation is returned if none are found.
#
# === Example
#
# A Firm class declares has_many :clients, which will add:
# * Firm#clients (similar to Client.where(firm_id: id))
# * Firm#clients<<
# * Firm#clients.delete
# * Firm#clients.destroy
# * Firm#clients=
# * Firm#client_ids
# * Firm#client_ids=
# * Firm#clients.clear
# * Firm#clients.empty? (similar to firm.clients.size == 0)
# * Firm#clients.size (similar to Client.count "firm_id = #{id}")
# * Firm#clients.find (similar to Client.where(firm_id: id).find(id))
# * Firm#clients.exists?(name: 'ACME') (similar to Client.exists?(name: 'ACME', firm_id: firm.id))
# * Firm#clients.build (similar to Client.new(firm_id: id))
# * Firm#clients.create (similar to c = Client.new(firm_id: id); c.save; c)
# * Firm#clients.create! (similar to c = Client.new(firm_id: id); c.save!)
# * Firm#clients.reload
# The declaration can also include an +options+ hash to specialize the behavior of the association.
#
# === Scopes
#
# You can pass a second argument +scope+ as a callable (i.e. proc or
# lambda) to retrieve a specific set of records or customize the generated
# query when you access the associated collection.
#
# Scope examples:
# has_many :comments, -> { where(author_id: 1) }
# has_many :employees, -> { joins(:address) }
# has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
#
# === Extensions
#
# The +extension+ argument allows you to pass a block into a has_many
# association. This is useful for adding new finders, creators and other
# factory-type methods to be used as part of the association.
#
# Extension examples:
# has_many :employees do
# def find_or_create_by_name(name)
# first_name, last_name = name.split(" ", 2)
# find_or_create_by(first_name: first_name, last_name: last_name)
# end
# end
#
# === Options
# [:class_name]
# Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So has_many :products will by default be linked
# to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
# specify it with this option.
# [:foreign_key]
# Specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
# association will use "person_id" as the default :foreign_key.
#
# If you are going to modify the association (rather than just read from it), then it is
# a good idea to set the :inverse_of option.
# [:foreign_type]
# Specify the column used to store the associated object's type, if this is a polymorphic
# association. By default this is guessed to be the name of the polymorphic association
# specified on "as" option with a "_type" suffix. So a class that defines a
# has_many :tags, as: :taggable association will use "taggable_type" as the
# default :foreign_type.
# [:primary_key]
# Specify the name of the column to use as the primary key for the association. By default this is +id+.
# [:dependent]
# Controls what happens to the associated objects when
# their owner is destroyed. Note that these are implemented as
# callbacks, and Rails executes callbacks in order. Therefore, other
# similar callbacks may affect the :dependent behavior, and the
# :dependent behavior may affect other callbacks.
#
# * :destroy causes all the associated objects to also be destroyed.
# * :delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
# * :nullify causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
# on polymorphic associations. Callbacks are not executed.
# * :restrict_with_exception causes an ActiveRecord::DeleteRestrictionError exception to be raised if there are any associated records.
# * :restrict_with_error causes an error to be added to the owner if there are any associated objects.
#
# If using with the :through option, the association on the join model must be
# a #belongs_to, and the records which get deleted are the join records, rather than
# the associated records.
#
# If using dependent: :destroy on a scoped association, only the scoped objects are destroyed.
# For example, if a Post model defines
# has_many :comments, -> { where published: true }, dependent: :destroy and destroy is
# called on a post, only published comments are destroyed. This means that any unpublished comments in the
# database would still contain a foreign key pointing to the now deleted post.
# [:counter_cache]
# This option can be used to configure a custom named :counter_cache. You only need this option,
# when you customized the name of your :counter_cache on the #belongs_to association.
# [:as]
# Specifies a polymorphic interface (See #belongs_to).
# [:through]
# Specifies an association through which to perform the query. This can be any other type
# of association, including other :through associations. Options for :class_name,
# :primary_key and :foreign_key are ignored, as the association uses the
# source reflection.
#
# If the association on the join model is a #belongs_to, the collection can be modified
# and the records on the :through model will be automatically created and removed
# as appropriate. Otherwise, the collection is read-only, so you should manipulate the
# :through association directly.
#
# If you are going to modify the association (rather than just read from it), then it is
# a good idea to set the :inverse_of option on the source association on the
# join model. This allows associated records to be built which will automatically create
# the appropriate join model records when they are saved. (See the 'Association Join Models'
# section above.)
# [:source]
# Specifies the source association name used by #has_many :through queries.
# Only use it if the name cannot be inferred from the association.
# has_many :subscribers, through: :subscriptions will look for either :subscribers or
# :subscriber on Subscription, unless a :source is given.
# [:source_type]
# Specifies type of the source association used by #has_many :through queries where the source
# association is a polymorphic #belongs_to.
# [:validate]
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
# [:autosave]
# If true, always save the associated objects or destroy them if marked for destruction,
# when saving the parent object. If false, never save or destroy the associated objects.
# By default, only save associated objects that are new records. This option is implemented as a
# +before_save+ callback. Because callbacks are run in the order they are defined, associated objects
# may need to be explicitly saved in any user-defined +before_save+ callbacks.
#
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
# :autosave to true.
# [:inverse_of]
# Specifies the name of the #belongs_to association on the associated object
# that is the inverse of this #has_many association.
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
# [:extend]
# Specifies a module or array of modules that will be extended into the association object returned.
# Useful for defining methods on associations, especially when they should be shared between multiple
# association objects.
#
# Option examples:
# has_many :comments, -> { order("posted_on") }
# has_many :comments, -> { includes(:author) }
# has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person"
# has_many :tracks, -> { order("position") }, dependent: :destroy
# has_many :comments, dependent: :nullify
# has_many :tags, as: :taggable
# has_many :reports, -> { readonly }
# has_many :subscribers, through: :subscriptions, source: :user
def has_many: (untyped name, ?untyped? scope, **untyped options) { () -> untyped } -> untyped
# Specifies a one-to-one association with another class. This method should only be used
# if the other class contains the foreign key. If the current class contains the foreign key,
# then you should use #belongs_to instead. See also ActiveRecord::Associations::ClassMethods's overview
# on when to use #has_one and when to use #belongs_to.
#
# The following methods for retrieval and query of a single associated object will be added:
#
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
# has_one :manager would add among others manager.nil?.
#
# [association]
# Returns the associated object. +nil+ is returned if none is found.
# [association=(associate)]
# Assigns the associate object, extracts the primary key, sets it as the foreign key,
# and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
# associated object when assigning a new one, even if the new one isn't saved to database.
# [build_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+ and linked to this object through a foreign key, but has not
# yet been saved.
# [create_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+, linked to this object through a foreign key, and that
# has already been saved (if it passed the validation).
# [create_association!(attributes = {})]
# Does the same as create_association, but raises ActiveRecord::RecordInvalid
# if the record is invalid.
# [reload_association]
# Returns the associated object, forcing a database read.
#
# === Example
#
# An Account class declares has_one :beneficiary, which will add:
# * Account#beneficiary (similar to Beneficiary.where(account_id: id).first)
# * Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save)
# * Account#build_beneficiary (similar to Beneficiary.new(account_id: id))
# * Account#create_beneficiary (similar to b = Beneficiary.new(account_id: id); b.save; b)
# * Account#create_beneficiary! (similar to b = Beneficiary.new(account_id: id); b.save!; b)
# * Account#reload_beneficiary
#
# === Scopes
#
# You can pass a second argument +scope+ as a callable (i.e. proc or
# lambda) to retrieve a specific record or customize the generated query
# when you access the associated object.
#
# Scope examples:
# has_one :author, -> { where(comment_id: 1) }
# has_one :employer, -> { joins(:company) }
# has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
#
# === Options
#
# The declaration can also include an +options+ hash to specialize the behavior of the association.
#
# Options are:
# [:class_name]
# Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So has_one :manager will by default be linked to the Manager class, but
# if the real class name is Person, you'll have to specify it with this option.
# [:dependent]
# Controls what happens to the associated object when
# its owner is destroyed:
#
# * :destroy causes the associated object to also be destroyed
# * :delete causes the associated object to be deleted directly from the database (so callbacks will not execute)
# * :nullify causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
# on polymorphic associations. Callbacks are not executed.
# * :restrict_with_exception causes an ActiveRecord::DeleteRestrictionError exception to be raised if there is an associated record
# * :restrict_with_error causes an error to be added to the owner if there is an associated object
#
# Note that :dependent option is ignored when using :through option.
# [:foreign_key]
# Specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
# will use "person_id" as the default :foreign_key.
#
# If you are going to modify the association (rather than just read from it), then it is
# a good idea to set the :inverse_of option.
# [:foreign_type]
# Specify the column used to store the associated object's type, if this is a polymorphic
# association. By default this is guessed to be the name of the polymorphic association
# specified on "as" option with a "_type" suffix. So a class that defines a
# has_one :tag, as: :taggable association will use "taggable_type" as the
# default :foreign_type.
# [:primary_key]
# Specify the method that returns the primary key used for the association. By default this is +id+.
# [:as]
# Specifies a polymorphic interface (See #belongs_to).
# [:through]
# Specifies a Join Model through which to perform the query. Options for :class_name,
# :primary_key, and :foreign_key are ignored, as the association uses the
# source reflection. You can only use a :through query through a #has_one
# or #belongs_to association on the join model.
#
# If you are going to modify the association (rather than just read from it), then it is
# a good idea to set the :inverse_of option.
# [:source]
# Specifies the source association name used by #has_one :through queries.
# Only use it if the name cannot be inferred from the association.
# has_one :favorite, through: :favorites will look for a
# :favorite on Favorite, unless a :source is given.
# [:source_type]
# Specifies type of the source association used by #has_one :through queries where the source
# association is a polymorphic #belongs_to.
# [:validate]
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
# [:autosave]
# If true, always save the associated object or destroy it if marked for destruction,
# when saving the parent object. If false, never save or destroy the associated object.
# By default, only save the associated object if it's a new record.
#
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
# :autosave to true.
# [:inverse_of]
# Specifies the name of the #belongs_to association on the associated object
# that is the inverse of this #has_one association.
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
# [:required]
# When set to +true+, the association will also have its presence validated.
# This will validate the association itself, not the id. You can use
# +:inverse_of+ to avoid an extra query during validation.
#
# Option examples:
# has_one :credit_card, dependent: :destroy # destroys the associated credit card
# has_one :credit_card, dependent: :nullify # updates the associated records foreign
# # key value to NULL rather than destroying it
# has_one :last_comment, -> { order('posted_on') }, class_name: "Comment"
# has_one :project_manager, -> { where(role: 'project_manager') }, class_name: "Person"
# has_one :attachment, as: :attachable
# has_one :boss, -> { readonly }
# has_one :club, through: :membership
# has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
# has_one :credit_card, required: true
def has_one: (untyped name, ?untyped? scope, **untyped options) -> untyped
# Specifies a one-to-one association with another class. This method should only be used
# if this class contains the foreign key. If the other class contains the foreign key,
# then you should use #has_one instead. See also ActiveRecord::Associations::ClassMethods's overview
# on when to use #has_one and when to use #belongs_to.
#
# Methods will be added for retrieval and query for a single associated object, for which
# this object holds an id:
#
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
# belongs_to :author would add among others author.nil?.
#
# [association]
# Returns the associated object. +nil+ is returned if none is found.
# [association=(associate)]
# Assigns the associate object, extracts the primary key, and sets it as the foreign key.
# No modification or deletion of existing records takes place.
# [build_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
# [create_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+, linked to this object through a foreign key, and that
# has already been saved (if it passed the validation).
# [create_association!(attributes = {})]
# Does the same as create_association, but raises ActiveRecord::RecordInvalid
# if the record is invalid.
# [reload_association]
# Returns the associated object, forcing a database read.
#
# === Example
#
# A Post class declares belongs_to :author, which will add:
# * Post#author (similar to Author.find(author_id))
# * Post#author=(author) (similar to post.author_id = author.id)
# * Post#build_author (similar to post.author = Author.new)
# * Post#create_author (similar to post.author = Author.new; post.author.save; post.author)
# * Post#create_author! (similar to post.author = Author.new; post.author.save!; post.author)
# * Post#reload_author
# The declaration can also include an +options+ hash to specialize the behavior of the association.
#
# === Scopes
#
# You can pass a second argument +scope+ as a callable (i.e. proc or
# lambda) to retrieve a specific record or customize the generated query
# when you access the associated object.
#
# Scope examples:
# belongs_to :firm, -> { where(id: 2) }
# belongs_to :user, -> { joins(:friends) }
# belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
#
# === Options
#
# [:class_name]
# Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So belongs_to :author will by default be linked to the Author class, but
# if the real class name is Person, you'll have to specify it with this option.
# [:foreign_key]
# Specify the foreign key used for the association. By default this is guessed to be the name
# of the association with an "_id" suffix. So a class that defines a belongs_to :person
# association will use "person_id" as the default :foreign_key. Similarly,
# belongs_to :favorite_person, class_name: "Person" will use a foreign key
# of "favorite_person_id".
#
# If you are going to modify the association (rather than just read from it), then it is
# a good idea to set the :inverse_of option.
# [:foreign_type]
# Specify the column used to store the associated object's type, if this is a polymorphic
# association. By default this is guessed to be the name of the association with a "_type"
# suffix. So a class that defines a belongs_to :taggable, polymorphic: true
# association will use "taggable_type" as the default :foreign_type.
# [:primary_key]
# Specify the method that returns the primary key of associated object used for the association.
# By default this is +id+.
# [:dependent]
# If set to :destroy, the associated object is destroyed when this object is. If set to
# :delete, the associated object is deleted *without* calling its destroy method.
# This option should not be specified when #belongs_to is used in conjunction with
# a #has_many relationship on another class because of the potential to leave
# orphaned records behind.
# [:counter_cache]
# Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
# and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
# class is created and decremented when it's destroyed. This requires that a column
# named #{table_name}_count (such as +comments_count+ for a belonging Comment class)
# is used on the associate class (such as a Post class) - that is the migration for
# #{table_name}_count is created on the associate class (such that Post.comments_count will
# return the count cached, see note below). You can also specify a custom counter
# cache column by providing a column name instead of a +true+/+false+ value to this
# option (e.g., counter_cache: :my_custom_counter.)
# Note: Specifying a counter cache will add it to that model's list of readonly attributes
# using +attr_readonly+.
# [:polymorphic]
# Specify this association is a polymorphic association by passing +true+.
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
# to the +attr_readonly+ list in the associated classes (e.g. class Post; attr_readonly :comments_count; end).
# [:validate]
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
# [:autosave]
# If true, always save the associated object or destroy it if marked for destruction, when
# saving the parent object.
# If false, never save or destroy the associated object.
# By default, only save the associated object if it's a new record.
#
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
# sets :autosave to true.
# [:touch]
# If true, the associated object will be touched (the updated_at/on attributes set to current time)
# when this record is either saved or destroyed. If you specify a symbol, that attribute
# will be updated with the current time in addition to the updated_at/on attribute.
# Please note that with touching no validation is performed and only the +after_touch+,
# +after_commit+ and +after_rollback+ callbacks are executed.
# [:inverse_of]
# Specifies the name of the #has_one or #has_many association on the associated
# object that is the inverse of this #belongs_to association.
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
# [:optional]
# When set to +true+, the association will not have its presence validated.
# [:required]
# When set to +true+, the association will also have its presence validated.
# This will validate the association itself, not the id. You can use
# +:inverse_of+ to avoid an extra query during validation.
# NOTE: required is set to true by default and is deprecated. If
# you don't want to have association presence validated, use optional: true.
# [:default]
# Provide a callable (i.e. proc or lambda) to specify that the association should
# be initialized with a particular record before validation.
#
# Option examples:
# belongs_to :firm, foreign_key: "client_of"
# belongs_to :person, primary_key: "name", foreign_key: "person_name"
# belongs_to :author, class_name: "Person", foreign_key: "author_id"
# belongs_to :valid_coupon, ->(o) { where "discounts > ?", o.payments_count },
# class_name: "Coupon", foreign_key: "coupon_id"
# belongs_to :attachable, polymorphic: true
# belongs_to :project, -> { readonly }
# belongs_to :post, counter_cache: true
# belongs_to :comment, touch: true
# belongs_to :company, touch: :employees_last_updated_at
# belongs_to :user, optional: true
# belongs_to :account, default: -> { company.account }
def belongs_to: (untyped name, ?untyped? scope, **untyped options) -> untyped
# Specifies a many-to-many relationship with another class. This associates two classes via an
# intermediate join table. Unless the join table is explicitly specified as an option, it is
# guessed using the lexical order of the class names. So a join between Developer and Project
# will give the default join table name of "developers_projects" because "D" precedes "P" alphabetically.
# Note that this precedence is calculated using the < operator for String. This
# means that if the strings are of different lengths, and the strings are equal when compared
# up to the shortest length, then the longer string is considered of higher
# lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers"
# to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes",
# but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the
# custom :join_table option if you need to.
# If your tables share a common prefix, it will only appear once at the beginning. For example,
# the tables "catalog_categories" and "catalog_products" generate a join table name of "catalog_categories_products".
#
# The join table should not have a primary key or a model associated with it. You must manually generate the
# join table with a migration such as this:
#
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[5.0]
# def change
# create_join_table :developers, :projects
# end
# end
#
# It's also a good idea to add indexes to each of those columns to speed up the joins process.
# However, in MySQL it is advised to add a compound index for both of the columns as MySQL only
# uses one index per table during the lookup.
#
# Adds the following methods for retrieval and query:
#
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
# has_and_belongs_to_many :categories would add among others categories.empty?.
#
# [collection]
# Returns a Relation of all the associated objects.
# An empty Relation is returned if none are found.
# [collection<<(object, ...)]
# Adds one or more objects to the collection by creating associations in the join table
# (collection.push and collection.concat are aliases to this method).
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
# parent object, unless the parent object is a new record.
# [collection.delete(object, ...)]
# Removes one or more objects from the collection by removing their associations from the join table.
# This does not destroy the objects.
# [collection.destroy(object, ...)]
# Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
# This does not destroy the objects.
# [collection=objects]
# Replaces the collection's content by deleting and adding objects as appropriate.
# [collection_singular_ids]
# Returns an array of the associated objects' ids.
# [collection_singular_ids=ids]
# Replace the collection by the objects identified by the primary keys in +ids+.
# [collection.clear]
# Removes every object from the collection. This does not destroy the objects.
# [collection.empty?]
# Returns +true+ if there are no associated objects.
# [collection.size]
# Returns the number of associated objects.
# [collection.find(id)]
# Finds an associated object responding to the +id+ and that
# meets the condition that it has to be associated with this object.
# Uses the same rules as ActiveRecord::FinderMethods#find.
# [collection.exists?(...)]
# Checks whether an associated object with the given conditions exists.
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
# [collection.build(attributes = {})]
# Returns a new object of the collection type that has been instantiated
# with +attributes+ and linked to this object through the join table, but has not yet been saved.
# [collection.create(attributes = {})]
# Returns a new object of the collection type that has been instantiated
# with +attributes+, linked to this object through the join table, and that has already been
# saved (if it passed the validation).
# [collection.reload]
# Returns a Relation of all of the associated objects, forcing a database read.
# An empty Relation is returned if none are found.
#
# === Example
#
# A Developer class declares has_and_belongs_to_many :projects, which will add:
# * Developer#projects
# * Developer#projects<<
# * Developer#projects.delete
# * Developer#projects.destroy
# * Developer#projects=
# * Developer#project_ids
# * Developer#project_ids=
# * Developer#projects.clear
# * Developer#projects.empty?
# * Developer#projects.size
# * Developer#projects.find(id)
# * Developer#projects.exists?(...)
# * Developer#projects.build (similar to Project.new(developer_id: id))
# * Developer#projects.create (similar to c = Project.new(developer_id: id); c.save; c)
# * Developer#projects.reload
# The declaration may include an +options+ hash to specialize the behavior of the association.
#
# === Scopes
#
# You can pass a second argument +scope+ as a callable (i.e. proc or
# lambda) to retrieve a specific set of records or customize the generated
# query when you access the associated collection.
#
# Scope examples:
# has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
# has_and_belongs_to_many :categories, ->(post) {
# where("default_category = ?", post.default_category)
# }
#
# === Extensions
#
# The +extension+ argument allows you to pass a block into a
# has_and_belongs_to_many association. This is useful for adding new
# finders, creators and other factory-type methods to be used as part of
# the association.
#
# Extension examples:
# has_and_belongs_to_many :contractors do
# def find_or_create_by_name(name)
# first_name, last_name = name.split(" ", 2)
# find_or_create_by(first_name: first_name, last_name: last_name)
# end
# end
#
# === Options
#
# [:class_name]
# Specify the class name of the association. Use it only if that name can't be inferred
# from the association name. So has_and_belongs_to_many :projects will by default be linked to the
# Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
# [:join_table]
# Specify the name of the join table if the default based on lexical order isn't what you want.
# WARNING: If you're overwriting the table name of either class, the +table_name+ method
# MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
# [:foreign_key]
# Specify the foreign key used for the association. By default this is guessed to be the name
# of this class in lower-case and "_id" suffixed. So a Person class that makes
# a #has_and_belongs_to_many association to Project will use "person_id" as the
# default :foreign_key.
#
# If you are going to modify the association (rather than just read from it), then it is
# a good idea to set the :inverse_of option.
# [:association_foreign_key]
# Specify the foreign key used for the association on the receiving side of the association.
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
# So if a Person class makes a #has_and_belongs_to_many association to Project,
# the association will use "project_id" as the default :association_foreign_key.
# [:validate]
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
# [:autosave]
# If true, always save the associated objects or destroy them if marked for destruction, when
# saving the parent object.
# If false, never save or destroy the associated objects.
# By default, only save associated objects that are new records.
#
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
# :autosave to true.
#
# Option examples:
# has_and_belongs_to_many :projects
# has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
# has_and_belongs_to_many :nations, class_name: "Country"
# has_and_belongs_to_many :categories, join_table: "prods_cats"
# has_and_belongs_to_many :categories, -> { readonly }
def has_and_belongs_to_many: (untyped name, ?untyped? scope, **untyped options) { () -> untyped } -> untyped
end
end
end
module ActiveRecord
module Associations
class SingularAssociation < Association
# nodoc:
# Implements the reader method, e.g. foo.bar for Foo.has_one :bar
def reader: () -> untyped
# Implements the writer method, e.g. foo.bar= for Foo.belongs_to :bar
def writer: (untyped record) -> untyped
def build: (?::Hash[untyped, untyped] attributes) { () -> untyped } -> untyped
# Implements the reload reader method, e.g. foo.reload_bar for
# Foo.has_one :bar
def force_reload_reader: () -> untyped
def scope_for_create: () -> untyped
def find_target: () -> untyped
def replace: (untyped record) -> untyped
def set_new_record: (untyped record) -> untyped
def _create_record: (untyped attributes, ?bool raise_error) { () -> untyped } -> untyped
end
end
end
module ActiveRecord
module Associations
module ThroughAssociation
def through_reflection: () -> untyped
def through_association: () -> untyped
# We merge in these scopes for two reasons:
#
# 1. To get the default_scope conditions for any of the other reflections in the chain
# 2. To get the type conditions for any STI models in the chain
def target_scope: () -> untyped
# Construct attributes for :through pointing to owner and associate. This is used by the
# methods which create and delete records on the association.
#
# We only support indirectly modifying through associations which have a belongs_to source.
# This is the "has_many :tags, through: :taggings" situation, where the join model
# typically has a belongs_to on both side. In other words, associations which could also
# be represented as has_and_belongs_to_many associations.
#
# We do not support creating/deleting records on the association where the source has
# some other type, because this opens up a whole can of worms, and in basically any
# situation it is more natural for the user to just create or modify their join records
# directly as required.
def construct_join_attributes: (*untyped records) -> untyped
# Note: this does not capture all cases, for example it would be crazy to try to
# properly support stale-checking for nested associations.
def stale_state: () -> untyped
def foreign_key_present?: () -> untyped
def ensure_mutable: () -> untyped
def ensure_not_nested: () -> untyped
def build_record: (untyped attributes) -> untyped
end
end
end
module ActiveRecord
module AttributeAssignment
include ActiveModel::AttributeAssignment
def _assign_attributes: (untyped attributes) -> untyped
# Assign any deferred nested attributes after the base attributes have been set.
def assign_nested_parameter_attributes: (untyped pairs) -> untyped
# Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
# by calling new on the column type or aggregation type (through composed_of) object with these parameters.
# So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
# written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
# parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
# f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
def assign_multiparameter_attributes: (untyped pairs) -> untyped
def execute_callstack_for_multiparameter_attributes: (untyped callstack) -> untyped
def extract_callstack_for_multiparameter_attributes: (untyped pairs) -> untyped
def type_cast_attribute_value: (untyped multiparameter_name, untyped value) -> untyped
def find_parameter_position: (untyped multiparameter_name) -> untyped
end
end
module ActiveRecord
module AttributeDecorators
# :nodoc:
extend ActiveSupport::Concern
module ClassMethods
# :nodoc:
# This method is an internal API used to create class macros such as
# +serialize+, and features like time zone aware attributes.
#
# Used to wrap the type of an attribute in a new type.
# When the schema for a model is loaded, attributes with the same name as
# +column_name+ will have their type yielded to the given block. The
# return value of that block will be used instead.
#
# Subsequent calls where +column_name+ and +decorator_name+ are the same
# will override the previous decorator, not decorate twice. This can be
# used to create idempotent class macros like +serialize+
def decorate_attribute_type: (untyped column_name, untyped decorator_name) { () -> untyped } -> untyped
# This method is an internal API used to create higher level features like
# time zone aware attributes.
#
# When the schema for a model is loaded, +matcher+ will be called for each
# attribute with its name and type. If the matcher returns a truthy value,
# the type will then be yielded to the given block, and the return value
# of that block will replace the type.
#
# Subsequent calls to this method with the same value for +decorator_name+
# will replace the previous decorator, not decorate twice. This can be
# used to ensure that class macros are idempotent.
def decorate_matching_attribute_types: (untyped matcher, untyped decorator_name) { () -> untyped } -> untyped
def load_schema!: () -> untyped
end
class TypeDecorator
def initialize: (?::Hash[untyped, untyped] decorations) -> untyped
def merge: (*untyped args) -> TypeDecorator
def apply: (untyped name, untyped `type`) -> untyped
def decorators_for: (untyped name, untyped `type`) -> untyped
def matching: (untyped name, untyped `type`) -> untyped
end
end
end
module ActiveRecord
module AttributeMethods
extend ::ActiveRecord::AttributeMethods::Serialization::ClassMethods
extend ::ActiveRecord::AttributeMethods::TimeZoneConversion::ClassMethods
extend ::ActiveRecord::AttributeMethods::PrimaryKey::ClassMethods
extend ::ActiveRecord::AttributeMethods::Write::ClassMethods
extend ::ActiveRecord::AttributeMethods::Read::ClassMethods
extend ::ActiveModel::AttributeMethods::ClassMethods
# = Active Record Attribute Methods Before Type Cast
#
# ActiveRecord::AttributeMethods::BeforeTypeCast provides a way to
# read the value of the attributes before typecasting and deserialization.
#
# class Task < ActiveRecord::Base
# end
#
# task = Task.new(id: '1', completed_on: '2012-10-21')
# task.id # => 1
# task.completed_on # => Sun, 21 Oct 2012
#
# task.attributes_before_type_cast
# # => {"id"=>"1", "completed_on"=>"2012-10-21", ... }
# task.read_attribute_before_type_cast('id') # => "1"
# task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
#
# In addition to #read_attribute_before_type_cast and #attributes_before_type_cast,
# it declares a method for all attributes with the *_before_type_cast
# suffix.
#
# task.id_before_type_cast # => "1"
# task.completed_on_before_type_cast # => "2012-10-21"
module BeforeTypeCast
extend ActiveSupport::Concern
# Returns the value of the attribute identified by +attr_name+ before
# typecasting and deserialization.
#
# class Task < ActiveRecord::Base
# end
#
# task = Task.new(id: '1', completed_on: '2012-10-21')
# task.read_attribute('id') # => 1
# task.read_attribute_before_type_cast('id') # => '1'
# task.read_attribute('completed_on') # => Sun, 21 Oct 2012
# task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
# task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21"
def read_attribute_before_type_cast: (untyped attr_name) -> untyped
# Returns a hash of attributes before typecasting and deserialization.
#
# class Task < ActiveRecord::Base
# end
#
# task = Task.new(title: nil, is_done: true, completed_on: '2012-10-21')
# task.attributes
# # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>Sun, 21 Oct 2012, "created_at"=>nil, "updated_at"=>nil}
# task.attributes_before_type_cast
# # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
def attributes_before_type_cast: () -> untyped
# Dispatch target for *_before_type_cast attribute methods.
def attribute_before_type_cast: (untyped attribute_name) -> untyped
def attribute_came_from_user?: (untyped attribute_name) -> untyped
end
end
end
module ActiveRecord
module AttributeMethods
module Dirty
extend ActiveSupport::Concern
include ActiveModel::Dirty
# reload the record and clears changed attributes.
def reload: () -> untyped
# Did this attribute change when we last saved?
#
# This method is useful in after callbacks to determine if an attribute
# was changed during the save that triggered the callbacks to run. It can
# be invoked as +saved_change_to_name?+ instead of
# saved_change_to_attribute?("name").
#
# ==== Options
#
# +from+ When passed, this method will return false unless the original
# value is equal to the given option
#
# +to+ When passed, this method will return false unless the value was
# changed to the given value
def saved_change_to_attribute?: (untyped attr_name, **untyped options) -> untyped
# Returns the change to an attribute during the last save. If the
# attribute was changed, the result will be an array containing the
# original value and the saved value.
#
# This method is useful in after callbacks, to see the change in an
# attribute during the save that triggered the callbacks to run. It can be
# invoked as +saved_change_to_name+ instead of
# saved_change_to_attribute("name").
def saved_change_to_attribute: (untyped attr_name) -> untyped
# Returns the original value of an attribute before the last save.
#
# This method is useful in after callbacks to get the original value of an
# attribute before the save that triggered the callbacks to run. It can be
# invoked as +name_before_last_save+ instead of
# attribute_before_last_save("name").
def attribute_before_last_save: (untyped attr_name) -> untyped
# Did the last call to +save+ have any changes to change?
def saved_changes?: () -> untyped
# Returns a hash containing all the changes that were just saved.
def saved_changes: () -> untyped
# Will this attribute change the next time we save?
#
# This method is useful in validations and before callbacks to determine
# if the next call to +save+ will change a particular attribute. It can be
# invoked as +will_save_change_to_name?+ instead of
# will_save_change_to_attribute("name").
#
# ==== Options
#
# +from+ When passed, this method will return false unless the original
# value is equal to the given option
#
# +to+ When passed, this method will return false unless the value will be
# changed to the given value
def will_save_change_to_attribute?: (untyped attr_name, **untyped options) -> untyped
# Returns the change to an attribute that will be persisted during the
# next save.
#
# This method is useful in validations and before callbacks, to see the
# change to an attribute that will occur when the record is saved. It can
# be invoked as +name_change_to_be_saved+ instead of
# attribute_change_to_be_saved("name").
#
# If the attribute will change, the result will be an array containing the
# original value and the new value about to be saved.
def attribute_change_to_be_saved: (untyped attr_name) -> untyped
# Returns the value of an attribute in the database, as opposed to the
# in-memory value that will be persisted the next time the record is
# saved.
#
# This method is useful in validations and before callbacks, to see the
# original value of an attribute prior to any changes about to be
# saved. It can be invoked as +name_in_database+ instead of
# attribute_in_database("name").
def attribute_in_database: (untyped attr_name) -> untyped
# Will the next call to +save+ have any changes to persist?
def has_changes_to_save?: () -> untyped
# Returns a hash containing all the changes that will be persisted during
# the next save.
def changes_to_save: () -> untyped
# Returns an array of the names of any attributes that will change when
# the record is next saved.
def changed_attribute_names_to_save: () -> untyped
# Returns a hash of the attributes that will change when the record is
# next saved.
#
# The hash keys are the attribute names, and the hash values are the
# original attribute values in the database (as opposed to the in-memory
# values about to be saved).
def attributes_in_database: () -> untyped
def mutations_from_database: () -> untyped
def mutations_before_last_save: () -> untyped
def write_attribute_without_type_cast: (untyped attr_name, untyped value) -> untyped
def _touch_row: (untyped attribute_names, untyped time) -> untyped
def _update_record: (?untyped attribute_names) -> untyped
def _create_record: (?untyped attribute_names) -> untyped
def attribute_names_for_partial_writes: () -> untyped
end
end
end
module ActiveRecord
module AttributeMethods
module PrimaryKey
extend ActiveSupport::Concern
# Returns this record's primary key value wrapped in an array if one is
# available.
def to_key: () -> untyped
# Returns the primary key column's value.
def id: () -> untyped
# Sets the primary key column's value.
def id=: (untyped value) -> untyped
# Queries the primary key column's value.
def id?: () -> untyped
# Returns the primary key column's value before type cast.
def id_before_type_cast: () -> untyped
# Returns the primary key column's previous value.
def id_was: () -> untyped
# Returns the primary key column's value from the database.
def id_in_database: () -> untyped
def attribute_method?: (untyped attr_name) -> untyped
module ClassMethods
ID_ATTRIBUTE_METHODS: untyped
def instance_method_already_implemented?: (untyped method_name) -> untyped
def dangerous_attribute_method?: (untyped method_name) -> untyped
# Defines the primary key field -- can be overridden in subclasses.
# Overwriting will negate any effect of the +primary_key_prefix_type+
# setting, though.
def primary_key: () -> untyped
# Returns a quoted version of the primary key name, used to construct
# SQL statements.
def quoted_primary_key: () -> untyped
def reset_primary_key: () -> untyped
def get_primary_key: (untyped base_name) -> untyped
# Sets the name of the primary key column.
#
# class Project < ActiveRecord::Base
# self.primary_key = 'sysid'
# end
#
# You can also define the #primary_key method yourself:
#
# class Project < ActiveRecord::Base
# def self.primary_key
# 'foo_' + super
# end
# end
#
# Project.primary_key # => "foo_id"
def primary_key=: (untyped value) -> untyped
def suppress_composite_primary_key: (untyped pk) -> untyped
end
end
end
end
module ActiveRecord
module AttributeMethods
module Query
extend ActiveSupport::Concern
def query_attribute: (untyped attr_name) -> (::FalseClass | untyped)
# Dispatch target for *? attribute methods.
def attribute?: (untyped attribute_name) -> untyped
end
end
end
module ActiveRecord
# = Active Record Attribute Methods
module AttributeMethods
extend ActiveSupport::Concern
include ActiveModel::AttributeMethods
include Read
include Write
include BeforeTypeCast
include Query
include PrimaryKey
include TimeZoneConversion
include Dirty
include Serialization
RESTRICTED_CLASS_METHODS: ::Array[untyped]
class GeneratedAttributeMethods < Module
# nodoc:
include Mutex_m
end
module ClassMethods
def inherited: (untyped child_class) -> untyped
def initialize_generated_modules: () -> untyped
def define_attribute_methods: () -> (::FalseClass | untyped)
def undefine_attribute_methods: () -> untyped
# Raises an ActiveRecord::DangerousAttributeError exception when an
# \Active \Record method is defined in the model, otherwise +false+.
#
# class Person < ActiveRecord::Base
# def save
# 'already defined by Active Record'
# end
# end
#
# Person.instance_method_already_implemented?(:save)
# # => ActiveRecord::DangerousAttributeError: save is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
#
# Person.instance_method_already_implemented?(:name)
# # => false
def instance_method_already_implemented?: (untyped method_name) -> untyped
def dangerous_attribute_method?: (untyped name) -> untyped
def method_defined_within?: (untyped name, untyped klass, ?untyped superklass) -> untyped
# A class method is 'dangerous' if it is already (re)defined by Active Record, but
# not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
def dangerous_class_method?: (untyped method_name) -> untyped
def class_method_defined_within?: (untyped name, untyped klass, ?untyped superklass) -> untyped
# Returns +true+ if +attribute+ is an attribute method and table exists,
# +false+ otherwise.
#
# class Person < ActiveRecord::Base
# end
#
# Person.attribute_method?('name') # => true
# Person.attribute_method?(:age=) # => true
# Person.attribute_method?(:nothing) # => false
def attribute_method?: (untyped attribute) -> untyped
# Returns an array of column names as strings if it's not an abstract class and
# table exists. Otherwise it returns an empty array.
#
# class Person < ActiveRecord::Base
# end
#
# Person.attribute_names
# # => ["id", "created_at", "updated_at", "name", "age"]
def attribute_names: () -> untyped
# Returns true if the given attribute exists, otherwise false.
#
# class Person < ActiveRecord::Base
# end
#
# Person.has_attribute?('name') # => true
# Person.has_attribute?(:age) # => true
# Person.has_attribute?(:nothing) # => false
def has_attribute?: (untyped attr_name) -> untyped
# Returns the column object for the named attribute.
# Returns a +ActiveRecord::ConnectionAdapters::NullColumn+ if the
# named attribute does not exist.
#
# class Person < ActiveRecord::Base
# end
#
# person = Person.new
# person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
# # => #
#
# person.column_for_attribute(:nothing)
# # => #, ...>
def column_for_attribute: (untyped name) -> untyped
end
# A Person object with a name attribute can ask person.respond_to?(:name),
# person.respond_to?(:name=), and person.respond_to?(:name?)
# which will all return +true+. It also defines the attribute methods if they have
# not been generated.
#
# class Person < ActiveRecord::Base
# end
#
# person = Person.new
# person.respond_to?(:name) # => true
# person.respond_to?(:name=) # => true
# person.respond_to?(:name?) # => true
# person.respond_to?('age') # => true
# person.respond_to?('age=') # => true
# person.respond_to?('age?') # => true
# person.respond_to?(:nothing) # => false
def respond_to?: (untyped name, ?bool include_private) -> (::FalseClass | untyped | ::TrueClass)
# Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
#
# class Person < ActiveRecord::Base
# end
#
# person = Person.new
# person.has_attribute?(:name) # => true
# person.has_attribute?('age') # => true
# person.has_attribute?(:nothing) # => false
def has_attribute?: (untyped attr_name) -> untyped
# Returns an array of names for the attributes available on this object.
#
# class Person < ActiveRecord::Base
# end
#
# person = Person.new
# person.attribute_names
# # => ["id", "created_at", "updated_at", "name", "age"]
def attribute_names: () -> untyped
# Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
#
# class Person < ActiveRecord::Base
# end
#
# person = Person.create(name: 'Francesco', age: 22)
# person.attributes
# # => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
def attributes: () -> untyped
# Returns an #inspect-like string for the value of the
# attribute +attr_name+. String attributes are truncated up to 50
# characters, Date and Time attributes are returned in the
# :db format. Other attributes return the value of
# #inspect without modification.
#
# person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
#
# person.attribute_for_inspect(:name)
# # => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
#
# person.attribute_for_inspect(:created_at)
# # => "\"2012-10-22 00:15:07\""
#
# person.attribute_for_inspect(:tag_ids)
# # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
def attribute_for_inspect: (untyped attr_name) -> untyped
# Returns +true+ if the specified +attribute+ has been set by the user or by a
# database load and is neither +nil+ nor empty? (the latter only applies
# to objects that respond to empty?, most notably Strings). Otherwise, +false+.
# Note that it always returns +true+ with boolean attributes.
#
# class Task < ActiveRecord::Base
# end
#
# task = Task.new(title: '', is_done: false)
# task.attribute_present?(:title) # => false
# task.attribute_present?(:is_done) # => true
# task.title = 'Buy milk'
# task.is_done = true
# task.attribute_present?(:title) # => true
# task.attribute_present?(:is_done) # => true
def attribute_present?: (untyped attribute) -> untyped
# Returns the value of the attribute identified by attr_name after it has been typecast (for example,
# "2004-12-12" in a date column is cast to a date object, like Date.new(2004, 12, 12)). It raises
# ActiveModel::MissingAttributeError if the identified attribute is missing.
#
# Note: +:id+ is always present.
#
# class Person < ActiveRecord::Base
# belongs_to :organization
# end
#
# person = Person.new(name: 'Francesco', age: '22')
# person[:name] # => "Francesco"
# person[:age] # => 22
#
# person = Person.select('id').first
# person[:name] # => ActiveModel::MissingAttributeError: missing attribute: name
# person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute: organization_id
def []: (untyped attr_name) -> untyped
# Updates the attribute identified by attr_name with the specified +value+.
# (Alias for the protected #write_attribute method).
#
# class Person < ActiveRecord::Base
# end
#
# person = Person.new
# person[:age] = '22'
# person[:age] # => 22
# person[:age].class # => Integer
def []=: (untyped attr_name, untyped value) -> untyped
# Returns the name of all database fields which have been read from this
# model. This can be useful in development mode to determine which fields
# need to be selected. For performance critical pages, selecting only the
# required fields can be an easy performance win (assuming you aren't using
# all of the fields on the model).
#
# For example:
#
# class PostsController < ActionController::Base
# after_action :print_accessed_fields, only: :index
#
# def index
# @posts = Post.all
# end
#
# private
#
# def print_accessed_fields
# p @posts.first.accessed_fields
# end
# end
#
# Which allows you to quickly change your code to:
#
# class PostsController < ActionController::Base
# def index
# @posts = Post.select(:id, :title, :author_id, :updated_at)
# end
# end
def accessed_fields: () -> untyped
def attribute_method?: (untyped attr_name) -> untyped
def attributes_with_values: (untyped attribute_names) -> untyped
# Filters the primary keys and readonly attributes from the attribute names.
def attributes_for_update: (untyped attribute_names) -> untyped
# Filters out the primary keys, from the attribute names, when the primary
# key is to be generated (e.g. the id attribute has no value).
def attributes_for_create: (untyped attribute_names) -> untyped
def format_for_inspect: (untyped value) -> untyped
def readonly_attribute?: (untyped name) -> untyped
def pk_attribute?: (untyped name) -> untyped
end
end
module ActiveRecord
module AttributeMethods
module Read
extend ActiveSupport::Concern
module ClassMethods
def define_method_attribute: (untyped name) -> untyped
end
# Returns the value of the attribute identified by attr_name after
# it has been typecast (for example, "2004-12-12" in a date column is cast
# to a date object, like Date.new(2004, 12, 12)).
def read_attribute: (untyped attr_name) { () -> untyped } -> untyped
def _read_attribute: (untyped attr_name) { () -> untyped } -> untyped
end
end
end
module ActiveRecord
module AttributeMethods
module Serialization
extend ActiveSupport::Concern
class ColumnNotSerializableError < StandardError
def initialize: (untyped name, untyped `type`) -> untyped
end
module ClassMethods
# If you have an attribute that needs to be saved to the database as an
# object, and retrieved as the same object, then specify the name of that
# attribute using this method and it will be handled automatically. The
# serialization is done through YAML. If +class_name+ is specified, the
# serialized object must be of that class on assignment and retrieval.
# Otherwise SerializationTypeMismatch will be raised.
#
# Empty objects as {}, in the case of +Hash+, or [], in the case of
# +Array+, will always be persisted as null.
#
# Keep in mind that database adapters handle certain serialization tasks
# for you. For instance: +json+ and +jsonb+ types in PostgreSQL will be
# converted between JSON object/array syntax and Ruby +Hash+ or +Array+
# objects transparently. There is no need to use #serialize in this
# case.
#
# For more complex cases, such as conversion to or from your application
# domain objects, consider using the ActiveRecord::Attributes API.
#
# ==== Parameters
#
# * +attr_name+ - The field name that should be serialized.
# * +class_name_or_coder+ - Optional, a coder object, which responds to +.load+ and +.dump+
# or a class name that the object type should be equal to.
#
# ==== Example
#
# # Serialize a preferences attribute.
# class User < ActiveRecord::Base
# serialize :preferences
# end
#
# # Serialize preferences using JSON as coder.
# class User < ActiveRecord::Base
# serialize :preferences, JSON
# end
#
# # Serialize preferences as Hash using YAML coder.
# class User < ActiveRecord::Base
# serialize :preferences, Hash
# end
def serialize: (untyped attr_name, ?untyped class_name_or_coder) -> untyped
def type_incompatible_with_serialize?: (untyped `type`, untyped class_name) -> untyped
end
end
end
end
module ActiveRecord
module AttributeMethods
module TimeZoneConversion
# Note: It inherits unnamed class, but omitted
class TimeZoneConverter
# :nodoc:
def deserialize: (untyped value) -> untyped
def cast: (untyped value) -> (nil | untyped)
def convert_time_to_time_zone: (untyped value) -> (nil | untyped)
def set_time_zone_without_conversion: (untyped value) -> untyped
def map_avoiding_infinite_recursion: (untyped value) { (untyped) -> untyped } -> untyped
end
extend ActiveSupport::Concern
module ClassMethods
def inherited: (untyped subclass) -> untyped
def create_time_zone_conversion_attribute?: (untyped name, untyped cast_type) -> untyped
end
end
end
end
module ActiveRecord
module AttributeMethods
module Write
extend ActiveSupport::Concern
module ClassMethods
def define_method_attribute=: (untyped name) -> untyped
end
# Updates the attribute identified by attr_name with the
# specified +value+. Empty strings for Integer and Float columns are
# turned into +nil+.
def write_attribute: (untyped attr_name, untyped value) -> untyped
def _write_attribute: (untyped attr_name, untyped value) -> untyped
def write_attribute_without_type_cast: (untyped attr_name, untyped value) -> untyped
# Dispatch target for *= attribute methods.
def attribute=: (untyped attribute_name, untyped value) -> untyped
end
end
end
module ActiveRecord
# See ActiveRecord::Attributes::ClassMethods for documentation
module Attributes
extend ActiveSupport::Concern
module ClassMethods
# Defines an attribute with a type on this model. It will override the
# type of existing attributes if needed. This allows control over how
# values are converted to and from SQL when assigned to a model. It also
# changes the behavior of values passed to
# {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where]. This will let you use
# your domain objects across much of Active Record, without having to
# rely on implementation details or monkey patching.
#
# +name+ The name of the methods to define attribute methods for, and the
# column which this will persist to.
#
# +cast_type+ A symbol such as +:string+ or +:integer+, or a type object
# to be used for this attribute. See the examples below for more
# information about providing custom type objects.
#
# ==== Options
#
# The following options are accepted:
#
# +default+ The default value to use when no value is provided. If this option
# is not passed, the previous default value (if any) will be used.
# Otherwise, the default will be +nil+.
#
# +array+ (PostgreSQL only) specifies that the type should be an array (see the
# examples below).
#
# +range+ (PostgreSQL only) specifies that the type should be a range (see the
# examples below).
#
# When using a symbol for +cast_type+, extra options are forwarded to the
# constructor of the type object.
#
# ==== Examples
#
# The type detected by Active Record can be overridden.
#
# # db/schema.rb
# create_table :store_listings, force: true do |t|
# t.decimal :price_in_cents
# end
#
# # app/models/store_listing.rb
# class StoreListing < ActiveRecord::Base
# end
#
# store_listing = StoreListing.new(price_in_cents: '10.1')
#
# # before
# store_listing.price_in_cents # => BigDecimal(10.1)
#
# class StoreListing < ActiveRecord::Base
# attribute :price_in_cents, :integer
# end
#
# # after
# store_listing.price_in_cents # => 10
#
# A default can also be provided.
#
# # db/schema.rb
# create_table :store_listings, force: true do |t|
# t.string :my_string, default: "original default"
# end
#
# StoreListing.new.my_string # => "original default"
#
# # app/models/store_listing.rb
# class StoreListing < ActiveRecord::Base
# attribute :my_string, :string, default: "new default"
# end
#
# StoreListing.new.my_string # => "new default"
#
# class Product < ActiveRecord::Base
# attribute :my_default_proc, :datetime, default: -> { Time.now }
# end
#
# Product.new.my_default_proc # => 2015-05-30 11:04:48 -0600
# sleep 1
# Product.new.my_default_proc # => 2015-05-30 11:04:49 -0600
#
# \Attributes do not need to be backed by a database column.
#
# # app/models/my_model.rb
# class MyModel < ActiveRecord::Base
# attribute :my_string, :string
# attribute :my_int_array, :integer, array: true
# attribute :my_float_range, :float, range: true
# end
#
# model = MyModel.new(
# my_string: "string",
# my_int_array: ["1", "2", "3"],
# my_float_range: "[1,3.5]",
# )
# model.attributes
# # =>
# {
# my_string: "string",
# my_int_array: [1, 2, 3],
# my_float_range: 1.0..3.5
# }
#
# Passing options to the type constructor
#
# # app/models/my_model.rb
# class MyModel < ActiveRecord::Base
# attribute :small_int, :integer, limit: 2
# end
#
# MyModel.create(small_int: 65537)
# # => Error: 65537 is out of range for the limit of two bytes
#
# ==== Creating Custom Types
#
# Users may also define their own custom types, as long as they respond
# to the methods defined on the value type. The method +deserialize+ or
# +cast+ will be called on your type object, with raw input from the
# database or from your controllers. See ActiveModel::Type::Value for the
# expected API. It is recommended that your type objects inherit from an
# existing type, or from ActiveRecord::Type::Value
#
# class MoneyType < ActiveRecord::Type::Integer
# def cast(value)
# if !value.kind_of?(Numeric) && value.include?('$')
# price_in_dollars = value.gsub(/\$/, '').to_f
# super(price_in_dollars * 100)
# else
# super
# end
# end
# end
#
# # config/initializers/types.rb
# ActiveRecord::Type.register(:money, MoneyType)
#
# # app/models/store_listing.rb
# class StoreListing < ActiveRecord::Base
# attribute :price_in_cents, :money
# end
#
# store_listing = StoreListing.new(price_in_cents: '$10.00')
# store_listing.price_in_cents # => 1000
#
# For more details on creating custom types, see the documentation for
# ActiveModel::Type::Value. For more details on registering your types
# to be referenced by a symbol, see ActiveRecord::Type.register. You can
# also pass a type object directly, in place of a symbol.
#
# ==== \Querying
#
# When {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where] is called, it will
# use the type defined by the model class to convert the value to SQL,
# calling +serialize+ on your type object. For example:
#
# class Money < Struct.new(:amount, :currency)
# end
#
# class MoneyType < Type::Value
# def initialize(currency_converter:)
# @currency_converter = currency_converter
# end
#
# # value will be the result of +deserialize+ or
# # +cast+. Assumed to be an instance of +Money+ in
# # this case.
# def serialize(value)
# value_in_bitcoins = @currency_converter.convert_to_bitcoins(value)
# value_in_bitcoins.amount
# end
# end
#
# # config/initializers/types.rb
# ActiveRecord::Type.register(:money, MoneyType)
#
# # app/models/product.rb
# class Product < ActiveRecord::Base
# currency_converter = ConversionRatesFromTheInternet.new
# attribute :price_in_bitcoins, :money, currency_converter: currency_converter
# end
#
# Product.where(price_in_bitcoins: Money.new(5, "USD"))
# # => SELECT * FROM products WHERE price_in_bitcoins = 0.02230
#
# Product.where(price_in_bitcoins: Money.new(5, "GBP"))
# # => SELECT * FROM products WHERE price_in_bitcoins = 0.03412
#
# ==== Dirty Tracking
#
# The type of an attribute is given the opportunity to change how dirty
# tracking is performed. The methods +changed?+ and +changed_in_place?+
# will be called from ActiveModel::Dirty. See the documentation for those
# methods in ActiveModel::Type::Value for more details.
def attribute: (untyped name, ?untyped cast_type, **untyped options) -> untyped
# This is the low level API which sits beneath +attribute+. It only
# accepts type objects, and will do its work immediately instead of
# waiting for the schema to load. Automatic schema detection and
# ClassMethods#attribute both call this under the hood. While this method
# is provided so it can be used by plugin authors, application code
# should probably use ClassMethods#attribute.
#
# +name+ The name of the attribute being defined. Expected to be a +String+.
#
# +cast_type+ The type object to use for this attribute.
#
# +default+ The default value to use when no value is provided. If this option
# is not passed, the previous default value (if any) will be used.
# Otherwise, the default will be +nil+. A proc can also be passed, and
# will be called once each time a new value is needed.
#
# +user_provided_default+ Whether the default value should be cast using
# +cast+ or +deserialize+.
def define_attribute: (untyped name, untyped cast_type, ?user_provided_default: bool user_provided_default, ?default: untyped default) -> untyped
def load_schema!: () -> untyped
NO_DEFAULT_PROVIDED: untyped
def define_default_attribute: (untyped name, untyped value, untyped `type`, from_user: untyped from_user) -> untyped
end
end
end
module ActiveRecord
# = Active Record Autosave Association
#
# AutosaveAssociation is a module that takes care of automatically saving
# associated records when their parent is saved. In addition to saving, it
# also destroys any associated records that were marked for destruction.
# (See #mark_for_destruction and #marked_for_destruction?).
#
# Saving of the parent, its associations, and the destruction of marked
# associations, all happen inside a transaction. This should never leave the
# database in an inconsistent state.
#
# If validations for any of the associations fail, their error messages will
# be applied to the parent.
#
# Note that it also means that associations marked for destruction won't
# be destroyed directly. They will however still be marked for destruction.
#
# Note that autosave: false is not same as not declaring :autosave.
# When the :autosave option is not present then new association records are
# saved but the updated association records are not saved.
#
# == Validation
#
# Child records are validated unless :validate is +false+.
#
# == Callbacks
#
# Association with autosave option defines several callbacks on your
# model (before_save, after_create, after_update). Please note that
# callbacks are executed in the order they were defined in
# model. You should avoid modifying the association content, before
# autosave callbacks are executed. Placing your callbacks after
# associations is usually a good practice.
#
# === One-to-one Example
#
# class Post < ActiveRecord::Base
# has_one :author, autosave: true
# end
#
# Saving changes to the parent and its associated model can now be performed
# automatically _and_ atomically:
#
# post = Post.find(1)
# post.title # => "The current global position of migrating ducks"
# post.author.name # => "alloy"
#
# post.title = "On the migration of ducks"
# post.author.name = "Eloy Duran"
#
# post.save
# post.reload
# post.title # => "On the migration of ducks"
# post.author.name # => "Eloy Duran"
#
# Destroying an associated model, as part of the parent's save action, is as
# simple as marking it for destruction:
#
# post.author.mark_for_destruction
# post.author.marked_for_destruction? # => true
#
# Note that the model is _not_ yet removed from the database:
#
# id = post.author.id
# Author.find_by(id: id).nil? # => false
#
# post.save
# post.reload.author # => nil
#
# Now it _is_ removed from the database:
#
# Author.find_by(id: id).nil? # => true
#
# === One-to-many Example
#
# When :autosave is not declared new children are saved when their parent is saved:
#
# class Post < ActiveRecord::Base
# has_many :comments # :autosave option is not declared
# end
#
# post = Post.new(title: 'ruby rocks')
# post.comments.build(body: 'hello world')
# post.save # => saves both post and comment
#
# post = Post.create(title: 'ruby rocks')
# post.comments.build(body: 'hello world')
# post.save # => saves both post and comment
#
# post = Post.create(title: 'ruby rocks')
# post.comments.create(body: 'hello world')
# post.save # => saves both post and comment
#
# When :autosave is true all children are saved, no matter whether they
# are new records or not:
#
# class Post < ActiveRecord::Base
# has_many :comments, autosave: true
# end
#
# post = Post.create(title: 'ruby rocks')
# post.comments.create(body: 'hello world')
# post.comments[0].body = 'hi everyone'
# post.comments.build(body: "good morning.")
# post.title += "!"
# post.save # => saves both post and comments.
#
# Destroying one of the associated models as part of the parent's save action
# is as simple as marking it for destruction:
#
# post.comments # => [#, #
# post.comments[1].mark_for_destruction
# post.comments[1].marked_for_destruction? # => true
# post.comments.length # => 2
#
# Note that the model is _not_ yet removed from the database:
#
# id = post.comments.last.id
# Comment.find_by(id: id).nil? # => false
#
# post.save
# post.reload.comments.length # => 1
#
# Now it _is_ removed from the database:
#
# Comment.find_by(id: id).nil? # => true
module AutosaveAssociation
extend ActiveSupport::Concern
module AssociationBuilderExtension
# nodoc:
def self.build: (untyped model, untyped reflection) -> untyped
def self.valid_options: () -> ::Array[:autosave]
end
module ClassMethods
def define_non_cyclic_method: (untyped name) { () -> untyped } -> (nil | untyped)
# Adds validation and save callbacks for the association as specified by
# the +reflection+.
#
# For performance reasons, we don't check whether to validate at runtime.
# However the validation and callback methods are lazy and those methods
# get created when they are invoked for the very first time. However,
# this can change, for instance, when using nested attributes, which is
# called _after_ the association has been defined. Since we don't want
# the callbacks to get defined multiple times, there are guards that
# check if the save or validation methods have already been defined
# before actually defining them.
def add_autosave_association_callbacks: (untyped reflection) -> untyped
def define_autosave_validation_callbacks: (untyped reflection) -> untyped
end
# Reloads the attributes of the object as usual and clears marked_for_destruction flag.
def reload: (?untyped? options) -> untyped
# Marks this record to be destroyed as part of the parent's save transaction.
# This does _not_ actually destroy the record instantly, rather child record will be destroyed
# when parent.save is called.
#
# Only useful if the :autosave option on the parent is enabled for this associated model.
def mark_for_destruction: () -> untyped
# Returns whether or not this record will be destroyed as part of the parent's save transaction.
#
# Only useful if the :autosave option on the parent is enabled for this associated model.
def marked_for_destruction?: () -> untyped
# Records the association that is being destroyed and destroying this
# record in the process.
def destroyed_by_association=: (untyped reflection) -> untyped
# Returns the association for the parent being destroyed.
#
# Used to avoid updating the counter cache unnecessarily.
def destroyed_by_association: () -> untyped
# Returns whether or not this record has been changed in any way (including whether
# any of its nested autosave associations are likewise changed)
def changed_for_autosave?: () -> untyped
# Returns the record for an association collection that should be validated
# or saved. If +autosave+ is +false+ only new records will be returned,
# unless the parent is/was a new record itself.
def associated_records_to_validate_or_save: (untyped association, untyped new_record, untyped autosave) -> untyped
# go through nested autosave associations that are loaded in memory (without loading
# any new ones), and return true if is changed for autosave
def nested_records_changed_for_autosave?: () -> (::FalseClass | untyped)
# Validate the association if :validate or :autosave is
# turned on for the association.
def validate_single_association: (untyped reflection) -> untyped
# Validate the associated records if :validate or
# :autosave is turned on for the association specified by
# +reflection+.
def validate_collection_association: (untyped reflection) -> untyped
# Returns whether or not the association is valid and applies any errors to
# the parent, self, if it wasn't. Skips any :autosave
# enabled records if they're marked_for_destruction? or destroyed.
def association_valid?: (untyped reflection, untyped record, ?untyped? index) -> (::TrueClass | untyped)
def normalize_reflection_attribute: (untyped indexed_attribute, untyped reflection, untyped index, untyped attribute) -> untyped
# Is used as a before_save callback to check while saving a collection
# association whether or not the parent was a new record before saving.
def before_save_collection_association: () -> untyped
def after_save_collection_association: () -> untyped
# Saves any new associated records, or all loaded autosave associations if
# :autosave is enabled on the association.
#
# In addition, it destroys all children that were marked for destruction
# with #mark_for_destruction.
#
# This all happens inside a transaction, _if_ the Transactions module is included into
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
def save_collection_association: (untyped reflection) -> untyped
# Saves the associated record if it's new or :autosave is enabled
# on the association.
#
# In addition, it will destroy the association if it was marked for
# destruction with #mark_for_destruction.
#
# This all happens inside a transaction, _if_ the Transactions module is included into
# ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
def save_has_one_association: (untyped reflection) -> untyped
# If the record is new or it has changed, returns true.
def record_changed?: (untyped reflection, untyped record, untyped key) -> untyped
def association_foreign_key_changed?: (untyped reflection, untyped record, untyped key) -> (::FalseClass | untyped)
# Saves the associated record if it's new or :autosave is enabled.
#
# In addition, it will destroy the association if it was marked for destruction.
def save_belongs_to_association: (untyped reflection) -> (nil | untyped)
def custom_validation_context?: () -> untyped
def _ensure_no_duplicate_errors: () -> untyped
end
end
module ActiveRecord
# nodoc:
# = Active Record
#
# Active Record objects don't specify their attributes directly, but rather infer them from
# the table definition with which they're linked. Adding, removing, and changing attributes
# and their type is done directly in the database. Any change is instantly reflected in the
# Active Record objects. The mapping that binds a given Active Record class to a certain
# database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
#
# See the mapping rules in table_name and the full example in link:files/activerecord/README_rdoc.html for more insight.
#
# == Creation
#
# Active Records accept constructor parameters either in a hash or as a block. The hash
# method is especially useful when you're receiving the data from somewhere else, like an
# HTTP request. It works like this:
#
# user = User.new(name: "David", occupation: "Code Artist")
# user.name # => "David"
#
# You can also use block initialization:
#
# user = User.new do |u|
# u.name = "David"
# u.occupation = "Code Artist"
# end
#
# And of course you can just create a bare object and specify the attributes after the fact:
#
# user = User.new
# user.name = "David"
# user.occupation = "Code Artist"
#
# == Conditions
#
# Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
# The array form is to be used when the condition input is tainted and requires sanitization. The string form can
# be used for statements that don't involve tainted data. The hash form works much like the array form, except
# only equality and range is possible. Examples:
#
# class User < ActiveRecord::Base
# def self.authenticate_unsafely(user_name, password)
# where("user_name = '#{user_name}' AND password = '#{password}'").first
# end
#
# def self.authenticate_safely(user_name, password)
# where("user_name = ? AND password = ?", user_name, password).first
# end
#
# def self.authenticate_safely_simply(user_name, password)
# where(user_name: user_name, password: password).first
# end
# end
#
# The authenticate_unsafely method inserts the parameters directly into the query
# and is thus susceptible to SQL-injection attacks if the user_name and +password+
# parameters come directly from an HTTP request. The authenticate_safely and
# authenticate_safely_simply both will sanitize the user_name and +password+
# before inserting them in the query, which will ensure that an attacker can't escape the
# query and fake the login (or worse).
#
# When using multiple parameters in the conditions, it can easily become hard to read exactly
# what the fourth or fifth question mark is supposed to represent. In those cases, you can
# resort to named bind variables instead. That's done by replacing the question marks with
# symbols and supplying a hash with values for the matching symbol keys:
#
# Company.where(
# "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
# { id: 3, name: "37signals", division: "First", accounting_date: '2005-01-01' }
# ).first
#
# Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
# operator. For instance:
#
# Student.where(first_name: "Harvey", status: 1)
# Student.where(params[:student])
#
# A range may be used in the hash to use the SQL BETWEEN operator:
#
# Student.where(grade: 9..12)
#
# An array may be used in the hash to use the SQL IN operator:
#
# Student.where(grade: [9,11,12])
#
# When joining tables, nested hashes or keys written in the form 'table_name.column_name'
# can be used to qualify the table name of a particular condition. For instance:
#
# Student.joins(:schools).where(schools: { category: 'public' })
# Student.joins(:schools).where('schools.category' => 'public' )
#
# == Overwriting default accessors
#
# All column values are automatically available through basic accessors on the Active Record
# object, but sometimes you want to specialize this behavior. This can be done by overwriting
# the default accessors (using the same name as the attribute) and calling
# +super+ to actually change things.
#
# class Song < ActiveRecord::Base
# # Uses an integer of seconds to hold the length of the song
#
# def length=(minutes)
# super(minutes.to_i * 60)
# end
#
# def length
# super / 60
# end
# end
#
# == Attribute query methods
#
# In addition to the basic accessors, query methods are also automatically available on the Active Record object.
# Query methods allow you to test whether an attribute value is present.
# Additionally, when dealing with numeric values, a query method will return false if the value is zero.
#
# For example, an Active Record User with the name attribute has a name? method that you can call
# to determine whether the user has a name:
#
# user = User.new(name: "David")
# user.name? # => true
#
# anonymous = User.new(name: "")
# anonymous.name? # => false
#
# == Accessing attributes before they have been typecasted
#
# Sometimes you want to be able to read the raw attribute data without having the column-determined
# typecast run its course first. That can be done by using the _before_type_cast
# accessors that all attributes have. For example, if your Account model has a balance attribute,
# you can call account.balance_before_type_cast or account.id_before_type_cast.
#
# This is especially useful in validation situations where the user might supply a string for an
# integer field and you want to display the original string back in an error message. Accessing the
# attribute normally would typecast the string to 0, which isn't what you want.
#
# == Dynamic attribute-based finders
#
# Dynamic attribute-based finders are a mildly deprecated way of getting (and/or creating) objects
# by simple queries without turning to SQL. They work by appending the name of an attribute
# to find_by_ like Person.find_by_user_name.
# Instead of writing Person.find_by(user_name: user_name), you can use
# Person.find_by_user_name(user_name).
#
# It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
# ActiveRecord::RecordNotFound error if they do not return any records,
# like Person.find_by_last_name!.
#
# It's also possible to use multiple attributes in the same find_by_ by separating them with
# "_and_".
#
# Person.find_by(user_name: user_name, password: password)
# Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
#
# It's even possible to call these dynamic finder methods on relations and named scopes.
#
# Payment.order("created_on").find_by_amount(50)
#
# == Saving arrays, hashes, and other non-mappable objects in text columns
#
# Active Record can serialize any object in text columns using YAML. To do so, you must
# specify this with a call to the class method
# {serialize}[rdoc-ref:AttributeMethods::Serialization::ClassMethods#serialize].
# This makes it possible to store arrays, hashes, and other non-mappable objects without doing
# any additional work.
#
# class User < ActiveRecord::Base
# serialize :preferences
# end
#
# user = User.create(preferences: { "background" => "black", "display" => large })
# User.find(user.id).preferences # => { "background" => "black", "display" => large }
#
# You can also specify a class option as the second parameter that'll raise an exception
# if a serialized object is retrieved as a descendant of a class not in the hierarchy.
#
# class User < ActiveRecord::Base
# serialize :preferences, Hash
# end
#
# user = User.create(preferences: %w( one two three ))
# User.find(user.id).preferences # raises SerializationTypeMismatch
#
# When you specify a class option, the default value for that attribute will be a new
# instance of that class.
#
# class User < ActiveRecord::Base
# serialize :preferences, OpenStruct
# end
#
# user = User.new
# user.preferences.theme_color = "red"
#
#
# == Single table inheritance
#
# Active Record allows inheritance by storing the name of the class in a
# column that is named "type" by default. See ActiveRecord::Inheritance for
# more details.
#
# == Connection to multiple databases in different models
#
# Connections are usually created through
# {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] and retrieved
# by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this
# connection. But you can also set a class-specific connection. For example, if Course is an
# ActiveRecord::Base, but resides in a different database, you can just say Course.establish_connection
# and Course and all of its subclasses will use this connection instead.
#
# This feature is implemented by keeping a connection pool in ActiveRecord::Base that is
# a hash indexed by the class. If a connection is requested, the
# {ActiveRecord::Base.retrieve_connection}[rdoc-ref:ConnectionHandling#retrieve_connection] method
# will go up the class-hierarchy until a connection is found in the connection pool.
#
# == Exceptions
#
# * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
# * AdapterNotSpecified - The configuration hash used in
# {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection]
# didn't include an :adapter key.
# * AdapterNotFound - The :adapter key used in
# {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection]
# specified a non-existent adapter
# (or a bad spelling of an existing one).
# * AssociationTypeMismatch - The object assigned to the association wasn't of the type
# specified in the association definition.
# * AttributeAssignmentError - An error occurred while doing a mass assignment through the
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
# You can inspect the +attribute+ property of the exception object to determine which attribute
# triggered the error.
# * ConnectionNotEstablished - No connection has been established.
# Use {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] before querying.
# * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
# The +errors+ property of this exception contains an array of
# AttributeAssignmentError
# objects that should be inspected to determine which attributes triggered the errors.
# * RecordInvalid - raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
# {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]
# when the record is invalid.
# * RecordNotFound - No record responded to the {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] method.
# Either the row with the given ID doesn't exist or the row didn't meet the additional restrictions.
# Some {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] calls do not raise this exception to signal
# nothing was found, please check its documentation for further details.
# * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
# * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
#
# *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
# So it's possible to assign a logger to the class through Base.logger= which will then be used by all
# instances in the current object space.
class Base
extend ActiveModel::Naming
extend ActiveSupport::Benchmarkable
extend ActiveSupport::DescendantsTracker
extend ConnectionHandling
extend QueryCache::ClassMethods
extend Querying
extend Translation
extend DynamicMatchers
extend Explain
extend Enum
extend Delegation::DelegateCache
extend Aggregations::ClassMethods
include Core
extend ::ActiveRecord::Core::ClassMethods
include Persistence
extend ::ActiveRecord::Persistence::ClassMethods
include ReadonlyAttributes
extend ::ActiveRecord::ReadonlyAttributes::ClassMethods
include ModelSchema
extend ::ActiveRecord::ModelSchema::ClassMethods
include Inheritance
extend ::ActiveRecord::Inheritance::ClassMethods
include Scoping
extend ::ActiveRecord::Scoping::ClassMethods
include Sanitization
extend ::ActiveRecord::Sanitization::ClassMethods
include AttributeAssignment
include ActiveModel::Conversion
extend ::ActiveModel::Conversion::ClassMethods
include Integration
extend ::ActiveRecord::Integration::ClassMethods
include Validations
extend ::ActiveRecord::Validations::ClassMethods
include CounterCache
extend ::ActiveRecord::CounterCache::ClassMethods
include Attributes
extend ::ActiveRecord::Attributes::ClassMethods
include AttributeDecorators
extend ::ActiveRecord::AttributeDecorators::ClassMethods
include Locking::Optimistic
extend ::ActiveRecord::Locking::Optimistic::ClassMethods
include Locking::Pessimistic
include DefineCallbacks
extend ::ActiveRecord::DefineCallbacks::ClassMethods
include AttributeMethods
extend ::ActiveRecord::AttributeMethods::ClassMethods
include Callbacks
include Timestamp
extend ::ActiveRecord::Timestamp::ClassMethods
include Associations
extend ::ActiveRecord::Associations::ClassMethods
include ActiveModel::SecurePassword
extend ::ActiveModel::SecurePassword::ClassMethods
include AutosaveAssociation
extend ::ActiveRecord::AutosaveAssociation::ClassMethods
include NestedAttributes
extend ::ActiveRecord::NestedAttributes::ClassMethods
include Transactions
extend ::ActiveRecord::Transactions::ClassMethods
include TouchLater
include NoTouching
extend ::ActiveRecord::NoTouching::ClassMethods
include Reflection
extend ::ActiveRecord::Reflection::ClassMethods
include Serialization
include Store
extend ::ActiveRecord::Store::ClassMethods
include SecureToken
extend ::ActiveRecord::SecureToken::ClassMethods
include Suppressor
extend ::ActiveRecord::Suppressor::ClassMethods
end
end
module ActiveRecord
# = Active Record \Callbacks
#
# \Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
# before or after an alteration of the object state. This can be used to make sure that associated and
# dependent objects are deleted when {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] is called (by overwriting +before_destroy+) or
# to massage attributes before they're validated (by overwriting +before_validation+).
# As an example of the callbacks initiated, consider the {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] call for a new record:
#
# * (-) save
# * (-) valid
# * (1) before_validation
# * (-) validate
# * (2) after_validation
# * (3) before_save
# * (4) before_create
# * (-) create
# * (5) after_create
# * (6) after_save
# * (7) after_commit
#
# Also, an after_rollback callback can be configured to be triggered whenever a rollback is issued.
# Check out ActiveRecord::Transactions for more details about after_commit and
# after_rollback.
#
# Additionally, an after_touch callback is triggered whenever an
# object is touched.
#
# Lastly an after_find and after_initialize callback is triggered for each object that
# is found and instantiated by a finder, with after_initialize being triggered after new objects
# are instantiated as well.
#
# There are nineteen callbacks in total, which give you immense power to react and prepare for each state in the
# Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar,
# except that each _create callback is replaced by the corresponding _update callback.
#
# Examples:
# class CreditCard < ActiveRecord::Base
# # Strip everything but digits, so the user can specify "555 234 34" or
# # "5552-3434" and both will mean "55523434"
# before_validation(on: :create) do
# self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
# end
# end
#
# class Subscription < ActiveRecord::Base
# before_create :record_signup
#
# private
# def record_signup
# self.signed_up_on = Date.today
# end
# end
#
# class Firm < ActiveRecord::Base
# # Disables access to the system, for associated clients and people when the firm is destroyed
# before_destroy { |record| Person.where(firm_id: record.id).update_all(access: 'disabled') }
# before_destroy { |record| Client.where(client_of: record.id).update_all(access: 'disabled') }
# end
#
# == Inheritable callback queues
#
# Besides the overwritable callback methods, it's also possible to register callbacks through the
# use of the callback macros. Their main advantage is that the macros add behavior into a callback
# queue that is kept intact down through an inheritance hierarchy.
#
# class Topic < ActiveRecord::Base
# before_destroy :destroy_author
# end
#
# class Reply < Topic
# before_destroy :destroy_readers
# end
#
# Now, when Topic#destroy is run only +destroy_author+ is called. When Reply#destroy is
# run, both +destroy_author+ and +destroy_readers+ are called.
#
# *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
# callbacks before specifying the associations. Otherwise, you might trigger the loading of a
# child before the parent has registered the callbacks and they won't be inherited.
#
# == Types of callbacks
#
# There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
# inline methods (using a proc). Method references and callback objects
# are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
# creating mix-ins).
#
# The method reference callbacks work by specifying a protected or private method available in the object, like this:
#
# class Topic < ActiveRecord::Base
# before_destroy :delete_parents
#
# private
# def delete_parents
# self.class.delete_by(parent_id: id)
# end
# end
#
# The callback objects have methods named after the callback called with the record as the only parameter, such as:
#
# class BankAccount < ActiveRecord::Base
# before_save EncryptionWrapper.new
# after_save EncryptionWrapper.new
# after_initialize EncryptionWrapper.new
# end
#
# class EncryptionWrapper
# def before_save(record)
# record.credit_card_number = encrypt(record.credit_card_number)
# end
#
# def after_save(record)
# record.credit_card_number = decrypt(record.credit_card_number)
# end
#
# alias_method :after_initialize, :after_save
#
# private
# def encrypt(value)
# # Secrecy is committed
# end
#
# def decrypt(value)
# # Secrecy is unveiled
# end
# end
#
# So you specify the object you want to be messaged on a given callback. When that callback is triggered, the object has
# a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other
# initialization data such as the name of the attribute to work with:
#
# class BankAccount < ActiveRecord::Base
# before_save EncryptionWrapper.new("credit_card_number")
# after_save EncryptionWrapper.new("credit_card_number")
# after_initialize EncryptionWrapper.new("credit_card_number")
# end
#
# class EncryptionWrapper
# def initialize(attribute)
# @attribute = attribute
# end
#
# def before_save(record)
# record.send("#{@attribute}=", encrypt(record.send("#{@attribute}")))
# end
#
# def after_save(record)
# record.send("#{@attribute}=", decrypt(record.send("#{@attribute}")))
# end
#
# alias_method :after_initialize, :after_save
#
# private
# def encrypt(value)
# # Secrecy is committed
# end
#
# def decrypt(value)
# # Secrecy is unveiled
# end
# end
#
# == before_validation* returning statements
#
# If the +before_validation+ callback throws +:abort+, the process will be
# aborted and {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] will return +false+.
# If {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] is called it will raise an ActiveRecord::RecordInvalid exception.
# Nothing will be appended to the errors object.
#
# == Canceling callbacks
#
# If a before_* callback throws +:abort+, all the later callbacks and
# the associated action are cancelled.
# Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
# methods on the model, which are called last.
#
# == Ordering callbacks
#
# Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
# callback (+log_children+ in this case) should be executed before the children get destroyed by the
# dependent: :destroy option.
#
# Let's look at the code below:
#
# class Topic < ActiveRecord::Base
# has_many :children, dependent: :destroy
#
# before_destroy :log_children
#
# private
# def log_children
# # Child processing
# end
# end
#
# In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available
# because the {ActiveRecord::Base#destroy}[rdoc-ref:Persistence#destroy] callback gets executed first.
# You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
#
# class Topic < ActiveRecord::Base
# has_many :children, dependent: :destroy
#
# before_destroy :log_children, prepend: true
#
# private
# def log_children
# # Child processing
# end
# end
#
# This way, the +before_destroy+ gets executed before the dependent: :destroy is called, and the data is still available.
#
# Also, there are cases when you want several callbacks of the same type to
# be executed in order.
#
# For example:
#
# class Topic < ActiveRecord::Base
# has_many :children
#
# after_save :log_children
# after_save :do_something_else
#
# private
#
# def log_children
# # Child processing
# end
#
# def do_something_else
# # Something else
# end
# end
#
# In this case the +log_children+ gets executed before +do_something_else+.
# The same applies to all non-transactional callbacks.
#
# In case there are multiple transactional callbacks as seen below, the order
# is reversed.
#
# For example:
#
# class Topic < ActiveRecord::Base
# has_many :children
#
# after_commit :log_children
# after_commit :do_something_else
#
# private
#
# def log_children
# # Child processing
# end
#
# def do_something_else
# # Something else
# end
# end
#
# In this case the +do_something_else+ gets executed before +log_children+.
#
# == \Transactions
#
# The entire callback chain of a {#save}[rdoc-ref:Persistence#save], {#save!}[rdoc-ref:Persistence#save!],
# or {#destroy}[rdoc-ref:Persistence#destroy] call runs within a transaction. That includes after_* hooks.
# If everything goes fine a COMMIT is executed once the chain has been completed.
#
# If a before_* callback cancels the action a ROLLBACK is issued. You
# can also trigger a ROLLBACK raising an exception in any of the callbacks,
# including after_* hooks. Note, however, that in that case the client
# needs to be aware of it because an ordinary {#save}[rdoc-ref:Persistence#save] will raise such exception
# instead of quietly returning +false+.
#
# == Debugging callbacks
#
# The callback chain is accessible via the _*_callbacks method on an object. Active Model \Callbacks support
# :before, :after and :around as values for the kind property. The kind property
# defines what part of the chain the callback runs in.
#
# To find all callbacks in the before_save callback chain:
#
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
#
# Returns an array of callback objects that form the before_save chain.
#
# To further check if the before_save chain contains a proc defined as rest_when_dead use the filter property of the callback object:
#
# Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
#
# Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
#
module Callbacks
extend ActiveSupport::Concern
CALLBACKS: ::Array[untyped]
def destroy: () -> untyped
def touch: () -> untyped
def increment!: (untyped attribute, ?::Integer by, ?touch: untyped? touch) -> untyped
def create_or_update: () -> untyped
def _create_record: () -> untyped
def _update_record: () -> untyped
end
end
module ActiveRecord
module Coders
class JSON
# :nodoc:
# :nodoc:
def self.dump: (untyped obj) -> untyped
def self.load: (untyped json) -> untyped
end
end
end
module ActiveRecord
module Coders
class YAMLColumn
# :nodoc:
# :nodoc:
attr_accessor object_class: untyped
def initialize: (untyped attr_name, ?untyped object_class) -> untyped
def dump: (untyped obj) -> (nil | untyped)
def load: (untyped yaml) -> untyped
def assert_valid_value: (untyped obj, action: untyped action) -> untyped
def check_arity_of_constructor: () -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
# :nodoc:
extend ActiveSupport::Autoload
# Active Record supports multiple database systems. AbstractAdapter and
# related classes form the abstraction layer which makes this possible.
# An AbstractAdapter represents a connection to a database, and provides an
# abstract interface for database-specific functionality such as establishing
# a connection, escaping values, building the right SQL fragments for +:offset+
# and +:limit+ options, etc.
#
# All the concrete database adapters follow the interface laid down in this class.
# {ActiveRecord::Base.connection}[rdoc-ref:ConnectionHandling#connection] returns an AbstractAdapter object, which
# you can use.
#
# Most of the methods in the adapter are useful during migrations. Most
# notably, the instance methods provided by SchemaStatements are very useful.
class AbstractAdapter
ADAPTER_NAME: ::String
include ActiveSupport::Callbacks
extend ::ActiveSupport::Callbacks::ClassMethods
include Quoting
include DatabaseStatements
include SchemaStatements
include DatabaseLimits
include QueryCache
include Savepoints
SIMPLE_INT: untyped
COMMENT_REGEX: untyped
attr_accessor pool: untyped
attr_reader visitor: untyped
attr_reader owner: untyped
attr_reader logger: untyped
attr_reader lock: untyped
def self.type_cast_config_to_integer: (untyped config) -> untyped
def self.type_cast_config_to_boolean: (untyped config) -> untyped
def self.build_read_query_regexp: (*untyped parts) -> ::Regexp
def self.quoted_column_names: () -> untyped
def self.quoted_table_names: () -> untyped
def initialize: (untyped connection, ?untyped? logger, ?::Hash[untyped, untyped] config) -> untyped
def replica?: () -> untyped
# Determines whether writes are currently being prevents.
#
# Returns true if the connection is a replica, or if +prevent_writes+
# is set to true.
def preventing_writes?: () -> untyped
def migrations_paths: () -> untyped
def migration_context: () -> MigrationContext
def schema_migration: () -> untyped
def prepared_statements: () -> untyped
def prepared_statements_disabled_cache: () -> untyped
class Version
include Comparable
attr_reader full_version_string: untyped
def initialize: (untyped version_string, ?untyped? full_version_string) -> untyped
def <=>: (untyped version_string) -> untyped
def to_s: () -> untyped
end
def valid_type?: (untyped `type`) -> untyped
# this method must only be called while holding connection pool's mutex
def lease: () -> untyped
def schema_cache: () -> untyped
def schema_cache=: (untyped cache) -> untyped
# this method must only be called while holding connection pool's mutex
def expire: () -> untyped
def steal!: () -> untyped
def seconds_idle: () -> (0 | untyped)
def unprepared_statement: () { () -> untyped } -> untyped
# Returns the human-readable name of the adapter. Use mixed case - one
# can always use downcase if needed.
def adapter_name: () -> untyped
# Does the database for this adapter exist?
def self.database_exists?: (untyped config) -> untyped
# Does this adapter support DDL rollbacks in transactions? That is, would
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
def supports_ddl_transactions?: () -> ::FalseClass
def supports_bulk_alter?: () -> ::FalseClass
# Does this adapter support savepoints?
def supports_savepoints?: () -> ::FalseClass
# Does this adapter support application-enforced advisory locking?
def supports_advisory_locks?: () -> ::FalseClass
# Should primary key values be selected from their corresponding
# sequence before the insert statement? If true, next_sequence_value
# is called before each insert to set the record's primary key.
def prefetch_primary_key?: (?untyped? table_name) -> ::FalseClass
def supports_partitioned_indexes?: () -> ::FalseClass
# Does this adapter support index sort order?
def supports_index_sort_order?: () -> ::FalseClass
# Does this adapter support partial indices?
def supports_partial_index?: () -> ::FalseClass
# Does this adapter support expression indices?
def supports_expression_index?: () -> ::FalseClass
# Does this adapter support explain?
def supports_explain?: () -> ::FalseClass
# Does this adapter support setting the isolation level for a transaction?
def supports_transaction_isolation?: () -> ::FalseClass
# Does this adapter support database extensions?
def supports_extensions?: () -> ::FalseClass
# Does this adapter support creating indexes in the same statement as
# creating the table?
def supports_indexes_in_create?: () -> ::FalseClass
# Does this adapter support creating foreign key constraints?
def supports_foreign_keys?: () -> ::FalseClass
# Does this adapter support creating invalid constraints?
def supports_validate_constraints?: () -> ::FalseClass
# Does this adapter support creating foreign key constraints
# in the same statement as creating the table?
def supports_foreign_keys_in_create?: () -> untyped
# Does this adapter support views?
def supports_views?: () -> ::FalseClass
# Does this adapter support materialized views?
def supports_materialized_views?: () -> ::FalseClass
# Does this adapter support datetime with precision?
def supports_datetime_with_precision?: () -> ::FalseClass
# Does this adapter support json data type?
def supports_json?: () -> ::FalseClass
# Does this adapter support metadata comments on database objects (tables, columns, indexes)?
def supports_comments?: () -> ::FalseClass
# Can comments for tables, columns, and indexes be specified in create/alter table statements?
def supports_comments_in_create?: () -> ::FalseClass
# Does this adapter support multi-value insert?
def supports_multi_insert?: () -> ::TrueClass
# Does this adapter support virtual columns?
def supports_virtual_columns?: () -> ::FalseClass
# Does this adapter support foreign/external tables?
def supports_foreign_tables?: () -> ::FalseClass
# Does this adapter support optimizer hints?
def supports_optimizer_hints?: () -> ::FalseClass
def supports_common_table_expressions?: () -> ::FalseClass
def supports_lazy_transactions?: () -> ::FalseClass
def supports_insert_returning?: () -> ::FalseClass
def supports_insert_on_duplicate_skip?: () -> ::FalseClass
def supports_insert_on_duplicate_update?: () -> ::FalseClass
def supports_insert_conflict_target?: () -> ::FalseClass
# This is meant to be implemented by the adapters that support extensions
def disable_extension: (untyped name) -> nil
# This is meant to be implemented by the adapters that support extensions
def enable_extension: (untyped name) -> nil
def advisory_locks_enabled?: () -> untyped
def get_advisory_lock: (untyped lock_id) -> nil
def release_advisory_lock: (untyped lock_id) -> nil
# A list of extensions, to be filled in by adapters that support them.
def extensions: () -> ::Array[untyped]
# A list of index algorithms, to be filled by adapters that support them.
def index_algorithms: () -> ::Hash[untyped, untyped]
# Override to turn off referential integrity while executing &block.
def disable_referential_integrity: () { () -> untyped } -> untyped
# Checks whether the connection to the database is still active. This includes
# checking whether the database is actually capable of responding, i.e. whether
# the connection isn't stale.
def active?: () -> nil
# Disconnects from the database if already connected, and establishes a
# new connection with the database. Implementors should call super if they
# override the default implementation.
def reconnect!: () -> untyped
# Disconnects from the database if already connected. Otherwise, this
# method does nothing.
def disconnect!: () -> untyped
# Immediately forget this connection ever existed. Unlike disconnect!,
# this will not communicate with the server.
#
# After calling this method, the behavior of all other methods becomes
# undefined. This is called internally just before a forked process gets
# rid of a connection that belonged to its parent.
def discard!: () -> untyped
# Reset the state of this connection, directing the DBMS to clear
# transactions and other connection-related server-side state. Usually a
# database-dependent operation.
#
# The default implementation does nothing; the implementation should be
# overridden by concrete adapters.
def reset!: () -> nil
# Clear any caching the database adapter may be doing.
def clear_cache!: () -> untyped
# Returns true if its required to reload the connection between requests for development mode.
def requires_reloading?: () -> ::FalseClass
# Checks whether the connection to the database is still active (i.e. not stale).
# This is done under the hood by calling #active?. If the connection
# is no longer active, then this method will reconnect to the database.
def verify!: () -> untyped
# Provides access to the underlying database driver for this adapter. For
# example, this method returns a Mysql2::Client object in case of Mysql2Adapter,
# and a PG::Connection object in case of PostgreSQLAdapter.
#
# This is useful for when you need to call a proprietary method such as
# PostgreSQL's lo_* methods.
def raw_connection: () -> untyped
def default_uniqueness_comparison: (untyped attribute, untyped value, untyped klass) -> untyped
def case_sensitive_comparison: (untyped attribute, untyped value) -> untyped
def case_insensitive_comparison: (untyped attribute, untyped value) -> untyped
def can_perform_case_insensitive_comparison_for?: (untyped column) -> ::TrueClass
# Check the connection back in to the connection pool
def close: () -> untyped
def column_name_for_operation: (untyped operation, untyped node) -> untyped
def default_index_type?: (untyped index) -> untyped
def build_insert_sql: (untyped insert) -> ::String
def get_database_version: () -> nil
def database_version: () -> untyped
def check_version: () -> nil
def type_map: () -> untyped
def initialize_type_map: (?untyped m) -> untyped
def reload_type_map: () -> untyped
def register_class_with_limit: (untyped mapping, untyped key, untyped klass) -> untyped
def register_class_with_precision: (untyped mapping, untyped key, untyped klass) -> untyped
def extract_scale: (untyped sql_type) -> untyped
def extract_precision: (untyped sql_type) -> untyped
def extract_limit: (untyped sql_type) -> untyped
def translate_exception_class: (untyped e, untyped sql, untyped binds) -> untyped
def log: (untyped sql, ?::String name, ?untyped binds, ?untyped type_casted_binds, ?untyped? statement_name) { () -> untyped } -> untyped
def translate_exception: (untyped exception, binds: untyped binds, sql: untyped sql, message: untyped message) -> untyped
def without_prepared_statement?: (untyped binds) -> untyped
def column_for: (untyped table_name, untyped column_name) -> untyped
def column_for_attribute: (untyped attribute) -> untyped
def collector: () -> untyped
def arel_visitor: () -> Arel::Visitors::ToSql
def build_statement_pool: () -> nil
end
end
end
module ActiveRecord
# Raised when a connection could not be obtained within the connection
# acquisition timeout period: because max connections in pool
# are in use.
class ConnectionTimeoutError < ConnectionNotEstablished
end
# Raised when a pool was unable to get ahold of all its connections
# to perform a "group" action such as
# {ActiveRecord::Base.connection_pool.disconnect!}[rdoc-ref:ConnectionAdapters::ConnectionPool#disconnect!]
# or {ActiveRecord::Base.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
class ExclusiveConnectionTimeoutError < ConnectionTimeoutError
end
module ConnectionAdapters
module AbstractPool
# :nodoc:
def get_schema_cache: (untyped connection) -> untyped
def set_schema_cache: (untyped cache) -> untyped
end
class NullPool
# :nodoc:
include ConnectionAdapters::AbstractPool
def initialize: () -> untyped
end
# Connection pool base class for managing Active Record database
# connections.
#
# == Introduction
#
# A connection pool synchronizes thread access to a limited number of
# database connections. The basic idea is that each thread checks out a
# database connection from the pool, uses that connection, and checks the
# connection back in. ConnectionPool is completely thread-safe, and will
# ensure that a connection cannot be used by two threads at the same time,
# as long as ConnectionPool's contract is correctly followed. It will also
# handle cases in which there are more threads than connections: if all
# connections have been checked out, and a thread tries to checkout a
# connection anyway, then ConnectionPool will wait until some other thread
# has checked in a connection.
#
# == Obtaining (checking out) a connection
#
# Connections can be obtained and used from a connection pool in several
# ways:
#
# 1. Simply use {ActiveRecord::Base.connection}[rdoc-ref:ConnectionHandling.connection]
# as with Active Record 2.1 and
# earlier (pre-connection-pooling). Eventually, when you're done with
# the connection(s) and wish it to be returned to the pool, you call
# {ActiveRecord::Base.clear_active_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_active_connections!].
# This will be the default behavior for Active Record when used in conjunction with
# Action Pack's request handling cycle.
# 2. Manually check out a connection from the pool with
# {ActiveRecord::Base.connection_pool.checkout}[rdoc-ref:#checkout]. You are responsible for
# returning this connection to the pool when finished by calling
# {ActiveRecord::Base.connection_pool.checkin(connection)}[rdoc-ref:#checkin].
# 3. Use {ActiveRecord::Base.connection_pool.with_connection(&block)}[rdoc-ref:#with_connection], which
# obtains a connection, yields it as the sole argument to the block,
# and returns it to the pool after the block completes.
#
# Connections in the pool are actually AbstractAdapter objects (or objects
# compatible with AbstractAdapter's interface).
#
# == Options
#
# There are several connection-pooling-related options that you can add to
# your database connection configuration:
#
# * +pool+: maximum number of connections the pool may manage (default 5).
# * +idle_timeout+: number of seconds that a connection will be kept
# unused in the pool before it is automatically disconnected (default
# 300 seconds). Set this to zero to keep connections forever.
# * +checkout_timeout+: number of seconds to wait for a connection to
# become available before giving up and raising a timeout error (default
# 5 seconds).
#
# -
# Synchronization policy:
# * all public methods can be called outside +synchronize+
# * access to these instance variables needs to be in +synchronize+:
# * @connections
# * @now_connecting
# * private methods that require being called in a +synchronize+ blocks
# are now explicitly documented
class ConnectionPool
# Threadsafe, fair, LIFO queue. Meant to be used by ConnectionPool
# with which it shares a Monitor.
class Queue
def initialize: (?untyped lock) -> untyped
# Test if any threads are currently waiting on the queue.
def any_waiting?: () -> untyped
# Returns the number of threads currently waiting on this
# queue.
def num_waiting: () -> untyped
# Add +element+ to the queue. Never blocks.
def add: (untyped element) -> untyped
# If +element+ is in the queue, remove and return it, or +nil+.
def delete: (untyped element) -> untyped
# Remove all elements from the queue.
def clear: () -> untyped
# Remove the head of the queue.
#
# If +timeout+ is not given, remove and return the head the
# queue if the number of available elements is strictly
# greater than the number of threads currently waiting (that
# is, don't jump ahead in line). Otherwise, return +nil+.
#
# If +timeout+ is given, block if there is no element
# available, waiting up to +timeout+ seconds for an element to
# become available.
#
# Raises:
# - ActiveRecord::ConnectionTimeoutError if +timeout+ is given and no element
# becomes available within +timeout+ seconds,
def poll: (?untyped? timeout) -> untyped
def internal_poll: (untyped timeout) -> untyped
def synchronize: () { () -> untyped } -> untyped
# Test if the queue currently contains any elements.
def any?: () -> untyped
# A thread can remove an element from the queue without
# waiting if and only if the number of currently available
# connections is strictly greater than the number of waiting
# threads.
def can_remove_no_wait?: () -> untyped
# Removes and returns the head of the queue if possible, or +nil+.
def remove: () -> untyped
# Remove and return the head the queue if the number of
# available elements is strictly greater than the number of
# threads currently waiting. Otherwise, return +nil+.
def no_wait_poll: () -> untyped
# Waits on the queue up to +timeout+ seconds, then removes and
# returns the head of the queue.
def wait_poll: (untyped timeout) -> untyped
end
module BiasableQueue
class BiasedConditionVariable
# Adds the ability to turn a basic fair FIFO queue into one
# biased to some thread.
# :nodoc:
# :nodoc:
# semantics of condition variables guarantee that +broadcast+, +broadcast_on_biased+,
# +signal+ and +wait+ methods are only called while holding a lock
def initialize: (untyped lock, untyped other_cond, untyped preferred_thread) -> untyped
def broadcast: () -> untyped
def broadcast_on_biased: () -> untyped
def signal: () -> untyped
def wait: (untyped timeout) -> untyped
end
def with_a_bias_for: (untyped thread) { () -> untyped } -> untyped
end
class ConnectionLeasingQueue < Queue
# Connections must be leased while holding the main pool mutex. This is
# an internal subclass that also +.leases+ returned connections while
# still in queue's critical section (queue synchronizes with the same
# @lock as the main pool) so that a returned connection is already
# leased and there is no need to re-enter synchronized block.
# :nodoc:
include BiasableQueue
def internal_poll: (untyped timeout) -> untyped
end
# Every +frequency+ seconds, the reaper will call +reap+ and +flush+ on
# +pool+. A reaper instantiated with a zero frequency will never reap
# the connection pool.
#
# Configure the frequency by setting +reaping_frequency+ in your database
# yaml file (default 60 seconds).
class Reaper
attr_reader pool: untyped
attr_reader frequency: untyped
def initialize: (untyped pool, untyped frequency) -> untyped
def self.register_pool: (untyped pool, untyped frequency) -> untyped
def self.spawn_thread: (untyped frequency) -> untyped
def run: () -> (nil | untyped)
end
include MonitorMixin
include QueryCache::ConnectionPoolConfiguration
include ConnectionAdapters::AbstractPool
attr_accessor automatic_reconnect: untyped
attr_accessor checkout_timeout: untyped
attr_accessor schema_cache: untyped
attr_reader spec: untyped
attr_reader size: untyped
attr_reader reaper: untyped
# Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
# object which describes database connection information (e.g. adapter,
# host name, username, password, etc), as well as the maximum size for
# this ConnectionPool.
#
# The default ConnectionPool maximum size is 5.
def initialize: (untyped spec) -> untyped
def lock_thread=: (untyped lock_thread) -> untyped
# Retrieve the connection associated with the current thread, or call
# #checkout to obtain one if necessary.
#
# #connection can be called any number of times; the connection is
# held in a cache keyed by a thread.
def connection: () -> untyped
# Returns true if there is an open connection being used for the current thread.
#
# This method only works for connections that have been obtained through
# #connection or #with_connection methods. Connections obtained through
# #checkout will not be detected by #active_connection?
def active_connection?: () -> untyped
# Signal that the thread is finished with the current connection.
# #release_connection releases the connection-thread association
# and returns the connection to the pool.
#
# This method only works for connections that have been obtained through
# #connection or #with_connection methods, connections obtained through
# #checkout will not be automatically released.
def release_connection: (?untyped owner_thread) -> untyped
# If a connection obtained through #connection or #with_connection methods
# already exists yield it to the block. If no such connection
# exists checkout a connection, yield it to the block, and checkin the
# connection when finished.
def with_connection: () { (untyped) -> untyped } -> untyped
# Returns true if a connection has already been opened.
def connected?: () -> untyped
# Returns an array containing the connections currently in the pool.
# Access to the array does not require synchronization on the pool because
# the array is newly created and not retained by the pool.
#
# However; this method bypasses the ConnectionPool's thread-safe connection
# access pattern. A returned connection may be owned by another thread,
# unowned, or by happen-stance owned by the calling thread.
#
# Calling methods on a connection without ownership is subject to the
# thread-safety guarantees of the underlying method. Many of the methods
# on connection adapter classes are inherently multi-thread unsafe.
def connections: () -> untyped
# Disconnects all connections in the pool, and clears the pool.
#
# Raises:
# - ActiveRecord::ExclusiveConnectionTimeoutError if unable to gain ownership of all
# connections in the pool within a timeout interval (default duration is
# spec.config[:checkout_timeout] * 2 seconds).
def disconnect: (?bool raise_on_acquisition_timeout) -> untyped
# Disconnects all connections in the pool, and clears the pool.
#
# The pool first tries to gain ownership of all connections. If unable to
# do so within a timeout interval (default duration is
# spec.config[:checkout_timeout] * 2 seconds), then the pool is forcefully
# disconnected without any regard for other connection owning threads.
def disconnect!: () -> untyped
def discard!: () -> untyped
# Clears the cache which maps classes and re-connects connections that
# require reloading.
#
# Raises:
# - ActiveRecord::ExclusiveConnectionTimeoutError if unable to gain ownership of all
# connections in the pool within a timeout interval (default duration is
# spec.config[:checkout_timeout] * 2 seconds).
def clear_reloadable_connections: (?bool raise_on_acquisition_timeout) -> untyped
# Clears the cache which maps classes and re-connects connections that
# require reloading.
#
# The pool first tries to gain ownership of all connections. If unable to
# do so within a timeout interval (default duration is
# spec.config[:checkout_timeout] * 2 seconds), then the pool forcefully
# clears the cache and reloads connections without any regard for other
# connection owning threads.
def clear_reloadable_connections!: () -> untyped
# Check-out a database connection from the pool, indicating that you want
# to use it. You should call #checkin when you no longer need this.
#
# This is done by either returning and leasing existing connection, or by
# creating a new connection and leasing it.
#
# If all connections are leased and the pool is at capacity (meaning the
# number of currently leased connections is greater than or equal to the
# size limit set), an ActiveRecord::ConnectionTimeoutError exception will be raised.
#
# Returns: an AbstractAdapter object.
#
# Raises:
# - ActiveRecord::ConnectionTimeoutError no connection can be obtained from the pool.
def checkout: (?untyped checkout_timeout) -> untyped
# Check-in a database connection back into the pool, indicating that you
# no longer need this connection.
#
# +conn+: an AbstractAdapter object, which was obtained by earlier by
# calling #checkout on this pool.
def checkin: (untyped conn) -> untyped
# Remove a connection from the connection pool. The connection will
# remain open and active but will no longer be managed by this pool.
def remove: (untyped conn) -> untyped
# Recover lost connections for the pool. A lost connection can occur if
# a programmer forgets to checkin a connection at the end of a thread
# or a thread dies unexpectedly.
def reap: () -> (nil | untyped)
# Disconnect all connections that have been idle for at least
# +minimum_idle+ seconds. Connections currently checked out, or that were
# checked in less than +minimum_idle+ seconds ago, are unaffected.
def flush: (?untyped minimum_idle) -> (nil | untyped)
# Disconnect all currently idle connections. Connections currently checked
# out are unaffected.
def flush!: () -> untyped
def num_waiting_in_queue: () -> untyped
# Return connection pool's usage statistic
# Example:
#
# ActiveRecord::Base.connection_pool.stat # => { size: 15, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }
def stat: () -> untyped
# -
# this is unfortunately not concurrent
def bulk_make_new_connections: (untyped num_new_conns_needed) -> untyped
# -
# From the discussion on GitHub:
# https://github.com/rails/rails/pull/14938#commitcomment-6601951
# This hook-in method allows for easier monkey-patching fixes needed by
# JRuby users that use Fibers.
def connection_cache_key: (untyped thread) -> untyped
def current_thread: () -> untyped
# Take control of all existing connections so a "group" action such as
# reload/disconnect can be performed safely. It is no longer enough to
# wrap it in +synchronize+ because some pool's actions are allowed
# to be performed outside of the main +synchronize+ block.
def with_exclusively_acquired_all_connections: (?bool raise_on_acquisition_timeout) { () -> untyped } -> untyped
def attempt_to_checkout_all_existing_connections: (?bool raise_on_acquisition_timeout) -> untyped
# -
# Must be called in a synchronize block.
def checkout_for_exclusive_access: (untyped checkout_timeout) -> untyped
def with_new_connections_blocked: () { () -> untyped } -> untyped
# Acquire a connection by one of 1) immediately removing one
# from the queue of available connections, 2) creating a new
# connection if the pool is not at capacity, 3) waiting on the
# queue for a connection to become available.
#
# Raises:
# - ActiveRecord::ConnectionTimeoutError if a connection could not be acquired
#
# -
# Implementation detail: the connection returned by +acquire_connection+
# will already be "+connection.lease+ -ed" to the current thread.
def acquire_connection: (untyped checkout_timeout) -> untyped
# -
# if owner_thread param is omitted, this must be called in synchronize block
def remove_connection_from_thread_cache: (untyped conn, ?untyped owner_thread) -> untyped
def new_connection: () -> untyped
# If the pool is not at a @size limit, establish new connection. Connecting
# to the DB is done outside main synchronized section.
# -
# Implementation constraint: a newly established connection returned by this
# method must be in the +.leased+ state.
def try_to_checkout_new_connection: () -> untyped
def adopt_connection: (untyped conn) -> untyped
def checkout_new_connection: () -> untyped
def checkout_and_verify: (untyped c) -> untyped
end
# ConnectionHandler is a collection of ConnectionPool objects. It is used
# for keeping separate connection pools that connect to different databases.
#
# For example, suppose that you have 5 models, with the following hierarchy:
#
# class Author < ActiveRecord::Base
# end
#
# class BankAccount < ActiveRecord::Base
# end
#
# class Book < ActiveRecord::Base
# establish_connection :library_db
# end
#
# class ScaryBook < Book
# end
#
# class GoodBook < Book
# end
#
# And a database.yml that looked like this:
#
# development:
# database: my_application
# host: localhost
#
# library_db:
# database: library
# host: some.library.org
#
# Your primary database in the development environment is "my_application"
# but the Book model connects to a separate database called "library_db"
# (this can even be a database on a different machine).
#
# Book, ScaryBook and GoodBook will all use the same connection pool to
# "library_db" while Author, BankAccount, and any other models you create
# will use the default connection pool to "my_application".
#
# The various connection pools are managed by a single instance of
# ConnectionHandler accessible via ActiveRecord::Base.connection_handler.
# All Active Record models use this handler to determine the connection pool that they
# should use.
#
# The ConnectionHandler class is not coupled with the Active models, as it has no knowledge
# about the model. The model needs to pass a specification name to the handler,
# in order to look up the correct connection pool.
class ConnectionHandler
def self.create_owner_to_pool: () -> untyped
def self.unowned_pool_finalizer: (untyped pid_map) -> untyped
def self.discard_unowned_pools: (untyped pid_map) -> untyped
def initialize: () -> untyped
def prevent_writes: () -> untyped
def prevent_writes=: (untyped prevent_writes) -> untyped
# Prevent writing to the database regardless of role.
#
# In some cases you may want to prevent writes to the database
# even if you are on a database that can write. `while_preventing_writes`
# will prevent writes to the database for the duration of the block.
def while_preventing_writes: (?bool enabled) { () -> untyped } -> untyped
def connection_pool_list: () -> untyped
def establish_connection: (untyped config) -> untyped
# Returns true if there are any active connections among the connection
# pools that the ConnectionHandler is managing.
def active_connections?: () -> untyped
# Returns any connections in use by the current thread back to the pool,
# and also returns connections to the pool cached by threads that are no
# longer alive.
def clear_active_connections!: () -> untyped
# Clears the cache which maps classes.
#
# See ConnectionPool#clear_reloadable_connections! for details.
def clear_reloadable_connections!: () -> untyped
def clear_all_connections!: () -> untyped
# Disconnects all currently idle connections.
#
# See ConnectionPool#flush! for details.
def flush_idle_connections!: () -> untyped
def retrieve_connection: (untyped spec_name) -> untyped
# Returns true if a connection that's accessible to this class has
# already been opened.
def connected?: (untyped spec_name) -> untyped
# Remove the connection for this class. This will close the active
# connection and the defined connection (if they exist). The result
# can be used as an argument for #establish_connection, for easily
# re-establishing the connection.
def remove_connection: (untyped spec_name) -> untyped
# Retrieving the connection pool happens a lot, so we cache it in @owner_to_pool.
# This makes retrieving the connection pool O(1) once the process is warm.
# When a connection is established or removed, we invalidate the cache.
def retrieve_connection_pool: (untyped spec_name) -> untyped
def owner_to_pool: () -> untyped
def pool_from_any_process_for: (untyped spec_name) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
# :nodoc:
module DatabaseLimits
def max_identifier_length: () -> 64
# Returns the maximum length of a table alias.
def table_alias_length: () -> untyped
# Returns the maximum length of a column name.
def column_name_length: () -> untyped
# Returns the maximum length of a table name.
def table_name_length: () -> untyped
# Returns the maximum allowed length for an index name. This
# limit is enforced by \Rails and is less than or equal to
# #index_name_length. The gap between
# #index_name_length is to allow internal \Rails
# operations to use prefixes in temporary operations.
def allowed_index_name_length: () -> untyped
# Returns the maximum length of an index name.
def index_name_length: () -> untyped
# Returns the maximum number of columns per table.
def columns_per_table: () -> 1024
# Returns the maximum number of indexes per table.
def indexes_per_table: () -> 16
# Returns the maximum number of columns in a multicolumn index.
def columns_per_multicolumn_index: () -> 16
# Returns the maximum number of elements in an IN (x,y,z) clause.
# +nil+ means no limit.
def in_clause_length: () -> nil
# Returns the maximum length of an SQL query.
def sql_query_length: () -> 1048575
# Returns maximum number of joins in a single query.
def joins_per_query: () -> 256
def bind_params_length: () -> 65535
end
end
end
module ActiveRecord
module ConnectionAdapters
# :nodoc:
module DatabaseStatements
def initialize: () -> untyped
# Converts an arel AST to SQL
def to_sql: (untyped arel_or_sql_string, ?untyped binds) -> untyped
def to_sql_and_binds: (untyped arel_or_sql_string, ?untyped binds) -> untyped
def cacheable_query: (untyped klass, untyped arel) -> ::Array[untyped]
# Returns an ActiveRecord::Result instance.
def select_all: (untyped arel, ?untyped? name, ?untyped binds, ?preparable: untyped? preparable) -> untyped
# Returns a record hash with the column names as keys and column values
# as values.
def select_one: (untyped arel, ?untyped? name, ?untyped binds) -> untyped
# Returns a single value from a record
def select_value: (untyped arel, ?untyped? name, ?untyped binds) -> untyped
# Returns an array of the values of the first column in a select:
# select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
def select_values: (untyped arel, ?untyped? name, ?untyped binds) -> untyped
# Returns an array of arrays containing the field values.
# Order is the same as that returned by +columns+.
def select_rows: (untyped arel, ?untyped? name, ?untyped binds) -> untyped
def query_value: (untyped sql, ?untyped? name) -> untyped
def query_values: (untyped sql, ?untyped? name) -> untyped
def query: (untyped sql, ?untyped? name) -> untyped
# Determines whether the SQL statement is a write query.
def write_query?: (untyped sql) -> untyped
# Executes the SQL statement in the context of this connection and returns
# the raw result from the connection adapter.
# Note: depending on your database connector, the result returned by this
# method may be manually memory managed. Consider using the exec_query
# wrapper instead.
def execute: (untyped sql, ?untyped? name) -> untyped
# Executes +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is logged along with
# the executed +sql+ statement.
def exec_query: (untyped sql, ?::String name, ?untyped binds, ?prepare: bool prepare) -> untyped
# Executes insert +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is logged along with
# the executed +sql+ statement.
def exec_insert: (untyped sql, ?untyped? name, ?untyped binds, ?untyped? pk, ?untyped? sequence_name) -> untyped
# Executes delete +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is logged along with
# the executed +sql+ statement.
def exec_delete: (untyped sql, ?untyped? name, ?untyped binds) -> untyped
# Executes update +sql+ statement in the context of this connection using
# +binds+ as the bind substitutes. +name+ is logged along with
# the executed +sql+ statement.
def exec_update: (untyped sql, ?untyped? name, ?untyped binds) -> untyped
def exec_insert_all: (untyped sql, untyped name) -> untyped
# Executes an INSERT query and returns the new record's ID
#
# +id_value+ will be returned unless the value is +nil+, in
# which case the database will attempt to calculate the last inserted
# id and return that value.
#
# If the next id was calculated in advance (as in Oracle), it should be
# passed in as +id_value+.
def insert: (untyped arel, ?untyped? name, ?untyped? pk, ?untyped? id_value, ?untyped? sequence_name, ?untyped binds) -> untyped
# Executes the update statement and returns the number of rows affected.
def update: (untyped arel, ?untyped? name, ?untyped binds) -> untyped
# Executes the delete statement and returns the number of rows affected.
def delete: (untyped arel, ?untyped? name, ?untyped binds) -> untyped
# Executes the truncate statement.
def truncate: (untyped table_name, ?untyped? name) -> untyped
def truncate_tables: (*untyped table_names) -> (nil | untyped)
# Runs the given block in a database transaction, and returns the result
# of the block.
#
# == Nested transactions support
#
# Most databases don't support true nested transactions. At the time of
# writing, the only database that supports true nested transactions that
# we're aware of, is MS-SQL.
#
# In order to get around this problem, #transaction will emulate the effect
# of nested transactions, by using savepoints:
# https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
# Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
# supports savepoints.
#
# It is safe to call this method if a database transaction is already open,
# i.e. if #transaction is called within another #transaction block. In case
# of a nested call, #transaction will behave as follows:
#
# - The block will be run without doing anything. All database statements
# that happen within the block are effectively appended to the already
# open database transaction.
# - However, if +:requires_new+ is set, the block will be wrapped in a
# database savepoint acting as a sub-transaction.
#
# === Caveats
#
# MySQL doesn't support DDL transactions. If you perform a DDL operation,
# then any created savepoints will be automatically released. For example,
# if you've created a savepoint, then you execute a CREATE TABLE statement,
# then the savepoint that was created will be automatically released.
#
# This means that, on MySQL, you shouldn't execute DDL operations inside
# a #transaction call that you know might create a savepoint. Otherwise,
# #transaction will raise exceptions when it tries to release the
# already-automatically-released savepoints:
#
# Model.connection.transaction do # BEGIN
# Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
# Model.connection.create_table(...)
# # active_record_1 now automatically released
# end # RELEASE SAVEPOINT active_record_1 <--- BOOM! database error!
# end
#
# == Transaction isolation
#
# If your database supports setting the isolation level for a transaction, you can set
# it like so:
#
# Post.transaction(isolation: :serializable) do
# # ...
# end
#
# Valid isolation levels are:
#
# * :read_uncommitted
# * :read_committed
# * :repeatable_read
# * :serializable
#
# You should consult the documentation for your database to understand the
# semantics of these different levels:
#
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
# * https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html
#
# An ActiveRecord::TransactionIsolationError will be raised if:
#
# * The adapter does not support setting the isolation level
# * You are joining an existing open transaction
# * You are creating a nested (savepoint) transaction
#
# The mysql2 and postgresql adapters support setting the transaction
# isolation level.
def transaction: (?joinable: bool joinable, ?isolation: untyped? isolation, ?requires_new: untyped? requires_new) { () -> untyped } -> untyped
attr_reader transaction_manager: untyped
def transaction_open?: () -> untyped
def reset_transaction: () -> untyped
# Register a record with the current transaction so that its after_commit and after_rollback callbacks
# can be called.
def add_transaction_record: (untyped record) -> untyped
def transaction_state: () -> untyped
# Begins the transaction (and turns off auto-committing).
def begin_db_transaction: () -> nil
def transaction_isolation_levels: () -> { read_uncommitted: "READ UNCOMMITTED", read_committed: "READ COMMITTED", repeatable_read: "REPEATABLE READ", serializable: "SERIALIZABLE" }
# Begins the transaction with the isolation level set. Raises an error by
# default; adapters that support setting the isolation level should implement
# this method.
def begin_isolated_db_transaction: (untyped isolation) -> untyped
# Commits the transaction (and turns on auto-committing).
def commit_db_transaction: () -> nil
# Rolls back the transaction (and turns on auto-committing). Must be
# done if the transaction block raises an exception or returns false.
def rollback_db_transaction: () -> untyped
def exec_rollback_db_transaction: () -> nil
def rollback_to_savepoint: (?untyped? name) -> untyped
def default_sequence_name: (untyped table, untyped column) -> nil
# Set the sequence to the max value of the table's column.
def reset_sequence!: (untyped table, untyped column, ?untyped? sequence) -> nil
# Inserts the given fixture into the table. Overridden in adapters that require
# something beyond a simple insert (eg. Oracle).
# Most of adapters should implement `insert_fixtures_set` that leverages bulk SQL insert.
# We keep this method to provide fallback
# for databases like sqlite that do not support bulk inserts.
def insert_fixture: (untyped fixture, untyped table_name) -> untyped
def insert_fixtures_set: (untyped fixture_set, ?untyped tables_to_delete) -> untyped
def empty_insert_statement_value: (?untyped? primary_key) -> "DEFAULT VALUES"
# Sanitizes the given LIMIT parameter in order to prevent SQL injection.
#
# The +limit+ may be anything that can evaluate to a string via #to_s. It
# should look like an integer, or an Arel SQL literal.
#
# Returns Integer and Arel::Nodes::SqlLiteral limits as is.
def sanitize_limit: (untyped limit) -> untyped
def with_yaml_fallback: (untyped value) -> untyped
def execute_batch: (untyped statements, ?untyped? name) -> untyped
DEFAULT_INSERT_VALUE: untyped
def default_insert_value: (untyped column) -> untyped
def build_fixture_sql: (untyped fixtures, untyped table_name) -> untyped
def build_fixture_statements: (untyped fixture_set) -> untyped
def build_truncate_statement: (untyped table_name) -> ::String
def build_truncate_statements: (untyped table_names) -> untyped
def with_multi_statements: () { () -> untyped } -> untyped
def combine_multi_statements: (untyped total_sql) -> untyped
# Returns an ActiveRecord::Result instance.
def select: (untyped sql, ?untyped? name, ?untyped binds) -> untyped
def select_prepared: (untyped sql, ?untyped? name, ?untyped binds) -> untyped
def sql_for_insert: (untyped sql, untyped pk, untyped binds) -> ::Array[untyped]
def last_inserted_id: (untyped result) -> untyped
def single_value_from_rows: (untyped rows) -> untyped
def arel_from_relation: (untyped relation) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
class AbstractMysqlAdapter < AbstractAdapter
include MySQL::Quoting
include MySQL::SchemaStatements
NATIVE_DATABASE_TYPES: ::Hash[untyped, untyped]
class StatementPool < ConnectionAdapters::StatementPool
def dealloc: (untyped stmt) -> untyped
end
def initialize: (untyped connection, untyped logger, untyped connection_options, untyped config) -> untyped
def get_database_version: () -> AbstractAdapter::Version
def mariadb?: () -> untyped
def supports_bulk_alter?: () -> ::TrueClass
def supports_index_sort_order?: () -> untyped
def supports_expression_index?: () -> untyped
def supports_transaction_isolation?: () -> ::TrueClass
def supports_explain?: () -> ::TrueClass
def supports_indexes_in_create?: () -> ::TrueClass
def supports_foreign_keys?: () -> ::TrueClass
def supports_views?: () -> ::TrueClass
def supports_datetime_with_precision?: () -> untyped
def supports_virtual_columns?: () -> untyped
# See https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html for more details.
def supports_optimizer_hints?: () -> untyped
def supports_common_table_expressions?: () -> untyped
def supports_advisory_locks?: () -> ::TrueClass
def supports_insert_on_duplicate_skip?: () -> ::TrueClass
def supports_insert_on_duplicate_update?: () -> ::TrueClass
def get_advisory_lock: (untyped lock_name, ?::Integer timeout) -> untyped
def release_advisory_lock: (untyped lock_name) -> untyped
def native_database_types: () -> untyped
def index_algorithms: () -> { default: untyped, copy: untyped, inplace: untyped }
def each_hash: (untyped result) -> untyped
def error_number: (untyped exception) -> untyped
def disable_referential_integrity: () { () -> untyped } -> untyped
def clear_cache!: () -> untyped
def explain: (untyped arel, ?untyped binds) -> untyped
# Executes the SQL statement in the context of this connection.
def execute: (untyped sql, ?untyped? name) -> untyped
def execute_and_free: (untyped sql, ?untyped? name) { (untyped) -> untyped } -> untyped
def begin_db_transaction: () -> untyped
def begin_isolated_db_transaction: (untyped isolation) -> untyped
def commit_db_transaction: () -> untyped
def exec_rollback_db_transaction: () -> untyped
def empty_insert_statement_value: (?untyped? primary_key) -> "VALUES ()"
# Drops the database specified on the +name+ attribute
# and creates it again using the provided +options+.
def recreate_database: (untyped name, ?::Hash[untyped, untyped] options) -> untyped
# Create a new MySQL database with optional :charset and :collation.
# Charset defaults to utf8mb4.
#
# Example:
# create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin'
# create_database 'matt_development'
# create_database 'matt_development', charset: :big5
def create_database: (untyped name, ?::Hash[untyped, untyped] options) -> untyped
def drop_database: (untyped name) -> untyped
def current_database: () -> untyped
# Returns the database character set.
def charset: () -> untyped
# Returns the database collation strategy.
def collation: () -> untyped
def table_comment: (untyped table_name) -> untyped
def change_table_comment: (untyped table_name, untyped comment_or_changes) -> untyped
# Renames a table.
#
# Example:
# rename_table('octopuses', 'octopi')
def rename_table: (untyped table_name, untyped new_name) -> untyped
# Drops a table from the database.
#
# [:force]
# Set to +:cascade+ to drop dependent objects as well.
# Defaults to false.
# [:if_exists]
# Set to +true+ to only drop the table if it exists.
# Defaults to false.
# [:temporary]
# Set to +true+ to drop temporary table.
# Defaults to false.
#
# Although this command ignores most +options+ and the block if one is given,
# it can be helpful to provide these in a migration's +change+ method so it can be reverted.
# In that case, +options+ and the block will be used by create_table.
def drop_table: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
def rename_index: (untyped table_name, untyped old_name, untyped new_name) -> untyped
def change_column_default: (untyped table_name, untyped column_name, untyped default_or_changes) -> untyped
def change_column_null: (untyped table_name, untyped column_name, untyped null, ?untyped? default) -> untyped
def change_column_comment: (untyped table_name, untyped column_name, untyped comment_or_changes) -> untyped
def change_column: (untyped table_name, untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
def rename_column: (untyped table_name, untyped column_name, untyped new_column_name) -> untyped
def add_index: (untyped table_name, untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
def add_sql_comment!: (untyped sql, untyped comment) -> untyped
def foreign_keys: (untyped table_name) -> untyped
def table_options: (untyped table_name) -> untyped
# SHOW VARIABLES LIKE 'name'
def show_variable: (untyped name) -> untyped
def primary_keys: (untyped table_name) -> untyped
def default_uniqueness_comparison: (untyped attribute, untyped value, untyped klass) -> untyped
def case_sensitive_comparison: (untyped attribute, untyped value) -> untyped
def can_perform_case_insensitive_comparison_for?: (untyped column) -> untyped
def columns_for_distinct: (untyped columns, untyped orders) -> untyped
def strict_mode?: () -> untyped
def default_index_type?: (untyped index) -> untyped
def build_insert_sql: (untyped insert) -> untyped
def check_version: () -> untyped
def initialize_type_map: (?untyped m) -> untyped
def register_integer_type: (untyped mapping, untyped key, **untyped options) -> untyped
def extract_precision: (untyped sql_type) -> untyped
# See https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
ER_FILSORT_ABORT: ::Integer
ER_DUP_ENTRY: ::Integer
ER_NOT_NULL_VIOLATION: ::Integer
ER_NO_REFERENCED_ROW: ::Integer
ER_ROW_IS_REFERENCED: ::Integer
ER_DO_NOT_HAVE_DEFAULT: ::Integer
ER_ROW_IS_REFERENCED_2: ::Integer
ER_NO_REFERENCED_ROW_2: ::Integer
ER_DATA_TOO_LONG: ::Integer
ER_OUT_OF_RANGE: ::Integer
ER_LOCK_DEADLOCK: ::Integer
ER_CANNOT_ADD_FOREIGN: ::Integer
ER_CANNOT_CREATE_TABLE: ::Integer
ER_LOCK_WAIT_TIMEOUT: ::Integer
ER_QUERY_INTERRUPTED: ::Integer
ER_QUERY_TIMEOUT: ::Integer
ER_FK_INCOMPATIBLE_COLUMNS: ::Integer
def translate_exception: (untyped exception, binds: untyped binds, sql: untyped sql, message: untyped message) -> untyped
def change_column_for_alter: (untyped table_name, untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
def rename_column_for_alter: (untyped table_name, untyped column_name, untyped new_column_name) -> untyped
def add_index_for_alter: (untyped table_name, untyped column_name, ?::Hash[untyped, untyped] options) -> ::String
def remove_index_for_alter: (untyped table_name, ?::Hash[untyped, untyped] options) -> ::String
def supports_rename_index?: () -> untyped
def configure_connection: () -> untyped
def column_definitions: (untyped table_name) -> untyped
def create_table_info: (untyped table_name) -> untyped
def arel_visitor: () -> untyped
def build_statement_pool: () -> untyped
def mismatched_foreign_key: (untyped message, binds: untyped binds, sql: untyped sql) -> untyped
def version_string: (untyped full_version_string) -> untyped
class MysqlString < ActiveModel::Type::String
# :nodoc:
def serialize: (untyped value) -> untyped
def cast_value: (untyped value) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
# :nodoc:
module QueryCache
def self.included: (untyped base) -> untyped
def self.dirties_query_cache: (untyped base, *untyped method_names) -> untyped
module ConnectionPoolConfiguration
def initialize: () -> untyped
def enable_query_cache!: () -> untyped
def disable_query_cache!: () -> untyped
def query_cache_enabled: () -> untyped
end
attr_reader query_cache: untyped
attr_reader query_cache_enabled: untyped
def initialize: () -> untyped
# Enable the query cache within the block.
def cache: () { () -> untyped } -> untyped
def enable_query_cache!: () -> untyped
def disable_query_cache!: () -> untyped
# Disable the query cache within the block.
def uncached: () { () -> untyped } -> untyped
# Clears the query cache.
#
# One reason you may wish to call this method explicitly is between queries
# that ask the database to randomize results. Otherwise the cache would see
# the same SQL query and repeatedly return the same result each time, silently
# undermining the randomness you were expecting.
def clear_query_cache: () -> untyped
def select_all: (untyped arel, ?untyped? name, ?untyped binds, ?preparable: untyped? preparable) -> untyped
def cache_sql: (untyped sql, untyped name, untyped binds) { () -> untyped } -> untyped
# Database adapters can override this method to
# provide custom cache information.
def cache_notification_info: (untyped sql, untyped name, untyped binds) -> { sql: untyped, binds: untyped, type_casted_binds: untyped, name: untyped, connection_id: untyped, connection: untyped, cached: ::TrueClass }
# If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
# queries should not be cached.
def locked?: (untyped arel) -> untyped
def configure_query_cache!: () -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
# :nodoc:
module Quoting
# Quotes the column value to help prevent
# {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
def quote: (untyped value) -> untyped
# Cast a +value+ to a type that the database understands. For example,
# SQLite does not understand dates, so this method will convert a Date
# to a String.
def type_cast: (untyped value, ?untyped? column) -> untyped
def type_cast_from_column: (untyped column, untyped value) -> untyped
def lookup_cast_type_from_column: (untyped column) -> untyped
# Quotes a string, escaping any ' (single quote) and \ (backslash)
# characters.
def quote_string: (untyped s) -> untyped
# Quotes the column name. Defaults to no quoting.
def quote_column_name: (untyped column_name) -> untyped
# Quotes the table name. Defaults to column name quoting.
def quote_table_name: (untyped table_name) -> untyped
# Override to return the quoted table name for assignment. Defaults to
# table quoting.
#
# This works for mysql2 where table.column can be used to
# resolve ambiguity.
#
# We override this in the sqlite3 and postgresql adapters to use only
# the column name (as per syntax requirements).
def quote_table_name_for_assignment: (untyped table, untyped attr) -> untyped
def quote_default_expression: (untyped value, untyped column) -> untyped
def quoted_true: () -> "TRUE"
def unquoted_true: () -> ::TrueClass
def quoted_false: () -> "FALSE"
def unquoted_false: () -> ::FalseClass
# Quote date/time values for use in SQL input. Includes microseconds
# if the value is a Time responding to usec.
def quoted_date: (untyped value) -> untyped
def quoted_time: (untyped value) -> untyped
def quoted_binary: (untyped value) -> ::String
def sanitize_as_sql_comment: (untyped value) -> untyped
def column_name_matcher: () -> untyped
def column_name_with_order_matcher: () -> untyped
# Regexp for column names (with or without a table name prefix).
# Matches the following:
#
# "#{table_name}.#{column_name}"
# "#{column_name}"
COLUMN_NAME: untyped
# Regexp for column names with order (with or without a table name prefix,
# with or without various order modifiers). Matches the following:
#
# "#{table_name}.#{column_name}"
# "#{table_name}.#{column_name} #{direction}"
# "#{table_name}.#{column_name} #{direction} NULLS FIRST"
# "#{table_name}.#{column_name} NULLS LAST"
# "#{column_name}"
# "#{column_name} #{direction}"
# "#{column_name} #{direction} NULLS FIRST"
# "#{column_name} NULLS LAST"
COLUMN_NAME_WITH_ORDER: untyped
def type_casted_binds: (untyped binds) -> untyped
def lookup_cast_type: (untyped sql_type) -> untyped
def id_value_for_database: (untyped value) -> untyped
def _quote: (untyped value) -> untyped
def _type_cast: (untyped value) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
module Savepoints
def current_savepoint_name: () -> untyped
def create_savepoint: (?untyped name) -> untyped
def exec_rollback_to_savepoint: (?untyped name) -> untyped
def release_savepoint: (?untyped name) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
class AbstractAdapter
class SchemaCreation
# :nodoc:
def initialize: (untyped conn) -> untyped
def accept: (untyped o) -> untyped
def visit_AlterTable: (untyped o) -> untyped
def visit_ColumnDefinition: (untyped o) -> untyped
def visit_AddColumnDefinition: (untyped o) -> untyped
def visit_TableDefinition: (untyped o) -> untyped
def visit_PrimaryKeyDefinition: (untyped o) -> ::String
def visit_ForeignKeyDefinition: (untyped o) -> untyped
def visit_AddForeignKey: (untyped o) -> ::String
def visit_DropForeignKey: (untyped name) -> ::String
def table_options: (untyped o) -> untyped
def add_table_options!: (untyped create_sql, untyped options) -> untyped
def column_options: (untyped o) -> untyped
def add_column_options!: (untyped sql, untyped options) -> untyped
def to_sql: (untyped sql) -> untyped
# Returns any SQL string to go between CREATE and TABLE. May be nil.
def table_modifier_in_create: (untyped o) -> untyped
def foreign_key_in_create: (untyped from_table, untyped to_table, untyped options) -> untyped
def action_sql: (untyped action, untyped dependency) -> untyped
end
end
SchemaCreation: untyped
end
end
module ActiveRecord
module ConnectionAdapters
class IndexDefinition
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader table: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader name: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader unique: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader columns: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader lengths: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader orders: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader opclasses: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader where: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader type: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader using: untyped
# nodoc:
# Abstract representation of an index definition on a table. Instances of
# this type are typically created and returned by methods in database
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
# :nodoc:
attr_reader comment: untyped
def initialize: (untyped table, untyped name, ?bool unique, ?untyped columns, ?comment: untyped? comment, ?using: untyped? using, ?type: untyped? `type`, ?where: untyped? where, ?opclasses: ::Hash[untyped, untyped] opclasses, ?orders: ::Hash[untyped, untyped] orders, ?lengths: ::Hash[untyped, untyped] lengths) -> untyped
def concise_options: (untyped options) -> untyped
end
class ColumnDefinition < ::Struct[untyped]
attr_accessor name(): untyped
attr_accessor type(): untyped
attr_accessor options(): untyped
attr_accessor sql_type(): untyped
# Abstract representation of a column definition. Instances of this type
# are typically created by methods in TableDefinition, and added to the
# +columns+ attribute of said TableDefinition object, in order to be used
# for generating a number of table creation or table changing SQL statements.
# :nodoc:
def primary_key?: () -> untyped
end
class AddColumnDefinition < ::Struct[untyped]
attr_accessor column(): untyped
end
class ChangeColumnDefinition < ::Struct[untyped]
attr_accessor column(): untyped
attr_accessor name(): untyped
end
class PrimaryKeyDefinition < ::Struct[untyped]
attr_accessor name(): untyped
end
class ForeignKeyDefinition < ::Struct[untyped]
attr_accessor from_table(): untyped
attr_accessor to_table(): untyped
attr_accessor options(): untyped
# nodoc:
def name: () -> untyped
def column: () -> untyped
def primary_key: () -> untyped
def on_delete: () -> untyped
def on_update: () -> untyped
def custom_primary_key?: () -> untyped
def validate?: () -> untyped
def export_name_on_schema_dump?: () -> untyped
def defined_for?: (?to_table: untyped? to_table, **untyped options) -> untyped
def default_primary_key: () -> "id"
end
class ReferenceDefinition
# :nodoc:
def initialize: (untyped name, ?type: ::Symbol `type`, ?foreign_key: bool foreign_key, ?index: bool index, ?polymorphic: bool polymorphic, **untyped options) -> untyped
def add_to: (untyped table) -> untyped
attr_reader name: untyped
attr_reader polymorphic: untyped
attr_reader index: untyped
attr_reader foreign_key: untyped
attr_reader type: untyped
attr_reader options: untyped
def as_options: (untyped value) -> untyped
def polymorphic_options: () -> untyped
def index_options: () -> untyped
def foreign_key_options: () -> untyped
def columns: () -> untyped
def column_name: () -> ::String
def column_names: () -> untyped
def foreign_table_name: () -> untyped
end
module ColumnMethods
extend ActiveSupport::Concern
# Appends a primary key definition to the table definition.
# Can be called multiple times, but this is probably not a good idea.
def primary_key: (untyped name, ?::Symbol `type`, **untyped options) -> untyped
module ClassMethods
def define_column_methods: (*untyped column_types) -> untyped
end
end
# Represents the schema of an SQL table in an abstract way. This class
# provides methods for manipulating the schema representation.
#
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
# is actually of this type:
#
# class SomeMigration < ActiveRecord::Migration[5.0]
# def up
# create_table :foo do |t|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
# end
# end
#
# def down
# ...
# end
# end
#
class TableDefinition
include ColumnMethods
extend ::ActiveRecord::ConnectionAdapters::ColumnMethods::ClassMethods
attr_reader name: untyped
attr_reader temporary: untyped
attr_reader if_not_exists: untyped
attr_reader options: untyped
attr_reader as: untyped
attr_reader comment: untyped
attr_reader indexes: untyped
attr_reader foreign_keys: untyped
def initialize: (untyped conn, untyped name, ?comment: untyped? comment, ?as: untyped? as, ?options: untyped? options, ?if_not_exists: bool if_not_exists, ?temporary: bool temporary) -> untyped
def primary_keys: (?untyped? name) -> untyped
# Returns an array of ColumnDefinition objects for the columns of the table.
def columns: () -> untyped
# Returns a ColumnDefinition for the column with name +name+.
def []: (untyped name) -> untyped
# Instantiates a new column for the table.
# See {connection.add_column}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_column]
# for available options.
#
# Additional options are:
# * :index -
# Create an index for the column. Can be either true or an options hash.
#
# This method returns self.
#
# == Examples
#
# # Assuming +td+ is an instance of TableDefinition
# td.column(:granted, :boolean, index: true)
#
# == Short-hand examples
#
# Instead of calling #column directly, you can also work with the short-hand definitions for the default types.
# They use the type as the method name instead of as a parameter and allow for multiple columns to be defined
# in a single statement.
#
# What can be written like this with the regular calls to column:
#
# create_table :products do |t|
# t.column :shop_id, :integer
# t.column :creator_id, :integer
# t.column :item_number, :string
# t.column :name, :string, default: "Untitled"
# t.column :value, :string, default: "Untitled"
# t.column :created_at, :datetime
# t.column :updated_at, :datetime
# end
# add_index :products, :item_number
#
# can also be written as follows using the short-hand:
#
# create_table :products do |t|
# t.integer :shop_id, :creator_id
# t.string :item_number, index: true
# t.string :name, :value, default: "Untitled"
# t.timestamps null: false
# end
#
# There's a short-hand method for each of the type values declared at the top. And then there's
# TableDefinition#timestamps that'll add +created_at+ and +updated_at+ as datetimes.
#
# TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
# column if the :polymorphic option is supplied. If :polymorphic is a hash of
# options, these will be used when creating the _type column. The :index option
# will also create an index, similar to calling {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index].
# So what can be written like this:
#
# create_table :taggings do |t|
# t.integer :tag_id, :tagger_id, :taggable_id
# t.string :tagger_type
# t.string :taggable_type, default: 'Photo'
# end
# add_index :taggings, :tag_id, name: 'index_taggings_on_tag_id'
# add_index :taggings, [:tagger_id, :tagger_type]
#
# Can also be written as follows using references:
#
# create_table :taggings do |t|
# t.references :tag, index: { name: 'index_taggings_on_tag_id' }
# t.references :tagger, polymorphic: true
# t.references :taggable, polymorphic: { default: 'Photo' }, index: false
# end
def column: (untyped name, untyped `type`, **untyped options) -> untyped
# remove the column +name+ from the table.
# remove_column(:account_id)
def remove_column: (untyped name) -> untyped
# Adds index options to the indexes hash, keyed by column name
# This is primarily used to track indexes that need to be created after the table
#
# index(:account_id, name: 'index_projects_on_account_id')
def index: (untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
def foreign_key: (untyped table_name, **untyped options) -> untyped
# Appends :datetime columns :created_at and
# :updated_at to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
#
# t.timestamps null: false
def timestamps: (**untyped options) -> untyped
# Adds a reference.
#
# t.references(:user)
# t.belongs_to(:supplier, foreign_key: true)
# t.belongs_to(:supplier, foreign_key: true, type: :integer)
#
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
def references: (*untyped args, **untyped options) -> untyped
def new_column_definition: (untyped name, untyped `type`, **untyped options) -> untyped
def create_column_definition: (untyped name, untyped `type`, untyped options) -> ColumnDefinition
def aliased_types: (untyped name, untyped fallback) -> untyped
def integer_like_primary_key?: (untyped `type`, untyped options) -> untyped
def integer_like_primary_key_type: (untyped `type`, untyped options) -> untyped
end
class AlterTable
# :nodoc:
attr_reader adds: untyped
attr_reader foreign_key_adds: untyped
attr_reader foreign_key_drops: untyped
def initialize: (untyped td) -> untyped
def name: () -> untyped
def add_foreign_key: (untyped to_table, untyped options) -> untyped
def drop_foreign_key: (untyped name) -> untyped
def add_column: (untyped name, untyped `type`, **untyped options) -> untyped
end
# Represents an SQL table in an abstract way for updating a table.
# Also see TableDefinition and {connection.create_table}[rdoc-ref:SchemaStatements#create_table]
#
# Available transformations are:
#
# change_table :table do |t|
# t.primary_key
# t.column
# t.index
# t.rename_index
# t.timestamps
# t.change
# t.change_default
# t.rename
# t.references
# t.belongs_to
# t.string
# t.text
# t.integer
# t.bigint
# t.float
# t.decimal
# t.numeric
# t.datetime
# t.timestamp
# t.time
# t.date
# t.binary
# t.boolean
# t.foreign_key
# t.json
# t.virtual
# t.remove
# t.remove_foreign_key
# t.remove_references
# t.remove_belongs_to
# t.remove_index
# t.remove_timestamps
# end
#
class Table
include ColumnMethods
extend ::ActiveRecord::ConnectionAdapters::ColumnMethods::ClassMethods
attr_reader name: untyped
def initialize: (untyped table_name, untyped base) -> untyped
# Adds a new column to the named table.
#
# t.column(:name, :string)
#
# See TableDefinition#column for details of the options you can use.
def column: (untyped column_name, untyped `type`, **untyped options) -> untyped
# Checks to see if a column exists.
#
# t.string(:name) unless t.column_exists?(:name, :string)
#
# See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
def column_exists?: (untyped column_name, ?untyped? `type`, **untyped options) -> untyped
# Adds a new index to the table. +column_name+ can be a single Symbol, or
# an Array of Symbols.
#
# t.index(:name)
# t.index([:branch_id, :party_id], unique: true)
# t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
#
# See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
def index: (untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
# Checks to see if an index exists.
#
# unless t.index_exists?(:branch_id)
# t.index(:branch_id)
# end
#
# See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
def index_exists?: (untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
# Renames the given index on the table.
#
# t.rename_index(:user_id, :account_id)
#
# See {connection.rename_index}[rdoc-ref:SchemaStatements#rename_index]
def rename_index: (untyped index_name, untyped new_index_name) -> untyped
# Adds timestamps (+created_at+ and +updated_at+) columns to the table.
#
# t.timestamps(null: false)
#
# See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
def timestamps: (**untyped options) -> untyped
# Changes the column's definition according to the new options.
#
# t.change(:name, :string, limit: 80)
# t.change(:description, :text)
#
# See TableDefinition#column for details of the options you can use.
def change: (untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
# Sets a new default value for a column.
#
# t.change_default(:qualification, 'new')
# t.change_default(:authorized, 1)
# t.change_default(:status, from: nil, to: "draft")
#
# See {connection.change_column_default}[rdoc-ref:SchemaStatements#change_column_default]
def change_default: (untyped column_name, untyped default_or_changes) -> untyped
# Removes the column(s) from the table definition.
#
# t.remove(:qualification)
# t.remove(:qualification, :experience)
#
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
def remove: (*untyped column_names) -> untyped
# Removes the given index from the table.
#
# t.remove_index(:branch_id)
# t.remove_index(column: [:branch_id, :party_id])
# t.remove_index(name: :by_branch_party)
#
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
def remove_index: (?::Hash[untyped, untyped] options) -> untyped
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
#
# t.remove_timestamps
#
# See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
def remove_timestamps: (**untyped options) -> untyped
# Renames a column.
#
# t.rename(:description, :name)
#
# See {connection.rename_column}[rdoc-ref:SchemaStatements#rename_column]
def rename: (untyped column_name, untyped new_column_name) -> untyped
# Adds a reference.
#
# t.references(:user)
# t.belongs_to(:supplier, foreign_key: true)
#
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
def references: (*untyped args, **untyped options) -> untyped
# Removes a reference. Optionally removes a +type+ column.
#
# t.remove_references(:user)
# t.remove_belongs_to(:supplier, polymorphic: true)
#
# See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
def remove_references: (*untyped args, **untyped options) -> untyped
# Adds a foreign key to the table using a supplied table name.
#
# t.foreign_key(:authors)
# t.foreign_key(:authors, column: :author_id, primary_key: "id")
#
# See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
def foreign_key: (*untyped args, **untyped options) -> untyped
# Removes the given foreign key from the table.
#
# t.remove_foreign_key(:authors)
# t.remove_foreign_key(column: :author_id)
#
# See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
def remove_foreign_key: (*untyped args, **untyped options) -> untyped
# Checks to see if a foreign key exists.
#
# t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
#
# See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
def foreign_key_exists?: (*untyped args, **untyped options) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
class SchemaDumper < ActiveRecord::SchemaDumper
# :nodoc:
# :nodoc:
def self.create: (untyped connection, untyped options) -> untyped
def column_spec: (untyped column) -> ::Array[untyped]
def column_spec_for_primary_key: (untyped column) -> (::Hash[untyped, untyped] | untyped)
def prepare_column_options: (untyped column) -> untyped
def default_primary_key?: (untyped column) -> untyped
def explicit_primary_key_default?: (untyped column) -> ::FalseClass
def schema_type_with_virtual: (untyped column) -> untyped
def schema_type: (untyped column) -> untyped
def schema_limit: (untyped column) -> untyped
def schema_precision: (untyped column) -> untyped
def schema_scale: (untyped column) -> untyped
def schema_default: (untyped column) -> (nil | untyped)
def schema_expression: (untyped column) -> untyped
def schema_collation: (untyped column) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
# :nodoc:
module SchemaStatements
include ActiveRecord::Migration::JoinTable
# Returns a hash of mappings from the abstract data types to the native
# database types. See TableDefinition#column for details on the recognized
# abstract data types.
def native_database_types: () -> ::Hash[untyped, untyped]
def table_options: (untyped table_name) -> nil
# Returns the table comment that's stored in database metadata.
def table_comment: (untyped table_name) -> nil
# Truncates a table alias according to the limits of the current adapter.
def table_alias_for: (untyped table_name) -> untyped
# Returns the relation names useable to back Active Record models.
# For most adapters this means all #tables and #views.
def data_sources: () -> untyped
# Checks to see if the data source +name+ exists on the database.
#
# data_source_exists?(:ebooks)
#
def data_source_exists?: (untyped name) -> untyped
# Returns an array of table names defined in the database.
def tables: () -> untyped
# Checks to see if the table +table_name+ exists on the database.
#
# table_exists?(:developers)
#
def table_exists?: (untyped table_name) -> untyped
# Returns an array of view names defined in the database.
def views: () -> untyped
# Checks to see if the view +view_name+ exists on the database.
#
# view_exists?(:ebooks)
#
def view_exists?: (untyped view_name) -> untyped
# Returns an array of indexes for the given table.
def indexes: (untyped table_name) -> untyped
# Checks to see if an index exists on a table for a given index definition.
#
# # Check an index exists
# index_exists?(:suppliers, :company_id)
#
# # Check an index on multiple columns exists
# index_exists?(:suppliers, [:company_id, :company_type])
#
# # Check a unique index exists
# index_exists?(:suppliers, :company_id, unique: true)
#
# # Check an index with a custom name exists
# index_exists?(:suppliers, :company_id, name: "idx_company_id")
#
def index_exists?: (untyped table_name, untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
# Returns an array of +Column+ objects for the table specified by +table_name+.
def columns: (untyped table_name) -> untyped
# Checks to see if a column exists in a given table.
#
# # Check a column exists
# column_exists?(:suppliers, :name)
#
# # Check a column exists of a particular type
# column_exists?(:suppliers, :name, :string)
#
# # Check a column exists with a specific definition
# column_exists?(:suppliers, :name, :string, limit: 100)
# column_exists?(:suppliers, :name, :string, default: 'default')
# column_exists?(:suppliers, :name, :string, null: false)
# column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2)
#
def column_exists?: (untyped table_name, untyped column_name, ?untyped? `type`, **untyped options) -> untyped
# Returns just a table's primary key
def primary_key: (untyped table_name) -> untyped
# Creates a new table with the name +table_name+. +table_name+ may either
# be a String or a Symbol.
#
# There are two ways to work with #create_table. You can use the block
# form or the regular form, like this:
#
# === Block form
#
# # create_table() passes a TableDefinition object to the block.
# # This form will not only create the table, but also columns for the
# # table.
#
# create_table(:suppliers) do |t|
# t.column :name, :string, limit: 60
# # Other fields here
# end
#
# === Block form, with shorthand
#
# # You can also use the column types as method calls, rather than calling the column method.
# create_table(:suppliers) do |t|
# t.string :name, limit: 60
# # Other fields here
# end
#
# === Regular form
#
# # Creates a table called 'suppliers' with no columns.
# create_table(:suppliers)
# # Add a column to 'suppliers'.
# add_column(:suppliers, :name, :string, {limit: 60})
#
# The +options+ hash can include the following keys:
# [:id]
# Whether to automatically add a primary key column. Defaults to true.
# Join tables for {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many] should set it to false.
#
# A Symbol can be used to specify the type of the generated primary key column.
# [:primary_key]
# The name of the primary key, if one is to be added automatically.
# Defaults to +id+. If :id is false, then this option is ignored.
#
# If an array is passed, a composite primary key will be created.
#
# Note that Active Record models will automatically detect their
# primary key. This can be avoided by using
# {self.primary_key=}[rdoc-ref:AttributeMethods::PrimaryKey::ClassMethods#primary_key=] on the model
# to define the key explicitly.
#
# [:options]
# Any extra options you want appended to the table definition.
# [:temporary]
# Make a temporary table.
# [:force]
# Set to true to drop the table before creating it.
# Set to +:cascade+ to drop dependent objects as well.
# Defaults to false.
# [:if_not_exists]
# Set to true to avoid raising an error when the table already exists.
# Defaults to false.
# [:as]
# SQL to use to generate the table. When this option is used, the block is
# ignored, as are the :id and :primary_key options.
#
# ====== Add a backend specific option to the generated SQL (MySQL)
#
# create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4')
#
# generates:
#
# CREATE TABLE suppliers (
# id bigint auto_increment PRIMARY KEY
# ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
#
# ====== Rename the primary key column
#
# create_table(:objects, primary_key: 'guid') do |t|
# t.column :name, :string, limit: 80
# end
#
# generates:
#
# CREATE TABLE objects (
# guid bigint auto_increment PRIMARY KEY,
# name varchar(80)
# )
#
# ====== Change the primary key column type
#
# create_table(:tags, id: :string) do |t|
# t.column :label, :string
# end
#
# generates:
#
# CREATE TABLE tags (
# id varchar PRIMARY KEY,
# label varchar
# )
#
# ====== Create a composite primary key
#
# create_table(:orders, primary_key: [:product_id, :client_id]) do |t|
# t.belongs_to :product
# t.belongs_to :client
# end
#
# generates:
#
# CREATE TABLE order (
# product_id bigint NOT NULL,
# client_id bigint NOT NULL
# );
#
# ALTER TABLE ONLY "orders"
# ADD CONSTRAINT orders_pkey PRIMARY KEY (product_id, client_id);
#
# ====== Do not add a primary key column
#
# create_table(:categories_suppliers, id: false) do |t|
# t.column :category_id, :bigint
# t.column :supplier_id, :bigint
# end
#
# generates:
#
# CREATE TABLE categories_suppliers (
# category_id bigint,
# supplier_id bigint
# )
#
# ====== Create a temporary table based on a query
#
# create_table(:long_query, temporary: true,
# as: "SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id")
#
# generates:
#
# CREATE TEMPORARY TABLE long_query AS
# SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id
#
# See also TableDefinition#column for details on how to create columns.
def create_table: (untyped table_name, **untyped options) { (untyped) -> untyped } -> untyped
# Creates a new join table with the name created using the lexical order of the first two
# arguments. These arguments can be a String or a Symbol.
#
# # Creates a table called 'assemblies_parts' with no id.
# create_join_table(:assemblies, :parts)
#
# You can pass an +options+ hash which can include the following keys:
# [:table_name]
# Sets the table name, overriding the default.
# [:column_options]
# Any extra options you want appended to the columns definition.
# [:options]
# Any extra options you want appended to the table definition.
# [:temporary]
# Make a temporary table.
# [:force]
# Set to true to drop the table before creating it.
# Defaults to false.
#
# Note that #create_join_table does not create any indices by default; you can use
# its block form to do so yourself:
#
# create_join_table :products, :categories do |t|
# t.index :product_id
# t.index :category_id
# end
#
# ====== Add a backend specific option to the generated SQL (MySQL)
#
# create_join_table(:assemblies, :parts, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
#
# generates:
#
# CREATE TABLE assemblies_parts (
# assembly_id bigint NOT NULL,
# part_id bigint NOT NULL,
# ) ENGINE=InnoDB DEFAULT CHARSET=utf8
#
def create_join_table: (untyped table_1, untyped table_2, ?column_options: ::Hash[untyped, untyped] column_options, **untyped options) { (untyped) -> untyped } -> untyped
# Drops the join table specified by the given arguments.
# See #create_join_table for details.
#
# Although this command ignores the block if one is given, it can be helpful
# to provide one in a migration's +change+ method so it can be reverted.
# In that case, the block will be used by #create_join_table.
def drop_join_table: (untyped table_1, untyped table_2, **untyped options) -> untyped
# A block for changing columns in +table+.
#
# # change_table() yields a Table instance
# change_table(:suppliers) do |t|
# t.column :name, :string, limit: 60
# # Other column alterations here
# end
#
# The +options+ hash can include the following keys:
# [:bulk]
# Set this to true to make this a bulk alter query, such as
#
# ALTER TABLE `users` ADD COLUMN age INT, ADD COLUMN birthdate DATETIME ...
#
# Defaults to false.
#
# Only supported on the MySQL and PostgreSQL adapter, ignored elsewhere.
#
# ====== Add a column
#
# change_table(:suppliers) do |t|
# t.column :name, :string, limit: 60
# end
#
# ====== Add 2 integer columns
#
# change_table(:suppliers) do |t|
# t.integer :width, :height, null: false, default: 0
# end
#
# ====== Add created_at/updated_at columns
#
# change_table(:suppliers) do |t|
# t.timestamps
# end
#
# ====== Add a foreign key column
#
# change_table(:suppliers) do |t|
# t.references :company
# end
#
# Creates a company_id(bigint) column.
#
# ====== Add a polymorphic foreign key column
#
# change_table(:suppliers) do |t|
# t.belongs_to :company, polymorphic: true
# end
#
# Creates company_type(varchar) and company_id(bigint) columns.
#
# ====== Remove a column
#
# change_table(:suppliers) do |t|
# t.remove :company
# end
#
# ====== Remove several columns
#
# change_table(:suppliers) do |t|
# t.remove :company_id
# t.remove :width, :height
# end
#
# ====== Remove an index
#
# change_table(:suppliers) do |t|
# t.remove_index :company_id
# end
#
# See also Table for details on all of the various column transformations.
def change_table: (untyped table_name, **untyped options) { (untyped) -> untyped } -> untyped
# Renames a table.
#
# rename_table('octopuses', 'octopi')
#
def rename_table: (untyped table_name, untyped new_name) -> untyped
# Drops a table from the database.
#
# [:force]
# Set to +:cascade+ to drop dependent objects as well.
# Defaults to false.
# [:if_exists]
# Set to +true+ to only drop the table if it exists.
# Defaults to false.
#
# Although this command ignores most +options+ and the block if one is given,
# it can be helpful to provide these in a migration's +change+ method so it can be reverted.
# In that case, +options+ and the block will be used by #create_table.
def drop_table: (untyped table_name, **untyped options) -> untyped
# Add a new +type+ column named +column_name+ to +table_name+.
#
# The +type+ parameter is normally one of the migrations native types,
# which is one of the following:
# :primary_key, :string, :text,
# :integer, :bigint, :float, :decimal, :numeric,
# :datetime, :time, :date,
# :binary, :boolean.
#
# You may use a type not in this list as long as it is supported by your
# database (for example, "polygon" in MySQL), but this will not be database
# agnostic and should usually be avoided.
#
# Available options are (none of these exists by default):
# * :limit -
# Requests a maximum column length. This is the number of characters for a :string column
# and number of bytes for :text, :binary, and :integer columns.
# This option is ignored by some backends.
# * :default -
# The column's default value. Use +nil+ for +NULL+.
# * :null -
# Allows or disallows +NULL+ values in the column.
# * :precision -
# Specifies the precision for the :decimal, :numeric,
# :datetime, and :time columns.
# * :scale -
# Specifies the scale for the :decimal and :numeric columns.
# * :collation -
# Specifies the collation for a :string or :text column. If not specified, the
# column will have the same collation as the table.
# * :comment -
# Specifies the comment for the column. This option is ignored by some backends.
#
# Note: The precision is the total number of significant digits,
# and the scale is the number of digits that can be stored following
# the decimal point. For example, the number 123.45 has a precision of 5
# and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
# range from -999.99 to 999.99.
#
# Please be aware of different RDBMS implementations behavior with
# :decimal columns:
# * The SQL standard says the default scale should be 0, :scale <=
# :precision, and makes no comments about the requirements of
# :precision.
# * MySQL: :precision [1..63], :scale [0..30].
# Default is (10,0).
# * PostgreSQL: :precision [1..infinity],
# :scale [0..infinity]. No default.
# * SQLite3: No restrictions on :precision and :scale,
# but the maximum supported :precision is 16. No default.
# * Oracle: :precision [1..38], :scale [-84..127].
# Default is (38,0).
# * DB2: :precision [1..63], :scale [0..62].
# Default unknown.
# * SqlServer: :precision [1..38], :scale [0..38].
# Default (38,0).
#
# == Examples
#
# add_column(:users, :picture, :binary, limit: 2.megabytes)
# # ALTER TABLE "users" ADD "picture" blob(2097152)
#
# add_column(:articles, :status, :string, limit: 20, default: 'draft', null: false)
# # ALTER TABLE "articles" ADD "status" varchar(20) DEFAULT 'draft' NOT NULL
#
# add_column(:answers, :bill_gates_money, :decimal, precision: 15, scale: 2)
# # ALTER TABLE "answers" ADD "bill_gates_money" decimal(15,2)
#
# add_column(:measurements, :sensor_reading, :decimal, precision: 30, scale: 20)
# # ALTER TABLE "measurements" ADD "sensor_reading" decimal(30,20)
#
# # While :scale defaults to zero on most databases, it
# # probably wouldn't hurt to include it.
# add_column(:measurements, :huge_integer, :decimal, precision: 30)
# # ALTER TABLE "measurements" ADD "huge_integer" decimal(30)
#
# # Defines a column that stores an array of a type.
# add_column(:users, :skills, :text, array: true)
# # ALTER TABLE "users" ADD "skills" text[]
#
# # Defines a column with a database-specific type.
# add_column(:shapes, :triangle, 'polygon')
# # ALTER TABLE "shapes" ADD "triangle" polygon
def add_column: (untyped table_name, untyped column_name, untyped `type`, **untyped options) -> untyped
# Removes the given columns from the table definition.
#
# remove_columns(:suppliers, :qualification, :experience)
#
def remove_columns: (untyped table_name, *untyped column_names) -> untyped
# Removes the column from the table definition.
#
# remove_column(:suppliers, :qualification)
#
# The +type+ and +options+ parameters will be ignored if present. It can be helpful
# to provide these in a migration's +change+ method so it can be reverted.
# In that case, +type+ and +options+ will be used by #add_column.
# Indexes on the column are automatically removed.
def remove_column: (untyped table_name, untyped column_name, ?untyped? `type`, **untyped options) -> untyped
# Changes the column's definition according to the new options.
# See TableDefinition#column for details of the options you can use.
#
# change_column(:suppliers, :name, :string, limit: 80)
# change_column(:accounts, :description, :text)
#
def change_column: (untyped table_name, untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
# Sets a new default value for a column:
#
# change_column_default(:suppliers, :qualification, 'new')
# change_column_default(:accounts, :authorized, 1)
#
# Setting the default to +nil+ effectively drops the default:
#
# change_column_default(:users, :email, nil)
#
# Passing a hash containing +:from+ and +:to+ will make this change
# reversible in migration:
#
# change_column_default(:posts, :state, from: nil, to: "draft")
#
def change_column_default: (untyped table_name, untyped column_name, untyped default_or_changes) -> untyped
# Sets or removes a NOT NULL constraint on a column. The +null+ flag
# indicates whether the value can be +NULL+. For example
#
# change_column_null(:users, :nickname, false)
#
# says nicknames cannot be +NULL+ (adds the constraint), whereas
#
# change_column_null(:users, :nickname, true)
#
# allows them to be +NULL+ (drops the constraint).
#
# The method accepts an optional fourth argument to replace existing
# NULLs with some other value. Use that one when enabling the
# constraint if needed, since otherwise those rows would not be valid.
#
# Please note the fourth argument does not set a column's default.
def change_column_null: (untyped table_name, untyped column_name, untyped null, ?untyped? default) -> untyped
# Renames a column.
#
# rename_column(:suppliers, :description, :name)
#
def rename_column: (untyped table_name, untyped column_name, untyped new_column_name) -> untyped
# Adds a new index to the table. +column_name+ can be a single Symbol, or
# an Array of Symbols.
#
# The index will be named after the table and the column name(s), unless
# you pass :name as an option.
#
# ====== Creating a simple index
#
# add_index(:suppliers, :name)
#
# generates:
#
# CREATE INDEX suppliers_name_index ON suppliers(name)
#
# ====== Creating a unique index
#
# add_index(:accounts, [:branch_id, :party_id], unique: true)
#
# generates:
#
# CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
#
# ====== Creating a named index
#
# add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
#
# generates:
#
# CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
#
# ====== Creating an index with specific key length
#
# add_index(:accounts, :name, name: 'by_name', length: 10)
#
# generates:
#
# CREATE INDEX by_name ON accounts(name(10))
#
# ====== Creating an index with specific key lengths for multiple keys
#
# add_index(:accounts, [:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
#
# generates:
#
# CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
#
# Note: SQLite doesn't support index length.
#
# ====== Creating an index with a sort order (desc or asc, asc is the default)
#
# add_index(:accounts, [:branch_id, :party_id, :surname], order: {branch_id: :desc, party_id: :asc})
#
# generates:
#
# CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
#
# Note: MySQL only supports index order from 8.0.1 onwards (earlier versions accepted the syntax but ignored it).
#
# ====== Creating a partial index
#
# add_index(:accounts, [:branch_id, :party_id], unique: true, where: "active")
#
# generates:
#
# CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
#
# Note: Partial indexes are only supported for PostgreSQL and SQLite 3.8.0+.
#
# ====== Creating an index with a specific method
#
# add_index(:developers, :name, using: 'btree')
#
# generates:
#
# CREATE INDEX index_developers_on_name ON developers USING btree (name) -- PostgreSQL
# CREATE INDEX index_developers_on_name USING btree ON developers (name) -- MySQL
#
# Note: only supported by PostgreSQL and MySQL
#
# ====== Creating an index with a specific operator class
#
# add_index(:developers, :name, using: 'gist', opclass: :gist_trgm_ops)
# # CREATE INDEX developers_on_name ON developers USING gist (name gist_trgm_ops) -- PostgreSQL
#
# add_index(:developers, [:name, :city], using: 'gist', opclass: { city: :gist_trgm_ops })
# # CREATE INDEX developers_on_name_and_city ON developers USING gist (name, city gist_trgm_ops) -- PostgreSQL
#
# add_index(:developers, [:name, :city], using: 'gist', opclass: :gist_trgm_ops)
# # CREATE INDEX developers_on_name_and_city ON developers USING gist (name gist_trgm_ops, city gist_trgm_ops) -- PostgreSQL
#
# Note: only supported by PostgreSQL
#
# ====== Creating an index with a specific type
#
# add_index(:developers, :name, type: :fulltext)
#
# generates:
#
# CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL
#
# Note: only supported by MySQL.
#
# ====== Creating an index with a specific algorithm
#
# add_index(:developers, :name, algorithm: :concurrently)
# # CREATE INDEX CONCURRENTLY developers_on_name on developers (name)
#
# Note: only supported by PostgreSQL.
#
# Concurrently adding an index is not supported in a transaction.
#
# For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
def add_index: (untyped table_name, untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
# Removes the given index from the table.
#
# Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
#
# remove_index :accounts, :branch_id
#
# Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
#
# remove_index :accounts, column: :branch_id
#
# Removes the index on +branch_id+ and +party_id+ in the +accounts+ table if exactly one such index exists.
#
# remove_index :accounts, column: [:branch_id, :party_id]
#
# Removes the index named +by_branch_party+ in the +accounts+ table.
#
# remove_index :accounts, name: :by_branch_party
#
# Removes the index named +by_branch_party+ in the +accounts+ table +concurrently+.
#
# remove_index :accounts, name: :by_branch_party, algorithm: :concurrently
#
# Note: only supported by PostgreSQL.
#
# Concurrently removing an index is not supported in a transaction.
#
# For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
def remove_index: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
# Renames an index.
#
# Rename the +index_people_on_last_name+ index to +index_users_on_last_name+:
#
# rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name'
#
def rename_index: (untyped table_name, untyped old_name, untyped new_name) -> (nil | untyped)
def index_name: (untyped table_name, untyped options) -> untyped
# Verifies the existence of an index with a given name.
def index_name_exists?: (untyped table_name, untyped index_name) -> untyped
# Adds a reference. The reference column is a bigint by default,
# the :type option can be used to specify a different type.
# Optionally adds a +_type+ column, if :polymorphic option is provided.
# #add_reference and #add_belongs_to are acceptable.
#
# The +options+ hash can include the following keys:
# [:type]
# The reference column type. Defaults to +:bigint+.
# [:index]
# Add an appropriate index. Defaults to true.
# See #add_index for usage of this option.
# [:foreign_key]
# Add an appropriate foreign key constraint. Defaults to false.
# [:polymorphic]
# Whether an additional +_type+ column should be added. Defaults to false.
# [:null]
# Whether the column allows nulls. Defaults to true.
#
# ====== Create a user_id bigint column without an index
#
# add_reference(:products, :user, index: false)
#
# ====== Create a user_id string column
#
# add_reference(:products, :user, type: :string)
#
# ====== Create supplier_id, supplier_type columns
#
# add_reference(:products, :supplier, polymorphic: true)
#
# ====== Create a supplier_id column with a unique index
#
# add_reference(:products, :supplier, index: { unique: true })
#
# ====== Create a supplier_id column with a named index
#
# add_reference(:products, :supplier, index: { name: "my_supplier_index" })
#
# ====== Create a supplier_id column and appropriate foreign key
#
# add_reference(:products, :supplier, foreign_key: true)
#
# ====== Create a supplier_id column and a foreign key to the firms table
#
# add_reference(:products, :supplier, foreign_key: {to_table: :firms})
#
def add_reference: (untyped table_name, untyped ref_name, **untyped options) -> untyped
# Removes the reference(s). Also removes a +type+ column if one exists.
# #remove_reference and #remove_belongs_to are acceptable.
#
# ====== Remove the reference
#
# remove_reference(:products, :user, index: false)
#
# ====== Remove polymorphic reference
#
# remove_reference(:products, :supplier, polymorphic: true)
#
# ====== Remove the reference with a foreign key
#
# remove_reference(:products, :user, foreign_key: true)
#
def remove_reference: (untyped table_name, untyped ref_name, ?polymorphic: bool polymorphic, ?foreign_key: bool foreign_key, **untyped options) -> untyped
# Returns an array of foreign keys for the given table.
# The foreign keys are represented as ForeignKeyDefinition objects.
def foreign_keys: (untyped table_name) -> untyped
# Adds a new foreign key. +from_table+ is the table with the key column,
# +to_table+ contains the referenced primary key.
#
# The foreign key will be named after the following pattern: fk_rails_.
# +identifier+ is a 10 character long string which is deterministically generated from the
# +from_table+ and +column+. A custom name can be specified with the :name option.
#
# ====== Creating a simple foreign key
#
# add_foreign_key :articles, :authors
#
# generates:
#
# ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id")
#
# ====== Creating a foreign key on a specific column
#
# add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"
#
# generates:
#
# ALTER TABLE "articles" ADD CONSTRAINT fk_rails_58ca3d3a82 FOREIGN KEY ("author_id") REFERENCES "users" ("lng_id")
#
# ====== Creating a cascading foreign key
#
# add_foreign_key :articles, :authors, on_delete: :cascade
#
# generates:
#
# ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id") ON DELETE CASCADE
#
# The +options+ hash can include the following keys:
# [:column]
# The foreign key column name on +from_table+. Defaults to to_table.singularize + "_id"
# [:primary_key]
# The primary key column name on +to_table+. Defaults to +id+.
# [:name]
# The constraint name. Defaults to fk_rails_.
# [:on_delete]
# Action that happens ON DELETE. Valid values are +:nullify+, +:cascade+ and +:restrict+
# [:on_update]
# Action that happens ON UPDATE. Valid values are +:nullify+, +:cascade+ and +:restrict+
# [:validate]
# (PostgreSQL only) Specify whether or not the constraint should be validated. Defaults to +true+.
def add_foreign_key: (untyped from_table, untyped to_table, **untyped options) -> (nil | untyped)
# Removes the given foreign key from the table. Any option parameters provided
# will be used to re-add the foreign key in case of a migration rollback.
# It is recommended that you provide any options used when creating the foreign
# key so that the migration can be reverted properly.
#
# Removes the foreign key on +accounts.branch_id+.
#
# remove_foreign_key :accounts, :branches
#
# Removes the foreign key on +accounts.owner_id+.
#
# remove_foreign_key :accounts, column: :owner_id
#
# Removes the foreign key on +accounts.owner_id+.
#
# remove_foreign_key :accounts, to_table: :owners
#
# Removes the foreign key named +special_fk_name+ on the +accounts+ table.
#
# remove_foreign_key :accounts, name: :special_fk_name
#
# The +options+ hash accepts the same keys as SchemaStatements#add_foreign_key
# with an addition of
# [:to_table]
# The name of the table that contains the referenced primary key.
def remove_foreign_key: (untyped from_table, ?untyped? to_table, **untyped options) -> (nil | untyped)
# Checks to see if a foreign key exists on a table for a given foreign key definition.
#
# # Checks to see if a foreign key exists.
# foreign_key_exists?(:accounts, :branches)
#
# # Checks to see if a foreign key on a specified column exists.
# foreign_key_exists?(:accounts, column: :owner_id)
#
# # Checks to see if a foreign key with a custom name exists.
# foreign_key_exists?(:accounts, name: "special_fk_name")
#
def foreign_key_exists?: (untyped from_table, ?untyped? to_table, **untyped options) -> untyped
def foreign_key_column_for: (untyped table_name) -> ::String
def foreign_key_options: (untyped from_table, untyped to_table, untyped options) -> untyped
def dump_schema_information: () -> untyped
def internal_string_options_for_primary_key: () -> { primary_key: ::TrueClass }
def assume_migrated_upto_version: (untyped version, ?untyped? migrations_paths) -> untyped
def type_to_sql: (untyped `type`, ?scale: untyped? scale, ?precision: untyped? precision, ?limit: untyped? limit) -> untyped
def columns_for_distinct: (untyped columns, untyped orders) -> untyped
# Adds timestamps (+created_at+ and +updated_at+) columns to +table_name+.
# Additional options (like +:null+) are forwarded to #add_column.
#
# add_timestamps(:suppliers, null: true)
#
def add_timestamps: (untyped table_name, **untyped options) -> untyped
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table definition.
#
# remove_timestamps(:suppliers)
#
def remove_timestamps: (untyped table_name, **untyped options) -> untyped
def update_table_definition: (untyped table_name, untyped base) -> Table
def add_index_options: (untyped table_name, untyped column_name, ?comment: untyped? comment, **untyped options) -> ::Array[untyped]
def options_include_default?: (untyped options) -> untyped
# Changes the comment for a table or removes it if +nil+.
#
# Passing a hash containing +:from+ and +:to+ will make this change
# reversible in migration:
#
# change_table_comment(:posts, from: "old_comment", to: "new_comment")
def change_table_comment: (untyped table_name, untyped comment_or_changes) -> untyped
# Changes the comment for a column or removes it if +nil+.
#
# Passing a hash containing +:from+ and +:to+ will make this change
# reversible in migration:
#
# change_column_comment(:posts, :state, from: "old_comment", to: "new_comment")
def change_column_comment: (untyped table_name, untyped column_name, untyped comment_or_changes) -> untyped
def create_schema_dumper: (untyped options) -> untyped
def column_options_keys: () -> ::Array[:limit | :precision | :scale | :default | :null | :collation | :comment]
def add_index_sort_order: (untyped quoted_columns, **untyped options) -> untyped
def options_for_index_columns: (untyped options) -> untyped
# Overridden by the MySQL adapter for supporting index lengths and by
# the PostgreSQL adapter for supporting operator classes.
def add_options_for_index_columns: (untyped quoted_columns, **untyped options) -> untyped
def quoted_columns_for_index: (untyped column_names, **untyped options) -> (::Array[untyped] | untyped)
def index_name_for_remove: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
def rename_table_indexes: (untyped table_name, untyped new_name) -> untyped
def rename_column_indexes: (untyped table_name, untyped column_name, untyped new_column_name) -> untyped
def schema_creation: () -> untyped
def create_table_definition: (*untyped args, **untyped options) -> TableDefinition
def create_alter_table: (untyped name) -> AlterTable
def fetch_type_metadata: (untyped sql_type) -> SqlTypeMetadata
def index_column_names: (untyped column_names) -> untyped
def index_name_options: (untyped column_names) -> { column: untyped }
def strip_table_name_prefix_and_suffix: (untyped table_name) -> untyped
def foreign_key_name: (untyped table_name, untyped options) -> untyped
def foreign_key_for: (untyped from_table, **untyped options) -> (nil | untyped)
def foreign_key_for!: (untyped from_table, ?to_table: untyped? to_table, **untyped options) -> untyped
def extract_foreign_key_action: (untyped specifier) -> untyped
def validate_index_length!: (untyped table_name, untyped new_name, ?bool internal) -> untyped
def extract_new_default_value: (untyped default_or_changes) -> untyped
def can_remove_index_by_name?: (untyped options) -> untyped
def bulk_change_table: (untyped table_name, untyped operations) -> untyped
def add_column_for_alter: (untyped table_name, untyped column_name, untyped `type`, **untyped options) -> untyped
def remove_column_for_alter: (untyped table_name, untyped column_name, ?untyped? `type`, **untyped options) -> ::String
def remove_columns_for_alter: (untyped table_name, *untyped column_names, **untyped options) -> untyped
def add_timestamps_for_alter: (untyped table_name, **untyped options) -> ::Array[untyped]
def remove_timestamps_for_alter: (untyped table_name, **untyped options) -> untyped
def insert_versions_sql: (untyped versions) -> untyped
def data_source_sql: (?untyped? name, ?type: untyped? `type`) -> untyped
def quoted_scope: (?untyped? name, ?type: untyped? `type`) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
class TransactionState
def initialize: (?untyped? state) -> untyped
def add_child: (untyped state) -> untyped
def finalized?: () -> untyped
def committed?: () -> untyped
def fully_committed?: () -> untyped
def rolledback?: () -> untyped
def fully_rolledback?: () -> untyped
def fully_completed?: () -> untyped
def completed?: () -> untyped
def rollback!: () -> untyped
def full_rollback!: () -> untyped
def commit!: () -> untyped
def full_commit!: () -> untyped
def nullify!: () -> untyped
end
class NullTransaction
# nodoc:
def initialize: () -> nil
def state: () -> nil
def closed?: () -> ::TrueClass
def open?: () -> ::FalseClass
def joinable?: () -> ::FalseClass
def add_record: (untyped record) -> nil
end
class Transaction
# nodoc:
attr_reader connection: untyped
# nodoc:
attr_reader state: untyped
# nodoc:
attr_reader records: untyped
# nodoc:
attr_reader savepoint_name: untyped
# nodoc:
attr_reader isolation_level: untyped
def initialize: (untyped connection, untyped options, ?run_commit_callbacks: bool run_commit_callbacks) -> untyped
def add_record: (untyped record) -> untyped
def materialize!: () -> untyped
def materialized?: () -> untyped
def rollback_records: () -> untyped
def before_commit_records: () -> untyped
def commit_records: () -> untyped
def full_rollback?: () -> ::TrueClass
def joinable?: () -> untyped
def closed?: () -> ::FalseClass
def open?: () -> untyped
end
class SavepointTransaction < Transaction
def initialize: (untyped connection, untyped savepoint_name, untyped parent_transaction, *untyped args, **untyped options) -> untyped
def materialize!: () -> untyped
def rollback: () -> untyped
def commit: () -> untyped
def full_rollback?: () -> ::FalseClass
end
class RealTransaction < Transaction
def materialize!: () -> untyped
def rollback: () -> untyped
def commit: () -> untyped
end
class TransactionManager
# nodoc:
def initialize: (untyped connection) -> untyped
def begin_transaction: (?::Hash[untyped, untyped] options) -> untyped
def disable_lazy_transactions!: () -> untyped
def enable_lazy_transactions!: () -> untyped
def lazy_transactions_enabled?: () -> untyped
def materialize_transactions: () -> (nil | untyped)
def commit_transaction: () -> untyped
def rollback_transaction: (?untyped? transaction) -> untyped
def within_new_transaction: (?::Hash[untyped, untyped] options) { () -> untyped } -> untyped
def open_transactions: () -> untyped
def current_transaction: () -> untyped
NULL_TRANSACTION: untyped
# Deallocate invalidated prepared statements outside of the transaction
def after_failure_actions: (untyped transaction, untyped error) -> (nil | untyped)
end
end
end
module ActiveRecord
# :stopdoc:
module ConnectionAdapters
# An abstract definition of a column in a table.
class Column
attr_reader name: untyped
attr_reader default: untyped
attr_reader sql_type_metadata: untyped
attr_reader null: untyped
attr_reader default_function: untyped
attr_reader collation: untyped
attr_reader comment: untyped
# Instantiates a new column in the table.
#
# +name+ is the column's name, such as supplier_id in supplier_id bigint.
# +default+ is the type-casted default value, such as +new+ in sales_stage varchar(20) default 'new'.
# +sql_type_metadata+ is various information about the type of the column
# +null+ determines if this column allows +NULL+ values.
def initialize: (untyped name, untyped default, ?untyped? sql_type_metadata, ?bool null, ?untyped? default_function, ?comment: untyped? comment, ?collation: untyped? collation) -> untyped
def has_default?: () -> untyped
def bigint?: () -> untyped
# Returns the human name of the column name.
#
# ===== Examples
# Column.new('sales_stage', ...).human_name # => 'Sales stage'
def human_name: () -> untyped
def init_with: (untyped coder) -> untyped
def encode_with: (untyped coder) -> untyped
def ==: (untyped other) -> untyped
def hash: () -> untyped
end
class NullColumn < Column
def initialize: (untyped name) -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
class ConnectionSpecification
# nodoc:
attr_reader name: untyped
# nodoc:
attr_reader config: untyped
# nodoc:
attr_reader adapter_method: untyped
def initialize: (untyped name, untyped config, untyped adapter_method) -> untyped
def initialize_dup: (untyped original) -> untyped
def to_hash: () -> untyped
class ConnectionUrlResolver
# Expands a connection string into a hash.
# :nodoc:
# == Example
#
# url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000"
# ConnectionUrlResolver.new(url).to_hash
# # => {
# "adapter" => "postgresql",
# "host" => "localhost",
# "port" => 9000,
# "database" => "foo_test",
# "username" => "foo",
# "password" => "bar",
# "pool" => "5",
# "timeout" => "3000"
# }
def initialize: (untyped url) -> untyped
# Converts the given URL to a full connection hash.
def to_hash: () -> untyped
attr_reader uri: untyped
def uri_parser: () -> untyped
# Converts the query parameters of the URI into a hash.
#
# "localhost?pool=5&reaping_frequency=2"
# # => { "pool" => "5", "reaping_frequency" => "2" }
#
# returns empty hash if no query present.
#
# "localhost"
# # => {}
def query_hash: () -> untyped
def raw_config: () -> untyped
# Returns name of the database.
def database_from_path: () -> untyped
end
class Resolver
#
# Builds a ConnectionSpecification from user input.
# :nodoc:
attr_reader configurations: untyped
# Accepts a list of db config objects.
def initialize: (untyped configurations) -> untyped
# Returns a hash with database connection information.
#
# == Examples
#
# Full hash Configuration.
#
# configurations = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } }
# Resolver.new(configurations).resolve(:production)
# # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3"}
#
# Initialized with URL configuration strings.
#
# configurations = { "production" => "postgresql://localhost/foo" }
# Resolver.new(configurations).resolve(:production)
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
#
def resolve: (untyped config_or_env, ?untyped? pool_name) -> untyped
# Returns an instance of ConnectionSpecification for a given adapter.
# Accepts a hash one layer deep that contains all connection information.
#
# == Example
#
# config = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } }
# spec = Resolver.new(config).spec(:production)
# spec.adapter_method
# # => "sqlite3_connection"
# spec.config
# # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" }
#
def spec: (untyped config) -> ConnectionSpecification
# Returns fully resolved connection, accepts hash, string or symbol.
# Always returns a hash.
#
# == Examples
#
# Symbol representing current environment.
#
# Resolver.new("production" => {}).resolve_connection(:production)
# # => {}
#
# One layer deep hash of connection values.
#
# Resolver.new({}).resolve_connection("adapter" => "sqlite3")
# # => { "adapter" => "sqlite3" }
#
# Connection URL.
#
# Resolver.new({}).resolve_connection("postgresql://localhost/foo")
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
#
def resolve_connection: (untyped config_or_env, ?untyped? pool_name) -> untyped
# Takes the environment such as +:production+ or +:development+ and a
# pool name the corresponds to the name given by the connection pool
# to the connection. That pool name is merged into the hash with the
# name key.
#
# This requires that the @configurations was initialized with a key that
# matches.
#
# configurations = #"my_db"}>
# ]>
#
# Resolver.new(configurations).resolve_symbol_connection(:production, "primary")
# # => { "database" => "my_db" }
def resolve_symbol_connection: (untyped env_name, untyped pool_name) -> untyped
def build_configuration_sentence: () -> untyped
# Accepts a hash. Expands the "url" key that contains a
# URL database connection to a full connection
# hash and merges with the rest of the hash.
# Connection details inside of the "url" key win any merge conflicts
def resolve_hash_connection: (untyped spec) -> untyped
# Takes a connection URL.
#
# Resolver.new({}).resolve_url_connection("postgresql://localhost/foo")
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
#
def resolve_url_connection: (untyped url) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module DetermineIfPreparableVisitor
attr_accessor preparable: untyped
def accept: (untyped object, untyped collector) -> untyped
def visit_Arel_Nodes_In: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_NotIn: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SqlLiteral: (untyped o, untyped collector) -> untyped
end
end
end
module ActiveRecord
module ConnectionHandling
# :nodoc:
ER_BAD_DB_ERROR: ::Integer
# Establishes a connection to the database that's used by all Active Record objects.
def mysql2_connection: (untyped config) -> untyped
end
module ConnectionAdapters
class Mysql2Adapter < AbstractMysqlAdapter
ADAPTER_NAME: ::String
include MySQL::DatabaseStatements
def initialize: (untyped connection, untyped logger, untyped connection_options, untyped config) -> untyped
def self.database_exists?: (untyped config) -> untyped
def supports_json?: () -> untyped
def supports_comments?: () -> ::TrueClass
def supports_comments_in_create?: () -> ::TrueClass
def supports_savepoints?: () -> ::TrueClass
def supports_lazy_transactions?: () -> ::TrueClass
def each_hash: (untyped result) { (untyped) -> untyped } -> untyped
def error_number: (untyped exception) -> untyped
def quote_string: (untyped string) -> untyped
def active?: () -> untyped
def reconnect!: () -> untyped
# Disconnects from the database if already connected.
# Otherwise, this method does nothing.
def disconnect!: () -> untyped
def discard!: () -> untyped
def connect: () -> untyped
def configure_connection: () -> untyped
def full_version: () -> untyped
def get_full_version: () -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
class Column < ConnectionAdapters::Column
def unsigned?: () -> untyped
def case_sensitive?: () -> untyped
def auto_increment?: () -> untyped
def virtual?: () -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
module DatabaseStatements
def select_all: () -> untyped
def query: (untyped sql, ?untyped? name) -> untyped
READ_QUERY: untyped
def write_query?: (untyped sql) -> untyped
# Executes the SQL statement in the context of this connection.
def execute: (untyped sql, ?untyped? name) -> untyped
def exec_query: (untyped sql, ?::String name, ?untyped binds, ?prepare: bool prepare) -> untyped
def exec_delete: (untyped sql, ?untyped? name, ?untyped binds) -> untyped
def execute_batch: (untyped statements, ?untyped? name) -> untyped
def default_insert_value: (untyped column) -> untyped
def last_inserted_id: (untyped result) -> untyped
def supports_set_server_option?: () -> untyped
def multi_statements_enabled?: (untyped flags) -> untyped
def with_multi_statements: () { () -> untyped } -> untyped
def combine_multi_statements: (untyped total_sql) -> untyped
def max_allowed_packet_reached?: (untyped current_packet, untyped previous_packet) -> untyped
def max_allowed_packet: () -> untyped
def exec_stmt_and_free: (untyped sql, untyped name, untyped binds, ?cache_stmt: bool cache_stmt) { (untyped, untyped) -> untyped } -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
class ExplainPrettyPrinter
# :nodoc:
# Pretty prints the result of an EXPLAIN in a way that resembles the output of the
# MySQL shell:
#
# +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
# | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
# +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
# | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
# | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
# +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
# 2 rows in set (0.00 sec)
#
# This is an exercise in Ruby hyperrealism :).
def pp: (untyped result, untyped elapsed) -> untyped
def compute_column_widths: (untyped result) -> untyped
def build_separator: (untyped widths) -> untyped
def build_cells: (untyped items, untyped widths) -> untyped
def build_footer: (untyped nrows, untyped elapsed) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
module Quoting
# :nodoc:
def quote_column_name: (untyped name) -> untyped
def quote_table_name: (untyped name) -> untyped
def unquoted_true: () -> 1
def unquoted_false: () -> 0
def quoted_date: (untyped value) -> untyped
def quoted_binary: (untyped value) -> ::String
def column_name_matcher: () -> untyped
def column_name_with_order_matcher: () -> untyped
COLUMN_NAME: untyped
COLUMN_NAME_WITH_ORDER: untyped
def _type_cast: (untyped value) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
class SchemaCreation < AbstractAdapter::SchemaCreation
def visit_DropForeignKey: (untyped name) -> ::String
def visit_AddColumnDefinition: (untyped o) -> untyped
def visit_ChangeColumnDefinition: (untyped o) -> untyped
def add_table_options!: (untyped create_sql, untyped options) -> untyped
def add_column_options!: (untyped sql, untyped options) -> untyped
def add_column_position!: (untyped sql, untyped options) -> untyped
def index_in_create: (untyped table_name, untyped column_name, untyped options) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
module ColumnMethods
extend ActiveSupport::Concern
end
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
include ColumnMethods
def new_column_definition: (untyped name, untyped `type`, **untyped options) -> untyped
def aliased_types: (untyped name, untyped fallback) -> untyped
def integer_like_primary_key_type: (untyped `type`, untyped options) -> untyped
end
class Table < ActiveRecord::ConnectionAdapters::Table
include ColumnMethods
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
class SchemaDumper < ConnectionAdapters::SchemaDumper
def prepare_column_options: (untyped column) -> untyped
def column_spec_for_primary_key: (untyped column) -> untyped
def default_primary_key?: (untyped column) -> untyped
def explicit_primary_key_default?: (untyped column) -> untyped
def schema_type: (untyped column) -> untyped
def schema_limit: (untyped column) -> untyped
def schema_precision: (untyped column) -> untyped
def schema_collation: (untyped column) -> untyped
def extract_expression_for_virtual_column: (untyped column) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
module SchemaStatements
# :nodoc:
# Returns an array of indexes for the given table.
def indexes: (untyped table_name) -> untyped
def remove_column: (untyped table_name, untyped column_name, ?untyped? `type`, **untyped options) -> untyped
def create_table: (untyped table_name, ?options: untyped options) -> untyped
def internal_string_options_for_primary_key: () -> untyped
def update_table_definition: (untyped table_name, untyped base) -> untyped
def create_schema_dumper: (untyped options) -> untyped
# Maps logical Rails types to MySQL-specific data types.
def type_to_sql: (untyped `type`, ?unsigned: untyped? unsigned, ?size: untyped size, ?scale: untyped? scale, ?precision: untyped? precision, ?limit: untyped? limit) -> untyped
def table_alias_length: () -> 256
CHARSETS_OF_4BYTES_MAXLEN: ::Array[untyped]
def row_format_dynamic_by_default?: () -> untyped
def default_row_format: () -> (nil | untyped)
def schema_creation: () -> MySQL::SchemaCreation
def create_table_definition: (*untyped args, **untyped options) -> MySQL::TableDefinition
def new_column_from_field: (untyped table_name, untyped field) -> MySQL::Column
def fetch_type_metadata: (untyped sql_type, ?::String extra) -> MySQL::TypeMetadata
def extract_foreign_key_action: (untyped specifier) -> untyped
def add_index_length: (untyped quoted_columns, **untyped options) -> untyped
def add_options_for_index_columns: (untyped quoted_columns, **untyped options) -> untyped
def data_source_sql: (?untyped? name, ?type: untyped? `type`) -> untyped
def quoted_scope: (?untyped? name, ?type: untyped? `type`) -> untyped
def extract_schema_qualified_name: (untyped string) -> ::Array[untyped]
def type_with_size_to_sql: (untyped `type`, untyped size) -> untyped
def limit_to_size: (untyped limit, untyped `type`) -> untyped
def integer_to_sql: (untyped limit) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module MySQL
# Note: It inherits unnamed class, but omitted
class TypeMetadata
attr_reader extra: untyped
def initialize: (untyped type_metadata, ?extra: ::String extra) -> untyped
def ==: (untyped other) -> untyped
def hash: () -> untyped
end
end
end
end
class ::PG::Connection
end
module ActiveRecord
module ConnectionHandling
# :nodoc:
# Establishes a connection to the database that's used by all Active Record objects
def postgresql_connection: (untyped config) -> untyped
end
module ConnectionAdapters
# The PostgreSQL adapter works with the native C (https://bitbucket.org/ged/ruby-pg) driver.
#
# Options:
#
# * :host - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets,
# the default is to connect to localhost.
# * :port - Defaults to 5432.
# * :username - Defaults to be the same as the operating system name of the user running the application.
# * :password - Password to be used if the server demands password authentication.
# * :database - Defaults to be the same as the user name.
# * :schema_search_path - An optional schema search path for the connection given
# as a string of comma-separated schema names. This is backward-compatible with the :schema_order option.
# * :encoding - An optional client encoding that is used in a SET client_encoding TO
# call on the connection.
# * :min_messages - An optional client min messages that is used in a
# SET client_min_messages TO call on the connection.
# * :variables - An optional hash of additional parameters that
# will be used in SET SESSION key = val calls on the connection.
# * :insert_returning - An optional boolean to control the use of RETURNING for INSERT statements
# defaults to true.
#
# Any further options are used as connection parameters to libpq. See
# https://www.postgresql.org/docs/current/static/libpq-connect.html for the
# list of parameters.
#
# In addition, default connection parameters of libpq can be set per environment variables.
# See https://www.postgresql.org/docs/current/static/libpq-envars.html .
class PostgreSQLAdapter < AbstractAdapter
ADAPTER_NAME: ::String
NATIVE_DATABASE_TYPES: ::Hash[untyped, untyped]
OID: untyped
include PostgreSQL::Quoting
include PostgreSQL::ReferentialIntegrity
include PostgreSQL::SchemaStatements
include PostgreSQL::DatabaseStatements
def supports_bulk_alter?: () -> ::TrueClass
def supports_index_sort_order?: () -> ::TrueClass
def supports_partitioned_indexes?: () -> untyped
def supports_partial_index?: () -> ::TrueClass
def supports_expression_index?: () -> ::TrueClass
def supports_transaction_isolation?: () -> ::TrueClass
def supports_foreign_keys?: () -> ::TrueClass
def supports_validate_constraints?: () -> ::TrueClass
def supports_views?: () -> ::TrueClass
def supports_datetime_with_precision?: () -> ::TrueClass
def supports_json?: () -> ::TrueClass
def supports_comments?: () -> ::TrueClass
def supports_savepoints?: () -> ::TrueClass
def supports_insert_returning?: () -> ::TrueClass
def supports_insert_on_conflict?: () -> untyped
def index_algorithms: () -> { concurrently: "CONCURRENTLY" }
class StatementPool < ConnectionAdapters::StatementPool
# :nodoc:
def initialize: (untyped connection, untyped max) -> untyped
def next_key: () -> ::String
def []=: (untyped sql, untyped key) -> untyped
def dealloc: (untyped key) -> untyped
def connection_active?: () -> untyped
end
# Initializes and connects a PostgreSQL adapter.
def initialize: (untyped connection, untyped logger, untyped connection_parameters, untyped config) -> untyped
def self.database_exists?: (untyped config) -> untyped
# Is this connection alive and ready for queries?
def active?: () -> untyped
# Close then reopen the connection.
def reconnect!: () -> untyped
def reset!: () -> untyped
# Disconnects from the database if already connected. Otherwise, this
# method does nothing.
def disconnect!: () -> untyped
def discard!: () -> untyped
def native_database_types: () -> untyped
def set_standard_conforming_strings: () -> untyped
def supports_ddl_transactions?: () -> ::TrueClass
def supports_advisory_locks?: () -> ::TrueClass
def supports_explain?: () -> ::TrueClass
def supports_extensions?: () -> ::TrueClass
def supports_ranges?: () -> ::TrueClass
def supports_materialized_views?: () -> ::TrueClass
def supports_foreign_tables?: () -> ::TrueClass
def supports_pgcrypto_uuid?: () -> untyped
def supports_optimizer_hints?: () -> untyped
def supports_common_table_expressions?: () -> ::TrueClass
def supports_lazy_transactions?: () -> ::TrueClass
def get_advisory_lock: (untyped lock_id) -> untyped
def release_advisory_lock: (untyped lock_id) -> untyped
def enable_extension: (untyped name) -> untyped
def disable_extension: (untyped name) -> untyped
def extension_available?: (untyped name) -> untyped
def extension_enabled?: (untyped name) -> untyped
def extensions: () -> untyped
# Returns the configured supported identifier length supported by PostgreSQL
def max_identifier_length: () -> untyped
# Set the authorized user for this session
def session_auth=: (untyped user) -> untyped
def use_insert_returning?: () -> untyped
def column_name_for_operation: (untyped operation, untyped node) -> untyped
OPERATION_ALIASES: ::Hash[untyped, untyped]
def get_database_version: () -> untyped
def default_index_type?: (untyped index) -> untyped
def build_insert_sql: (untyped insert) -> untyped
def check_version: () -> untyped
# See https://www.postgresql.org/docs/current/static/errcodes-appendix.html
VALUE_LIMIT_VIOLATION: ::String
NUMERIC_VALUE_OUT_OF_RANGE: ::String
NOT_NULL_VIOLATION: ::String
FOREIGN_KEY_VIOLATION: ::String
UNIQUE_VIOLATION: ::String
SERIALIZATION_FAILURE: ::String
DEADLOCK_DETECTED: ::String
LOCK_NOT_AVAILABLE: ::String
QUERY_CANCELED: ::String
def translate_exception: (untyped exception, binds: untyped binds, sql: untyped sql, message: untyped message) -> untyped
def get_oid_type: (untyped oid, untyped fmod, untyped column_name, ?::String sql_type) -> untyped
def initialize_type_map: (?untyped m) -> untyped
# Extracts the value from a PostgreSQL column default definition.
def extract_value_from_default: (untyped default) -> untyped
def extract_default_function: (untyped default_value, untyped default) -> untyped
def has_default_function?: (untyped default_value, untyped default) -> untyped
def load_additional_types: (?untyped? oids) -> untyped
FEATURE_NOT_SUPPORTED: ::String
def execute_and_clear: (untyped sql, untyped name, untyped binds, ?prepare: bool prepare) { (untyped) -> untyped } -> untyped
def exec_no_cache: (untyped sql, untyped name, untyped binds) -> untyped
def exec_cache: (untyped sql, untyped name, untyped binds) -> untyped
# Annoyingly, the code for prepared statements whose return value may
# have changed is FEATURE_NOT_SUPPORTED.
#
# This covers various different error types so we need to do additional
# work to classify the exception definitively as a
# ActiveRecord::PreparedStatementCacheExpired
#
# Check here for more details:
# https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
CACHED_PLAN_HEURISTIC: ::String
def is_cached_plan_failure?: (untyped e) -> untyped
def in_transaction?: () -> untyped
# Returns the statement identifier for the client side cache
# of statements
def sql_key: (untyped sql) -> ::String
# Prepare the statement if it hasn't been prepared, return
# the statement key.
def prepare_statement: (untyped sql, untyped binds) -> untyped
# Connects to a PostgreSQL server and sets up the adapter depending on the
# connected server's characteristics.
def connect: () -> untyped
# Configures the encoding, verbosity, schema search path, and time zone of the connection.
# This is called by #connect and should not be called manually.
def configure_connection: () -> untyped
# Returns the list of a table's column names, data types, and default values.
#
# The underlying query is roughly:
# SELECT column.name, column.type, default.value, column.comment
# FROM column LEFT JOIN default
# ON column.table_id = default.table_id
# AND column.num = default.column_num
# WHERE column.table_id = get_table_id('table_name')
# AND column.num > 0
# AND NOT column.is_dropped
# ORDER BY column.num
#
# If the table name is not prefixed with a schema, the database will
# take the first match from the schema search path.
#
# Query implementation notes:
# - format_type includes the column size constraint, e.g. varchar(50)
# - ::regclass is a function that gives the id for a table name
def column_definitions: (untyped table_name) -> untyped
def extract_table_ref_from_insert_sql: (untyped sql) -> untyped
def arel_visitor: () -> Arel::Visitors::PostgreSQL
def build_statement_pool: () -> StatementPool
def can_perform_case_insensitive_comparison_for?: (untyped column) -> untyped
def add_pg_encoders: () -> untyped
def update_typemap_for_default_timezone: () -> untyped
def add_pg_decoders: () -> untyped
def construct_coder: (untyped row, untyped coder_class) -> (nil | untyped)
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
class Column < ConnectionAdapters::Column
def initialize: (?serial: untyped? serial) -> untyped
def serial?: () -> untyped
def array: () -> untyped
def sql_type: () -> untyped
end
end
PostgreSQLColumn: untyped
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module DatabaseStatements
def explain: (untyped arel, ?untyped binds) -> untyped
MONEY_COLUMN_TYPE_OID: ::Integer
BYTEA_COLUMN_TYPE_OID: ::Integer
def result_as_array: (untyped res) -> untyped
def query: (untyped sql, ?untyped? name) -> untyped
READ_QUERY: untyped
def write_query?: (untyped sql) -> untyped
# Executes an SQL statement, returning a PG::Result object on success
# or raising a PG::Error exception otherwise.
# Note: the PG::Result object is manually memory managed; if you don't
# need it specifically, you may want consider the exec_query wrapper.
def execute: (untyped sql, ?untyped? name) -> untyped
def exec_query: (untyped sql, ?::String name, ?untyped binds, ?prepare: bool prepare) -> untyped
def exec_delete: (untyped sql, ?untyped? name, ?untyped binds) -> untyped
def sql_for_insert: (untyped sql, untyped pk, untyped binds) -> untyped
def exec_insert: (untyped sql, ?untyped? name, ?untyped binds, ?untyped? pk, ?untyped? sequence_name) -> untyped
# Begins a transaction.
def begin_db_transaction: () -> untyped
def begin_isolated_db_transaction: (untyped isolation) -> untyped
# Commits a transaction.
def commit_db_transaction: () -> untyped
# Aborts a transaction.
def exec_rollback_db_transaction: () -> untyped
def execute_batch: (untyped statements, ?untyped? name) -> untyped
def build_truncate_statements: (untyped table_names) -> ::Array[::String]
# Returns the current ID of a table's sequence.
def last_insert_id_result: (untyped sequence_name) -> untyped
def suppress_composite_primary_key: (untyped pk) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
class ExplainPrettyPrinter
# :nodoc:
# Pretty prints the result of an EXPLAIN in a way that resembles the output of the
# PostgreSQL shell:
#
# QUERY PLAN
# ------------------------------------------------------------------------------
# Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
# Join Filter: (posts.user_id = users.id)
# -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
# Index Cond: (id = 1)
# -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
# Filter: (posts.user_id = 1)
# (6 rows)
#
def pp: (untyped result) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Array[unchecked out Elem] < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
include ActiveModel::Type::Helpers::Mutable
class Data < ::Struct[untyped]
attr_accessor encoder(): untyped
attr_accessor values(): untyped
end
attr_reader subtype: untyped
attr_reader delimiter: untyped
def initialize: (untyped subtype, ?::String delimiter) -> untyped
def deserialize: (untyped value) -> untyped
def cast: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
def ==: (untyped other) -> untyped
def type_cast_for_schema: (untyped value) -> untyped
def map: (untyped value) { () -> untyped } -> untyped
def changed_in_place?: (untyped raw_old_value, untyped new_value) -> untyped
def force_equality?: (untyped value) -> untyped
def type_cast_array: (untyped value, untyped method) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Bit < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
def `type`: () -> :bit
def cast_value: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
class Data
def initialize: (untyped value) -> untyped
def to_s: () -> untyped
def binary?: () -> untyped
def hex?: () -> untyped
attr_reader value: untyped
end
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class BitVarying < OID::Bit
# :nodoc:
# :nodoc:
def `type`: () -> :bit_varying
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Bytea < ActiveModel::Type::Binary
# :nodoc:
# :nodoc:
def deserialize: (untyped value) -> (nil | untyped)
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Cidr < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
def `type`: () -> :cidr
def type_cast_for_schema: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
def cast_value: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Date < Type::Date
# :nodoc:
# :nodoc:
def cast_value: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class DateTime < Type::DateTime
# :nodoc:
# :nodoc:
def cast_value: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Decimal < ActiveModel::Type::Decimal
# :nodoc:
# :nodoc:
def infinity: (?::Hash[untyped, untyped] options) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Enum < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
def `type`: () -> :enum
def cast_value: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Hstore < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
include ActiveModel::Type::Helpers::Mutable
def `type`: () -> :hstore
def deserialize: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
def accessor: () -> untyped
# Will compare the Hash equivalents of +raw_old_value+ and +new_value+.
# By comparing hashes, this avoids an edge case where the order of
# the keys change between the two hashes, and they would not be marked
# as equal.
def changed_in_place?: (untyped raw_old_value, untyped new_value) -> untyped
HstorePair: untyped
def escape_hstore: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Inet < Cidr
# :nodoc:
# :nodoc:
def `type`: () -> :inet
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Jsonb < Type::Json
# :nodoc:
# :nodoc:
def `type`: () -> :jsonb
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class LegacyPoint < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
include ActiveModel::Type::Helpers::Mutable
def `type`: () -> :point
def cast: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
def number_for_point: (untyped number) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Money < ActiveModel::Type::Decimal
# :nodoc:
# :nodoc:
def `type`: () -> :money
def scale: () -> 2
def cast_value: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Oid < Type::UnsignedInteger
# :nodoc:
# :nodoc:
def `type`: () -> :oid
end
end
end
end
end
module ActiveRecord
class Point < ::Struct[untyped]
attr_accessor x(): untyped
attr_accessor y(): untyped
end
module ConnectionAdapters
module PostgreSQL
module OID
class Point < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
include ActiveModel::Type::Helpers::Mutable
def `type`: () -> :point
def cast: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
def type_cast_for_schema: (untyped value) -> untyped
def number_for_point: (untyped number) -> untyped
def build_point: (untyped x, untyped y) -> ActiveRecord::Point
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Range[Elem] < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
attr_reader subtype: untyped
# :nodoc:
# :nodoc:
attr_reader type: untyped
def initialize: (untyped subtype, ?::Symbol `type`) -> untyped
def type_cast_for_schema: (untyped value) -> untyped
def cast_value: (untyped value) -> (nil | untyped)
def serialize: (untyped value) -> untyped
def ==: (untyped other) -> untyped
def map: (untyped value) { (untyped) -> untyped } -> untyped
def force_equality?: (untyped value) -> untyped
def type_cast_single: (untyped value) -> untyped
def type_cast_single_for_database: (untyped value) -> untyped
def extract_bounds: (untyped value) -> { from: untyped, to: untyped, exclude_start: untyped, :exclude_end => untyped }
def infinity: (?negative: bool negative) -> untyped
def infinity?: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class SpecializedString < ActiveModel::Type::String
# :nodoc:
# :nodoc:
attr_reader type: untyped
def initialize: (untyped `type`, **untyped options) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class TypeMapInitializer
# :nodoc:
# This class uses the data from PostgreSQL pg_type table to build
# the OID -> Type mapping.
# - OID is an integer representing the type.
# - Type is an OID::Type object.
# This class has side effects on the +store+ passed during initialization.
# :nodoc:
def initialize: (untyped store) -> untyped
def run: (untyped records) -> untyped
def query_conditions_for_initial_load: () -> untyped
def register_mapped_type: (untyped row) -> untyped
def register_enum_type: (untyped row) -> untyped
def register_array_type: (untyped row) -> untyped
def register_range_type: (untyped row) -> untyped
def register_domain_type: (untyped row) -> untyped
def register_composite_type: (untyped row) -> untyped
def register: (untyped oid, ?untyped? oid_type) { () -> untyped } -> untyped
def alias_type: (untyped oid, untyped target) -> untyped
def register_with_subtype: (untyped oid, untyped target_oid) { (untyped) -> untyped } -> untyped
def assert_valid_registration: (untyped oid, untyped oid_type) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Uuid < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
ACCEPTABLE_UUID: untyped
def `type`: () -> :uuid
def cast_value: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Vector < ActiveModel::Type::Value
# :nodoc:
# :nodoc:
attr_reader delim: untyped
# :nodoc:
# :nodoc:
attr_reader subtype: untyped
# +delim+ corresponds to the `typdelim` column in the pg_types
# table. +subtype+ is derived from the `typelem` column in the
# pg_types table.
def initialize: (untyped delim, untyped subtype) -> untyped
# FIXME: this should probably split on +delim+ and use +subtype+
# to cast the values. Unfortunately, the current Rails behavior
# is to just return the string.
def cast: (untyped value) -> untyped
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID
class Xml < ActiveModel::Type::String
# :nodoc:
# :nodoc:
def `type`: () -> :xml
def serialize: (untyped value) -> (nil | Data)
class Data
# :nodoc:
def initialize: (untyped value) -> untyped
def to_s: () -> untyped
end
end
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module Quoting
# Escapes binary strings for bytea input to the database.
def escape_bytea: (untyped value) -> untyped
# Unescapes bytea output from a database to the binary string it represents.
# NOTE: This is NOT an inverse of escape_bytea! This is only to be used
# on escaped binary output from database drive.
def unescape_bytea: (untyped value) -> untyped
def quote_string: (untyped s) -> untyped
def quote_table_name: (untyped name) -> untyped
# Quotes schema names for use in SQL queries.
def quote_schema_name: (untyped name) -> untyped
def quote_table_name_for_assignment: (untyped table, untyped attr) -> untyped
def quote_column_name: (untyped name) -> untyped
def quoted_date: (untyped value) -> untyped
def quoted_binary: (untyped value) -> ::String
def quote_default_expression: (untyped value, untyped column) -> untyped
def lookup_cast_type_from_column: (untyped column) -> untyped
def column_name_matcher: () -> untyped
def column_name_with_order_matcher: () -> untyped
COLUMN_NAME: untyped
COLUMN_NAME_WITH_ORDER: untyped
def lookup_cast_type: (untyped sql_type) -> untyped
def _quote: (untyped value) -> untyped
def _type_cast: (untyped value) -> untyped
def encode_array: (untyped array_data) -> untyped
def encode_range: (untyped range) -> ::String
def determine_encoding_of_strings_in_array: (untyped value) -> untyped
def type_cast_array: (untyped values) -> untyped
def type_cast_range_value: (untyped value) -> untyped
def infinity?: (untyped value) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module ReferentialIntegrity
def disable_referential_integrity: () { () -> untyped } -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
class SchemaCreation < AbstractAdapter::SchemaCreation
def visit_AlterTable: (untyped o) -> untyped
def visit_AddForeignKey: (untyped o) -> untyped
def visit_ValidateConstraint: (untyped name) -> ::String
def visit_ChangeColumnDefinition: (untyped o) -> untyped
def add_column_options!: (untyped sql, untyped options) -> untyped
# Returns any SQL string to go between CREATE and TABLE. May be nil.
def table_modifier_in_create: (untyped o) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module ColumnMethods
extend ActiveSupport::Concern
# Defines the primary key field.
# Use of the native PostgreSQL UUID type is supported, and can be used
# by defining your tables as such:
#
# create_table :stuffs, id: :uuid do |t|
# t.string :content
# t.timestamps
# end
#
# By default, this will use the gen_random_uuid() function from the
# +pgcrypto+ extension. As that extension is only available in
# PostgreSQL 9.4+, for earlier versions an explicit default can be set
# to use uuid_generate_v4() from the +uuid-ossp+ extension instead:
#
# create_table :stuffs, id: false do |t|
# t.primary_key :id, :uuid, default: "uuid_generate_v4()"
# t.uuid :foo_id
# t.timestamps
# end
#
# To enable the appropriate extension, which is a requirement, use
# the +enable_extension+ method in your migrations.
#
# To use a UUID primary key without any of the extensions, set the
# +:default+ option to +nil+:
#
# create_table :stuffs, id: false do |t|
# t.primary_key :id, :uuid, default: nil
# t.uuid :foo_id
# t.timestamps
# end
#
# You may also pass a custom stored procedure that returns a UUID or use a
# different UUID generation function from another library.
#
# Note that setting the UUID primary key default value to +nil+ will
# require you to assure that you always provide a UUID value before saving
# a record (as primary keys cannot be +nil+). This might be done via the
# +SecureRandom.uuid+ method and a +before_save+ callback, for instance.
def primary_key: (untyped name, ?::Symbol `type`, **untyped options) -> untyped
end
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
include ColumnMethods
attr_reader unlogged: untyped
def initialize: () -> untyped
def integer_like_primary_key_type: (untyped `type`, untyped options) -> untyped
end
class Table < ActiveRecord::ConnectionAdapters::Table
include ColumnMethods
end
class AlterTable < ActiveRecord::ConnectionAdapters::AlterTable
attr_reader constraint_validations: untyped
def initialize: (untyped td) -> untyped
def validate_constraint: (untyped name) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
class SchemaDumper < ConnectionAdapters::SchemaDumper
def extensions: (untyped stream) -> untyped
def prepare_column_options: (untyped column) -> untyped
def default_primary_key?: (untyped column) -> untyped
def explicit_primary_key_default?: (untyped column) -> untyped
def schema_type: (untyped column) -> untyped
def schema_expression: (untyped column) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module SchemaStatements
def recreate_database: (untyped name, ?::Hash[untyped, untyped] options) -> untyped
# Create a new PostgreSQL database. Options include :owner, :template,
# :encoding (defaults to utf8), :collation, :ctype,
# :tablespace, and :connection_limit (note that MySQL uses
# :charset while PostgreSQL uses :encoding).
#
# Example:
# create_database config[:database], config
# create_database 'foo_development', encoding: 'unicode'
def create_database: (untyped name, ?::Hash[untyped, untyped] options) -> untyped
def drop_database: (untyped name) -> untyped
def drop_table: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
# Returns true if schema exists.
def schema_exists?: (untyped name) -> untyped
# Verifies existence of an index with a given name.
def index_name_exists?: (untyped table_name, untyped index_name) -> untyped
def indexes: (untyped table_name) -> untyped
def table_options: (untyped table_name) -> untyped
def table_comment: (untyped table_name) -> untyped
# Returns the current database name.
def current_database: () -> untyped
# Returns the current schema name.
def current_schema: () -> untyped
# Returns the current database encoding format.
def encoding: () -> untyped
# Returns the current database collation.
def collation: () -> untyped
# Returns the current database ctype.
def ctype: () -> untyped
# Returns an array of schema names.
def schema_names: () -> untyped
# Creates a schema for the given schema name.
def create_schema: (untyped schema_name) -> untyped
# Drops the schema for the given schema name.
def drop_schema: (untyped schema_name, ?::Hash[untyped, untyped] options) -> untyped
# Sets the schema search path to a string of comma-separated schema names.
# Names beginning with $ have to be quoted (e.g. $user => '$user').
# See: https://www.postgresql.org/docs/current/static/ddl-schemas.html
#
# This should be not be called manually but set in database.yml.
def schema_search_path=: (untyped schema_csv) -> untyped
# Returns the active schema search path.
def schema_search_path: () -> untyped
# Returns the current client message level.
def client_min_messages: () -> untyped
# Set the client message level.
def client_min_messages=: (untyped level) -> untyped
def default_sequence_name: (untyped table_name, ?::String pk) -> untyped
def serial_sequence: (untyped table, untyped column) -> untyped
def set_pk_sequence!: (untyped table, untyped value) -> untyped
def reset_pk_sequence!: (untyped table, ?untyped? pk, ?untyped? sequence) -> untyped
def pk_and_sequence_for: (untyped table) -> untyped
def primary_keys: (untyped table_name) -> untyped
# Renames a table.
# Also renames a table's primary key sequence if the sequence name exists and
# matches the Active Record default.
#
# Example:
# rename_table('octopuses', 'octopi')
def rename_table: (untyped table_name, untyped new_name) -> untyped
def add_column: (untyped table_name, untyped column_name, untyped `type`, **untyped options) -> untyped
def change_column: (untyped table_name, untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
def change_column_default: (untyped table_name, untyped column_name, untyped default_or_changes) -> untyped
def change_column_null: (untyped table_name, untyped column_name, untyped null, ?untyped? default) -> untyped
def change_column_comment: (untyped table_name, untyped column_name, untyped comment_or_changes) -> untyped
def change_table_comment: (untyped table_name, untyped comment_or_changes) -> untyped
def rename_column: (untyped table_name, untyped column_name, untyped new_column_name) -> untyped
def add_index: (untyped table_name, untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
def remove_index: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
# Renames an index of a table. Raises error if length of new
# index name is greater than allowed limit.
def rename_index: (untyped table_name, untyped old_name, untyped new_name) -> untyped
def foreign_keys: (untyped table_name) -> untyped
def foreign_tables: () -> untyped
def foreign_table_exists?: (untyped table_name) -> untyped
def type_to_sql: (untyped `type`, ?array: untyped? array, ?scale: untyped? scale, ?precision: untyped? precision, ?limit: untyped? limit) -> untyped
def columns_for_distinct: (untyped columns, untyped orders) -> untyped
def update_table_definition: (untyped table_name, untyped base) -> PostgreSQL::Table
def create_schema_dumper: (untyped options) -> untyped
# Validates the given constraint.
#
# Validates the constraint named +constraint_name+ on +accounts+.
#
# validate_constraint :accounts, :constraint_name
def validate_constraint: (untyped table_name, untyped constraint_name) -> (nil | untyped)
# Validates the given foreign key.
#
# Validates the foreign key on +accounts.branch_id+.
#
# validate_foreign_key :accounts, :branches
#
# Validates the foreign key on +accounts.owner_id+.
#
# validate_foreign_key :accounts, column: :owner_id
#
# Validates the foreign key named +special_fk_name+ on the +accounts+ table.
#
# validate_foreign_key :accounts, name: :special_fk_name
#
# The +options+ hash accepts the same keys as SchemaStatements#add_foreign_key.
def validate_foreign_key: (untyped from_table, ?untyped? to_table, **untyped options) -> (nil | untyped)
def schema_creation: () -> PostgreSQL::SchemaCreation
def create_table_definition: (*untyped args, **untyped options) -> PostgreSQL::TableDefinition
def create_alter_table: (untyped name) -> PostgreSQL::AlterTable
def new_column_from_field: (untyped table_name, untyped field) -> PostgreSQL::Column
def fetch_type_metadata: (untyped column_name, untyped sql_type, untyped oid, untyped fmod) -> PostgreSQL::TypeMetadata
def sequence_name_from_parts: (untyped table_name, untyped column_name, untyped suffix) -> ::String
def extract_foreign_key_action: (untyped specifier) -> untyped
def add_column_for_alter: (untyped table_name, untyped column_name, untyped `type`, **untyped options) -> (untyped | ::Array[untyped])
def change_column_for_alter: (untyped table_name, untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
def change_column_default_for_alter: (untyped table_name, untyped column_name, untyped default_or_changes) -> (nil | untyped)
def change_column_null_for_alter: (untyped table_name, untyped column_name, untyped null, ?untyped? default) -> ::String
def add_index_opclass: (untyped quoted_columns, **untyped options) -> untyped
def add_options_for_index_columns: (untyped quoted_columns, **untyped options) -> untyped
def data_source_sql: (?untyped? name, ?type: untyped? `type`) -> untyped
def quoted_scope: (?untyped? name, ?type: untyped? `type`) -> untyped
def extract_schema_qualified_name: (untyped string) -> ::Array[untyped]
end
end
end
end
module ActiveRecord
# :stopdoc:
module ConnectionAdapters
module PostgreSQL
# Note: It inherits unnamed class, but omitted
class TypeMetadata
attr_reader oid: untyped
attr_reader fmod: untyped
def initialize: (untyped type_metadata, ?fmod: untyped? fmod, ?oid: untyped? oid) -> untyped
def ==: (untyped other) -> untyped
def hash: () -> untyped
end
end
PostgreSQLTypeMetadata: untyped
end
end
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
class Name
# Value Object to hold a schema qualified name.
# This is usually the name of a PostgreSQL relation but it can also represent
# schema qualified type names. +schema+ and +identifier+ are unquoted to prevent
# double quoting.
# :nodoc:
SEPARATOR: ::String
attr_reader schema: untyped
attr_reader identifier: untyped
def initialize: (untyped schema, untyped identifier) -> untyped
def to_s: () -> untyped
def quoted: () -> untyped
def ==: (untyped o) -> untyped
def hash: () -> untyped
def parts: () -> untyped
def unquote: (untyped part) -> untyped
end
module Utils
# Returns an instance of ActiveRecord::ConnectionAdapters::PostgreSQL::Name
# extracted from +string+.
# +schema+ is +nil+ if not specified in +string+.
# +schema+ and +identifier+ exclude surrounding quotes (regardless of whether provided in +string+)
# +string+ supports the range of schema/table references understood by PostgreSQL, for example:
#
# * table_name
# * "table.name"
# * schema_name.table_name
# * schema_name."table.name"
# * "schema_name".table_name
# * "schema.name"."table name"
def extract_schema_qualified_name: (untyped string) -> PostgreSQL::Name
end
end
end
end
module ActiveRecord
module ConnectionAdapters
class SchemaCache
attr_reader version: untyped
attr_accessor connection: untyped
def initialize: (untyped conn) -> untyped
def initialize_dup: (untyped other) -> untyped
def encode_with: (untyped coder) -> untyped
def init_with: (untyped coder) -> untyped
def primary_keys: (untyped table_name) -> untyped
# A cached lookup for table existence.
def data_source_exists?: (untyped name) -> untyped
# Add internal cache for table with +table_name+.
def add: (untyped table_name) -> untyped
def data_sources: (untyped name) -> untyped
# Get the columns for a table
def columns: (untyped table_name) -> untyped
# Get the columns for a table as a hash, key is the column name
# value is the column object.
def columns_hash: (untyped table_name) -> untyped
# Checks whether the columns hash is already cached for a table.
def columns_hash?: (untyped table_name) -> untyped
def indexes: (untyped table_name) -> untyped
def database_version: () -> untyped
# Clears out internal caches
def clear!: () -> untyped
def size: () -> untyped
# Clear out internal caches for the data source +name+.
def clear_data_source_cache!: (untyped name) -> untyped
def marshal_dump: () -> ::Array[untyped]
def marshal_load: (untyped array) -> untyped
def prepare_data_sources: () -> untyped
end
end
end
module ActiveRecord
module ConnectionHandling
# :nodoc:
def sqlite3_connection: (untyped config) -> untyped
end
module ConnectionAdapters
# nodoc:
# The SQLite3 adapter works SQLite 3.6.16 or newer
# with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
#
# Options:
#
# * :database - Path to the database file.
class SQLite3Adapter < AbstractAdapter
ADAPTER_NAME: ::String
include SQLite3::Quoting
include SQLite3::SchemaStatements
include SQLite3::DatabaseStatements
NATIVE_DATABASE_TYPES: ::Hash[untyped, untyped]
def self.represent_boolean_as_integer=: (untyped value) -> untyped
class StatementPool < ConnectionAdapters::StatementPool
def dealloc: (untyped stmt) -> untyped
end
def initialize: (untyped connection, untyped logger, untyped connection_options, untyped config) -> untyped
def self.database_exists?: (untyped config) -> untyped
def supports_ddl_transactions?: () -> ::TrueClass
def supports_savepoints?: () -> ::TrueClass
def supports_partial_index?: () -> ::TrueClass
def supports_expression_index?: () -> untyped
def requires_reloading?: () -> ::TrueClass
def supports_foreign_keys?: () -> ::TrueClass
def supports_views?: () -> ::TrueClass
def supports_datetime_with_precision?: () -> ::TrueClass
def supports_json?: () -> ::TrueClass
def supports_common_table_expressions?: () -> untyped
def supports_insert_on_conflict?: () -> untyped
def active?: () -> untyped
def reconnect!: () -> untyped
# Disconnects from the database if already connected. Otherwise, this
# method does nothing.
def disconnect!: () -> untyped
def supports_index_sort_order?: () -> ::TrueClass
# Returns 62. SQLite supports index names up to 64
# characters. The rest is used by Rails internally to perform
# temporary rename operations
def allowed_index_name_length: () -> untyped
def native_database_types: () -> untyped
# Returns the current database encoding format as a string, eg: 'UTF-8'
def encoding: () -> untyped
def supports_explain?: () -> ::TrueClass
def supports_lazy_transactions?: () -> ::TrueClass
def disable_referential_integrity: () { () -> untyped } -> untyped
# -
# DATABASE STATEMENTS ======================================
# +
def explain: (untyped arel, ?untyped binds) -> untyped
def primary_keys: (untyped table_name) -> untyped
def remove_index: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
# Renames a table.
#
# Example:
# rename_table('octopuses', 'octopi')
def rename_table: (untyped table_name, untyped new_name) -> untyped
def add_column: (untyped table_name, untyped column_name, untyped `type`, **untyped options) -> untyped
def remove_column: (untyped table_name, untyped column_name, ?untyped? `type`, **untyped options) -> untyped
def change_column_default: (untyped table_name, untyped column_name, untyped default_or_changes) -> untyped
def change_column_null: (untyped table_name, untyped column_name, untyped null, ?untyped? default) -> untyped
def change_column: (untyped table_name, untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
def rename_column: (untyped table_name, untyped column_name, untyped new_column_name) -> untyped
def add_reference: (untyped table_name, untyped ref_name, **untyped options) -> untyped
def foreign_keys: (untyped table_name) -> untyped
def build_insert_sql: (untyped insert) -> untyped
def get_database_version: () -> AbstractAdapter::Version
def check_version: () -> untyped
# See https://www.sqlite.org/limits.html,
# the default value is 999 when not configured.
def bind_params_length: () -> 999
def initialize_type_map: (?untyped m) -> untyped
def table_structure: (untyped table_name) -> untyped
# See: https://www.sqlite.org/lang_altertable.html
# SQLite has an additional restriction on the ALTER TABLE statement
def invalid_alter_table_type?: (untyped `type`, untyped options) -> untyped
def alter_table: (untyped table_name, ?untyped foreign_keys, **untyped options) { (untyped) -> untyped } -> untyped
def move_table: (untyped from, untyped to, ?::Hash[untyped, untyped] options) { () -> untyped } -> untyped
def copy_table: (untyped from, untyped to, ?::Hash[untyped, untyped] options) { (untyped) -> untyped } -> untyped
def copy_table_indexes: (untyped from, untyped to, ?::Hash[untyped, untyped] rename) -> untyped
def copy_table_contents: (untyped from, untyped to, untyped columns, ?::Hash[untyped, untyped] rename) -> untyped
def translate_exception: (untyped exception, binds: untyped binds, sql: untyped sql, message: untyped message) -> untyped
COLLATE_REGEX: untyped
def table_structure_with_collation: (untyped table_name, untyped basic_structure) -> untyped
def arel_visitor: () -> Arel::Visitors::SQLite
def build_statement_pool: () -> StatementPool
def connect: () -> untyped
def configure_connection: () -> untyped
class SQLite3Integer < ActiveModel::Type::Integer
def _limit: () -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module SQLite3
module DatabaseStatements
READ_QUERY: untyped
def write_query?: (untyped sql) -> untyped
def execute: (untyped sql, ?untyped? name) -> untyped
def exec_query: (untyped sql, ?untyped? name, ?untyped binds, ?prepare: bool prepare) -> untyped
def exec_delete: (untyped sql, ?::String name, ?untyped binds) -> untyped
def begin_db_transaction: () -> untyped
def commit_db_transaction: () -> untyped
def exec_rollback_db_transaction: () -> untyped
def execute_batch: (untyped statements, ?untyped? name) -> untyped
def last_inserted_id: (untyped result) -> untyped
def build_fixture_statements: (untyped fixture_set) -> untyped
def build_truncate_statement: (untyped table_name) -> ::String
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module SQLite3
class ExplainPrettyPrinter
# :nodoc:
# Pretty prints the result of an EXPLAIN QUERY PLAN in a way that resembles
# the output of the SQLite shell:
#
# 0|0|0|SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
# 0|1|1|SCAN TABLE posts (~100000 rows)
#
def pp: (untyped result) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module SQLite3
module Quoting
# :nodoc:
def quote_string: (untyped s) -> untyped
def quote_table_name_for_assignment: (untyped table, untyped attr) -> untyped
def quote_table_name: (untyped name) -> untyped
def quote_column_name: (untyped name) -> untyped
def quoted_time: (untyped value) -> untyped
def quoted_binary: (untyped value) -> ::String
def quoted_true: () -> "1"
def unquoted_true: () -> 1
def quoted_false: () -> "0"
def unquoted_false: () -> 0
def column_name_matcher: () -> untyped
def column_name_with_order_matcher: () -> untyped
COLUMN_NAME: untyped
COLUMN_NAME_WITH_ORDER: untyped
def _type_cast: (untyped value) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module SQLite3
class SchemaCreation < AbstractAdapter::SchemaCreation
def add_column_options!: (untyped sql, untyped options) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module SQLite3
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
def references: (*untyped args, **untyped options) -> untyped
def integer_like_primary_key_type: (untyped `type`, untyped options) -> :primary_key
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module SQLite3
class SchemaDumper < ConnectionAdapters::SchemaDumper
def default_primary_key?: (untyped column) -> untyped
def explicit_primary_key_default?: (untyped column) -> untyped
end
end
end
end
module ActiveRecord
module ConnectionAdapters
module SQLite3
module SchemaStatements
# :nodoc:
# Returns an array of indexes for the given table.
def indexes: (untyped table_name) -> untyped
def add_foreign_key: (untyped from_table, untyped to_table, **untyped options) -> untyped
def remove_foreign_key: (untyped from_table, ?untyped? to_table, **untyped options) -> untyped
def create_schema_dumper: (untyped options) -> untyped
def schema_creation: () -> SQLite3::SchemaCreation
def create_table_definition: (*untyped args, **untyped options) -> SQLite3::TableDefinition
def new_column_from_field: (untyped table_name, untyped field) -> Column
def data_source_sql: (?untyped? name, ?type: untyped? `type`) -> untyped
def quoted_scope: (?untyped? name, ?type: untyped? `type`) -> untyped
end
end
end
end
module ActiveRecord
# :stopdoc:
module ConnectionAdapters
class SqlTypeMetadata
attr_reader sql_type: untyped
attr_reader type: untyped
attr_reader limit: untyped
attr_reader precision: untyped
attr_reader scale: untyped
def initialize: (?scale: untyped? scale, ?precision: untyped? precision, ?limit: untyped? limit, ?type: untyped? `type`, ?sql_type: untyped? sql_type) -> untyped
def ==: (untyped other) -> untyped
def hash: () -> untyped
end
end
end
module ActiveRecord
module ConnectionAdapters
class StatementPool
# :nodoc:
include Enumerable[untyped, untyped]
DEFAULT_STATEMENT_LIMIT: ::Integer
def initialize: (?untyped? statement_limit) -> untyped
def each: () { () -> untyped } -> untyped
def key?: (untyped key) -> untyped
def []: (untyped key) -> untyped
def length: () -> untyped
def []=: (untyped sql, untyped stmt) -> untyped
def clear: () -> untyped
def delete: (untyped key) -> untyped
def cache: () -> untyped
def dealloc: (untyped stmt) -> untyped
end
end
end
module ActiveRecord
module ConnectionHandling
RAILS_ENV: untyped
DEFAULT_ENV: untyped
# Establishes the connection to the database. Accepts a hash as input where
# the :adapter key must be specified with the name of a database adapter (in lower-case)
# example for regular databases (MySQL, PostgreSQL, etc):
#
# ActiveRecord::Base.establish_connection(
# adapter: "mysql2",
# host: "localhost",
# username: "myuser",
# password: "mypass",
# database: "somedatabase"
# )
#
# Example for SQLite database:
#
# ActiveRecord::Base.establish_connection(
# adapter: "sqlite3",
# database: "path/to/dbfile"
# )
#
# Also accepts keys as strings (for parsing from YAML for example):
#
# ActiveRecord::Base.establish_connection(
# "adapter" => "sqlite3",
# "database" => "path/to/dbfile"
# )
#
# Or a URL:
#
# ActiveRecord::Base.establish_connection(
# "postgres://myuser:mypass@localhost/somedatabase"
# )
#
# In case {ActiveRecord::Base.configurations}[rdoc-ref:Core.configurations]
# is set (Rails automatically loads the contents of config/database.yml into it),
# a symbol can also be given as argument, representing a key in the
# configuration hash:
#
# ActiveRecord::Base.establish_connection(:production)
#
# The exceptions AdapterNotSpecified, AdapterNotFound and +ArgumentError+
# may be returned on an error.
def establish_connection: (?untyped? config_or_env) -> untyped
# Connects a model to the databases specified. The +database+ keyword
# takes a hash consisting of a +role+ and a +database_key+.
#
# This will create a connection handler for switching between connections,
# look up the config hash using the +database_key+ and finally
# establishes a connection to that config.
#
# class AnimalsModel < ApplicationRecord
# self.abstract_class = true
#
# connects_to database: { writing: :primary, reading: :primary_replica }
# end
#
# Returns an array of established connections.
def connects_to: (?database: ::Hash[untyped, untyped] database) -> untyped
# Connects to a database or role (ex writing, reading, or another
# custom role) for the duration of the block.
#
# If a role is passed, Active Record will look up the connection
# based on the requested role:
#
# ActiveRecord::Base.connected_to(role: :writing) do
# Dog.create! # creates dog using dog writing connection
# end
#
# ActiveRecord::Base.connected_to(role: :reading) do
# Dog.create! # throws exception because we're on a replica
# end
#
# ActiveRecord::Base.connected_to(role: :unknown_role) do
# # raises exception due to non-existent role
# end
#
# The `database` kwarg is deprecated in 6.1 and will be removed in 6.2
#
# It is not recommended for use as it re-establishes a connection every
# time it is called.
def connected_to: (?prevent_writes: bool prevent_writes, ?role: untyped? role, ?database: untyped? database) { () -> untyped } -> untyped
# Returns true if role is the current connected role.
#
# ActiveRecord::Base.connected_to(role: :writing) do
# ActiveRecord::Base.connected_to?(role: :writing) #=> true
# ActiveRecord::Base.connected_to?(role: :reading) #=> false
# end
def connected_to?: (role: untyped role) -> untyped
# Returns the symbol representing the current connected role.
#
# ActiveRecord::Base.connected_to(role: :writing) do
# ActiveRecord::Base.current_role #=> :writing
# end
#
# ActiveRecord::Base.connected_to(role: :reading) do
# ActiveRecord::Base.current_role #=> :reading
# end
def current_role: () -> untyped
def lookup_connection_handler: (untyped handler_key) -> untyped
def with_handler: (untyped handler_key) { () -> untyped } -> untyped
def resolve_config_for_connection: (untyped config_or_env) -> untyped
# Clears the query cache for all connections associated with the current thread.
def clear_query_caches_for_current_thread: () -> untyped
# Returns the connection currently associated with the class. This can
# also be used to "borrow" the connection to do database work unrelated
# to any of the specific Active Records.
def connection: () -> untyped
attr_writer connection_specification_name: untyped
# Return the specification name from the current class or its parent.
def connection_specification_name: () -> untyped
def primary_class?: () -> untyped
# Returns the configuration of the associated connection as a hash:
#
# ActiveRecord::Base.connection_config
# # => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"}
#
# Please use only for reading.
def connection_config: () -> untyped
def connection_pool: () -> untyped
def retrieve_connection: () -> untyped
# Returns +true+ if Active Record is connected.
def connected?: () -> untyped
def remove_connection: (?untyped? name) -> untyped
def clear_cache!: () -> untyped
def swap_connection_handler: (untyped handler) { () -> untyped } -> untyped
end
end
module ActiveRecord
module Core
extend ActiveSupport::Concern
#
# Contains the database configuration - as is typically stored in config/database.yml -
# as an ActiveRecord::DatabaseConfigurations object.
#
# For example, the following database.yml...
#
# development:
# adapter: sqlite3
# database: db/development.sqlite3
#
# production:
# adapter: sqlite3
# database: db/production.sqlite3
#
# ...would result in ActiveRecord::Base.configurations to look like this:
#
# #"sqlite3", "database"=>"db/development.sqlite3"}>,
# #"mysql2", "database"=>"db/production.sqlite3"}>
# ]>
def self.configurations=: (untyped config) -> untyped
# Returns fully resolved ActiveRecord::DatabaseConfigurations object
def self.configurations: () -> untyped
def self.connection_handler: () -> untyped
def self.connection_handler=: (untyped handler) -> untyped
module ClassMethods
def initialize_find_by_cache: () -> untyped
def inherited: (untyped child_class) -> untyped
def find: (*untyped ids) -> untyped
def find_by: (*untyped args) -> untyped
def find_by!: (*untyped args) -> untyped
def initialize_generated_modules: () -> untyped
def generated_association_methods: () -> untyped
# Returns columns which shouldn't be exposed while calling +#inspect+.
def filter_attributes: () -> untyped
# Specifies columns which shouldn't be exposed while calling +#inspect+.
attr_writer filter_attributes: untyped
def inspect: () -> untyped
def ===: (untyped object) -> untyped
def arel_table: () -> untyped
def arel_attribute: (untyped name, ?untyped table) -> untyped
def predicate_builder: () -> untyped
def type_caster: () -> TypeCaster::Map
def _internal?: () -> ::FalseClass
def cached_find_by_statement: (untyped key) { () -> untyped } -> untyped
def relation: () -> untyped
def table_metadata: () -> TableMetadata
end
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
# attributes but not yet saved (pass a hash with key names matching the associated table column names).
# In both instances, valid attribute keys are determined by the column names of the associated table --
# hence you can't have attributes that aren't part of the table columns.
#
# ==== Example:
# # Instantiates a single new object
# User.new(first_name: 'Jamie')
def initialize: (?untyped? attributes) { (untyped) -> untyped } -> untyped
# Initialize an empty model object from +coder+. +coder+ should be
# the result of previously encoding an Active Record model, using
# #encode_with.
#
# class Post < ActiveRecord::Base
# end
#
# old_post = Post.new(title: "hello world")
# coder = {}
# old_post.encode_with(coder)
#
# post = Post.allocate
# post.init_with(coder)
# post.title # => 'hello world'
def init_with: (untyped coder) { () -> untyped } -> untyped
def init_with_attributes: (untyped attributes, ?bool new_record) { (untyped) -> untyped } -> untyped
def initialize_dup: (untyped other) -> untyped
# Populate +coder+ with attributes about this record that should be
# serialized. The structure of +coder+ defined in this method is
# guaranteed to match the structure of +coder+ passed to the #init_with
# method.
#
# Example:
#
# class Post < ActiveRecord::Base
# end
# coder = {}
# Post.new.encode_with(coder)
# coder # => {"attributes" => {"id" => nil, ... }}
def encode_with: (untyped coder) -> untyped
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
# is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
#
# Note that new records are different from any other record by definition, unless the
# other record is the receiver itself. Besides, if you fetch existing records with
# +select+ and leave the ID out, you're on your own, this predicate will return false.
#
# Note also that destroying a record preserves its ID in the model instance, so deleted
# models are still comparable.
def ==: (untyped comparison_object) -> untyped
# Delegates to id in order to allow two records of the same type and id to work with something like:
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
def hash: () -> untyped
# Clone and freeze the attributes hash such that associations are still
# accessible, even on destroyed records, but cloned models will not be
# frozen.
def freeze: () -> untyped
# Returns +true+ if the attributes hash has been frozen.
def frozen?: () -> untyped
# Allows sort on objects
def <=>: (untyped other_object) -> untyped
def present?: () -> ::TrueClass
def blank?: () -> ::FalseClass
# Returns +true+ if the record is read only. Records loaded through joins with piggy-back
# attributes will be marked as read only since they cannot be saved.
def readonly?: () -> untyped
# Marks this record as read only.
def readonly!: () -> untyped
def connection_handler: () -> untyped
# Returns the contents of the record as a nicely formatted string.
def inspect: () -> ::String
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from pp record
# when pp is required.
def pretty_print: (untyped pp) -> untyped
# Returns a hash of the given methods with their names as keys and returned values as values.
def slice: (*untyped methods) -> untyped
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
# the array, and then rescues from the possible +NoMethodError+. If those elements are
# +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
# which significantly impacts upon performance.
#
# So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
#
# See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
def to_ary: () -> nil
def init_internals: () -> untyped
def initialize_internals_callback: () -> nil
def custom_inspect_method_defined?: () -> untyped
# Note: It inherits unnamed class, but omitted
class InspectionMask
def pretty_print: (untyped pp) -> untyped
end
def inspection_filter: () -> untyped
end
end
module ActiveRecord
# = Active Record Counter Cache
module CounterCache
extend ActiveSupport::Concern
module ClassMethods
# Resets one or more counter caches to their correct value using an SQL
# count query. This is useful when adding new counter caches, or if the
# counter has been corrupted or modified directly by SQL.
#
# ==== Parameters
#
# * +id+ - The id of the object you wish to reset a counter on.
# * +counters+ - One or more association counters to reset. Association name or counter name can be given.
# * :touch - Touch timestamp columns when updating.
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
# touch that column or an array of symbols to touch just those ones.
#
# ==== Examples
#
# # For the Post with id #1, reset the comments_count
# Post.reset_counters(1, :comments)
#
# # Like above, but also touch the +updated_at+ and/or +updated_on+
# # attributes.
# Post.reset_counters(1, :comments, touch: true)
def reset_counters: (untyped id, *untyped counters, ?touch: untyped? touch) -> ::TrueClass
# A generic "counter updater" implementation, intended primarily to be
# used by #increment_counter and #decrement_counter, but which may also
# be useful on its own. It simply does a direct SQL update for the record
# with the given ID, altering the given hash of counters by the amount
# given by the corresponding value:
#
# ==== Parameters
#
# * +id+ - The id of the object you wish to update a counter on or an array of ids.
# * +counters+ - A Hash containing the names of the fields
# to update as keys and the amount to update the field by as values.
# * :touch option - Touch timestamp columns when updating.
# If attribute names are passed, they are updated along with updated_at/on
# attributes.
#
# ==== Examples
#
# # For the Post with id of 5, decrement the comment_count by 1, and
# # increment the action_count by 1
# Post.update_counters 5, comment_count: -1, action_count: 1
# # Executes the following SQL:
# # UPDATE posts
# # SET comment_count = COALESCE(comment_count, 0) - 1,
# # action_count = COALESCE(action_count, 0) + 1
# # WHERE id = 5
#
# # For the Posts with id of 10 and 15, increment the comment_count by 1
# Post.update_counters [10, 15], comment_count: 1
# # Executes the following SQL:
# # UPDATE posts
# # SET comment_count = COALESCE(comment_count, 0) + 1
# # WHERE id IN (10, 15)
#
# # For the Posts with id of 10 and 15, increment the comment_count by 1
# # and update the updated_at value for each counter.
# Post.update_counters [10, 15], comment_count: 1, touch: true
# # Executes the following SQL:
# # UPDATE posts
# # SET comment_count = COALESCE(comment_count, 0) + 1,
# # `updated_at` = '2016-10-13T09:59:23-05:00'
# # WHERE id IN (10, 15)
def update_counters: (untyped id, untyped counters) -> untyped
# Increment a numeric field by one, via a direct SQL update.
#
# This method is used primarily for maintaining counter_cache columns that are
# used to store aggregate values. For example, a +DiscussionBoard+ may cache
# posts_count and comments_count to avoid running an SQL query to calculate the
# number of posts and comments there are, each time it is displayed.
#
# ==== Parameters
#
# * +counter_name+ - The name of the field that should be incremented.
# * +id+ - The id of the object that should be incremented or an array of ids.
# * :touch - Touch timestamp columns when updating.
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
# touch that column or an array of symbols to touch just those ones.
#
# ==== Examples
#
# # Increment the posts_count column for the record with an id of 5
# DiscussionBoard.increment_counter(:posts_count, 5)
#
# # Increment the posts_count column for the record with an id of 5
# # and update the updated_at value.
# DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
def increment_counter: (untyped counter_name, untyped id, ?touch: untyped? touch) -> untyped
# Decrement a numeric field by one, via a direct SQL update.
#
# This works the same as #increment_counter but reduces the column value by
# 1 instead of increasing it.
#
# ==== Parameters
#
# * +counter_name+ - The name of the field that should be decremented.
# * +id+ - The id of the object that should be decremented or an array of ids.
# * :touch - Touch timestamp columns when updating.
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
# touch that column or an array of symbols to touch just those ones.
#
# ==== Examples
#
# # Decrement the posts_count column for the record with an id of 5
# DiscussionBoard.decrement_counter(:posts_count, 5)
#
# # Decrement the posts_count column for the record with an id of 5
# # and update the updated_at value.
# DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
def decrement_counter: (untyped counter_name, untyped id, ?touch: untyped? touch) -> untyped
end
def _create_record: (?untyped attribute_names) -> untyped
def destroy_row: () -> untyped
def each_counter_cached_associations: () { (untyped) -> untyped } -> untyped
end
end
module ActiveRecord
class DatabaseConfigurations
class DatabaseConfig
# ActiveRecord::Base.configurations will return either a HashConfig or
# UrlConfig respectively. It will never return a DatabaseConfig object,
# as this is the parent class for the types of database configuration objects.
# :nodoc:
attr_reader env_name: untyped
# ActiveRecord::Base.configurations will return either a HashConfig or
# UrlConfig respectively. It will never return a DatabaseConfig object,
# as this is the parent class for the types of database configuration objects.
# :nodoc:
attr_reader spec_name: untyped
def initialize: (untyped env_name, untyped spec_name) -> untyped
def replica?: () -> untyped
def migrations_paths: () -> untyped
def url_config?: () -> ::FalseClass
def to_legacy_hash: () -> ::Hash[untyped, untyped]
def for_current_env?: () -> untyped
end
end
end
module ActiveRecord
class DatabaseConfigurations
# A HashConfig object is created for each database configuration entry that
# is created from a hash.
#
# A hash config:
#
# { "development" => { "database" => "db_name" } }
#
# Becomes:
#
# #"db_name"}>
#
# ==== Options
#
# * :env_name - The Rails environment, i.e. "development".
# * :spec_name - The specification name. In a standard two-tier
# database configuration this will default to "primary". In a multiple
# database three-tier database configuration this corresponds to the name
# used in the second tier, for example "primary_readonly".
# * :config - The config hash. This is the hash that contains the
# database adapter, name, and other important information for database
# connections.
class HashConfig < DatabaseConfig
attr_reader config: untyped
def initialize: (untyped env_name, untyped spec_name, untyped config) -> untyped
# Determines whether a database configuration is for a replica / readonly
# connection. If the +replica+ key is present in the config, +replica?+ will
# return +true+.
def replica?: () -> untyped
# The migrations paths for a database configuration. If the
# +migrations_paths+ key is present in the config, +migrations_paths+
# will return its value.
def migrations_paths: () -> untyped
end
end
end
module ActiveRecord
# ActiveRecord::DatabaseConfigurations returns an array of DatabaseConfig
# objects (either a HashConfig or UrlConfig) that are constructed from the
# application's database configuration hash or URL string.
class DatabaseConfigurations
class InvalidConfigurationError < StandardError
end
attr_reader configurations: untyped
def initialize: (?::Hash[untyped, untyped] configurations) -> untyped
# Collects the configs for the environment and optionally the specification
# name passed in. To include replica configurations pass include_replicas: true.
#
# If a spec name is provided a single DatabaseConfig object will be
# returned, otherwise an array of DatabaseConfig objects will be
# returned that corresponds with the environment and type requested.
#
# ==== Options
#
# * env_name: The environment name. Defaults to +nil+ which will collect
# configs for all environments.
# * spec_name: The specification name (i.e. primary, animals, etc.). Defaults
# to +nil+.
# * include_replicas: Determines whether to include replicas in
# the returned list. Most of the time we're only iterating over the write
# connection (i.e. migrations don't need to run for the write and read connection).
# Defaults to +false+.
def configs_for: (?include_replicas: bool include_replicas, ?spec_name: untyped? spec_name, ?env_name: untyped? env_name) -> untyped
# Returns the config hash that corresponds with the environment
#
# If the application has multiple databases +default_hash+ will
# return the first config hash for the environment.
#
# { database: "my_db", adapter: "mysql2" }
def default_hash: (?untyped env) -> untyped
# Returns a single DatabaseConfig object based on the requested environment.
#
# If the application has multiple databases +find_db_config+ will return
# the first DatabaseConfig for the environment.
def find_db_config: (untyped env) -> untyped
# Returns the DatabaseConfigurations object as a Hash.
def to_h: () -> untyped
# Checks if the application's configurations are empty.
#
# Aliased to blank?
def empty?: () -> untyped
def each: () { (untyped) -> untyped } -> untyped
def first: () -> ::Array[untyped]
def env_with_configs: (?untyped? env) -> untyped
def build_configs: (untyped configs) -> untyped
def walk_configs: (untyped env_name, untyped config) -> untyped
def build_db_config_from_raw_config: (untyped env_name, untyped spec_name, untyped config) -> untyped
def build_db_config_from_string: (untyped env_name, untyped spec_name, untyped config) -> untyped
def build_db_config_from_hash: (untyped env_name, untyped spec_name, untyped config) -> untyped
def merge_db_environment_variables: (untyped current_env, untyped configs) -> untyped
def environment_url_config: (untyped env, untyped spec_name, untyped config) -> (nil | ActiveRecord::DatabaseConfigurations::UrlConfig)
def environment_value_for: (untyped spec_name) -> untyped
def method_missing: (untyped method, *untyped args) { () -> untyped } -> untyped
def throw_setter_deprecation: (untyped method) -> untyped
def throw_getter_deprecation: (untyped method) -> untyped
end
end
module ActiveRecord
class DatabaseConfigurations
# A UrlConfig object is created for each database configuration
# entry that is created from a URL. This can either be a URL string
# or a hash with a URL in place of the config hash.
#
# A URL config:
#
# postgres://localhost/foo
#
# Becomes:
#
# #"postgresql", "database"=>"foo", "host"=>"localhost"},
# @url="postgres://localhost/foo">
#
# ==== Options
#
# * :env_name - The Rails environment, ie "development".
# * :spec_name - The specification name. In a standard two-tier
# database configuration this will default to "primary". In a multiple
# database three-tier database configuration this corresponds to the name
# used in the second tier, for example "primary_readonly".
# * :url - The database URL.
# * :config - The config hash. This is the hash that contains the
# database adapter, name, and other important information for database
# connections.
class UrlConfig < DatabaseConfig
attr_reader url: untyped
attr_reader config: untyped
def initialize: (untyped env_name, untyped spec_name, untyped url, ?::Hash[untyped, untyped] config) -> untyped
def url_config?: () -> ::TrueClass
# Determines whether a database configuration is for a replica / readonly
# connection. If the +replica+ key is present in the config, +replica?+ will
# return +true+.
def replica?: () -> untyped
# The migrations paths for a database configuration. If the
# +migrations_paths+ key is present in the config, +migrations_paths+
# will return its value.
def migrations_paths: () -> untyped
def build_url_hash: (untyped url) -> untyped
def build_config: (untyped original_config, untyped url) -> untyped
end
end
end
module ActiveRecord
# This module exists because ActiveRecord::AttributeMethods::Dirty needs to
# define callbacks, but continue to have its version of +save+ be the super
# method of ActiveRecord::Callbacks. This will be removed when the removal
# of deprecated code removes this need.
module DefineCallbacks
extend ActiveSupport::Concern
module ClassMethods
# :nodoc:
include ActiveModel::Callbacks
end
include ActiveModel::Validations::Callbacks
extend ::ActiveModel::Validations::Callbacks::ClassMethods
end
end
module ActiveRecord
module DynamicMatchers
def respond_to_missing?: (untyped name, untyped _) -> untyped
def method_missing: (untyped name, *untyped arguments) { () -> untyped } -> untyped
class Method
attr_reader matchers: untyped
def self.match: (untyped model, untyped name) -> untyped
def self.pattern: () -> untyped
def self.prefix: () -> untyped
def self.suffix: () -> ::String
attr_reader model: untyped
attr_reader name: untyped
attr_reader attribute_names: untyped
def initialize: (untyped model, untyped method_name) -> untyped
def valid?: () -> untyped
def define: () -> untyped
def body: () -> ::String
# The parameters in the signature may have reserved Ruby words, in order
# to prevent errors, we start each param name with `_`.
def signature: () -> untyped
# Given that the parameters starts with `_`, the finder needs to use the
# same parameter name.
def attributes_hash: () -> untyped
def finder: () -> untyped
end
class FindBy < Method
def self.prefix: () -> "find_by"
def finder: () -> "find_by"
end
class FindByBang < Method
def self.prefix: () -> "find_by"
def self.suffix: () -> "!"
def finder: () -> "find_by!"
end
end
end
module ActiveRecord
module Enum
def self.extended: (untyped base) -> untyped
def inherited: (untyped base) -> untyped
class EnumType < ActiveModel::Type::Value
def initialize: (untyped name, untyped mapping, untyped subtype) -> untyped
def cast: (untyped value) -> (nil | untyped)
def deserialize: (untyped value) -> (nil | untyped)
def serialize: (untyped value) -> untyped
def assert_valid_value: (untyped value) -> untyped
attr_reader name: untyped
attr_reader mapping: untyped
attr_reader subtype: untyped
end
def enum: (untyped definitions) -> untyped
def _enum_methods_module: () -> untyped
def assert_valid_enum_definition_values: (untyped values) -> untyped
ENUM_CONFLICT_MESSAGE: ::String
def detect_enum_conflict!: (untyped enum_name, untyped method_name, ?bool klass_method) -> untyped
def raise_conflict_error: (untyped enum_name, untyped method_name, ?source: ::String source, ?type: ::String `type`) -> untyped
def detect_negative_condition!: (untyped method_name) -> untyped
end
end
module ActiveRecord
# = Active Record Errors
#
# Generic Active Record exception class.
class ActiveRecordError < StandardError
end
# Raised when the single-table inheritance mechanism fails to locate the subclass
# (for example due to improper usage of column that
# {ActiveRecord::Base.inheritance_column}[rdoc-ref:ModelSchema::ClassMethods#inheritance_column]
# points to).
class SubclassNotFound < ActiveRecordError
end
# Raised when an object assigned to an association has an incorrect type.
#
# class Ticket < ActiveRecord::Base
# has_many :patches
# end
#
# class Patch < ActiveRecord::Base
# belongs_to :ticket
# end
#
# # Comments are not patches, this assignment raises AssociationTypeMismatch.
# @ticket.patches << Comment.new(content: "Please attach tests to your patch.")
class AssociationTypeMismatch < ActiveRecordError
end
# Raised when unserialized object's type mismatches one specified for serializable field.
class SerializationTypeMismatch < ActiveRecordError
end
# Raised when adapter not specified on connection (or configuration file
# +config/database.yml+ misses adapter field).
class AdapterNotSpecified < ActiveRecordError
end
# Raised when Active Record cannot find database adapter specified in
# +config/database.yml+ or programmatically.
class AdapterNotFound < ActiveRecordError
end
# Raised when connection to the database could not been established (for example when
# {ActiveRecord::Base.connection=}[rdoc-ref:ConnectionHandling#connection]
# is given a +nil+ object).
class ConnectionNotEstablished < ActiveRecordError
end
# Raised when a write to the database is attempted on a read only connection.
class ReadOnlyError < ActiveRecordError
end
# Raised when Active Record cannot find a record by given id or set of ids.
class RecordNotFound < ActiveRecordError
attr_reader model: untyped
attr_reader primary_key: untyped
attr_reader id: untyped
def initialize: (?untyped? message, ?untyped? model, ?untyped? primary_key, ?untyped? id) -> untyped
end
# Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
# {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]
# methods when a record is invalid and cannot be saved.
class RecordNotSaved < ActiveRecordError
attr_reader record: untyped
def initialize: (?untyped? message, ?untyped? record) -> untyped
end
# Raised by {ActiveRecord::Base#destroy!}[rdoc-ref:Persistence#destroy!]
# when a call to {#destroy}[rdoc-ref:Persistence#destroy!]
# would return false.
#
# begin
# complex_operation_that_internally_calls_destroy!
# rescue ActiveRecord::RecordNotDestroyed => invalid
# puts invalid.record.errors
# end
#
class RecordNotDestroyed < ActiveRecordError
attr_reader record: untyped
def initialize: (?untyped? message, ?untyped? record) -> untyped
end
# Superclass for all database execution errors.
#
# Wraps the underlying database error as +cause+.
class StatementInvalid < ActiveRecordError
def initialize: (?untyped? message, ?binds: untyped? binds, ?sql: untyped? sql) -> untyped
attr_reader sql: untyped
attr_reader binds: untyped
end
# Defunct wrapper class kept for compatibility.
# StatementInvalid wraps the original exception now.
class WrappedDatabaseException < StatementInvalid
end
# Raised when a record cannot be inserted or updated because it would violate a uniqueness constraint.
class RecordNotUnique < WrappedDatabaseException
end
# Raised when a record cannot be inserted or updated because it references a non-existent record,
# or when a record cannot be deleted because a parent record references it.
class InvalidForeignKey < WrappedDatabaseException
end
# Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
class MismatchedForeignKey < StatementInvalid
def initialize: (?primary_key_column: untyped? primary_key_column, ?primary_key: untyped? primary_key, ?target_table: untyped? target_table, ?foreign_key: untyped? foreign_key, ?table: untyped? table, ?binds: untyped? binds, ?sql: untyped? sql, ?message: untyped? message) -> untyped
end
# Raised when a record cannot be inserted or updated because it would violate a not null constraint.
class NotNullViolation < StatementInvalid
end
# Raised when a record cannot be inserted or updated because a value too long for a column type.
class ValueTooLong < StatementInvalid
end
# Raised when values that executed are out of range.
class RangeError < StatementInvalid
end
# Raised when number of bind variables in statement given to +:condition+ key
# (for example, when using {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] method)
# does not match number of expected values supplied.
#
# For example, when there are two placeholders with only one value supplied:
#
# Location.where("lat = ? AND lng = ?", 53.7362)
class PreparedStatementInvalid < ActiveRecordError
end
# Raised when a given database does not exist.
class NoDatabaseError < StatementInvalid
end
# Raised when PostgreSQL returns 'cached plan must not change result type' and
# we cannot retry gracefully (e.g. inside a transaction)
class PreparedStatementCacheExpired < StatementInvalid
end
# Raised on attempt to save stale record. Record is stale when it's being saved in another query after
# instantiation, for example, when two users edit the same wiki page and one starts editing and saves
# the page before the other.
#
# Read more about optimistic locking in ActiveRecord::Locking module
# documentation.
class StaleObjectError < ActiveRecordError
attr_reader record: untyped
attr_reader attempted_action: untyped
def initialize: (?untyped? record, ?untyped? attempted_action) -> untyped
end
# Raised when association is being configured improperly or user tries to use
# offset and limit together with
# {ActiveRecord::Base.has_many}[rdoc-ref:Associations::ClassMethods#has_many] or
# {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many]
# associations.
class ConfigurationError < ActiveRecordError
end
# Raised on attempt to update record that is instantiated as read only.
class ReadOnlyRecord < ActiveRecordError
end
# {ActiveRecord::Base.transaction}[rdoc-ref:Transactions::ClassMethods#transaction]
# uses this exception to distinguish a deliberate rollback from other exceptional situations.
# Normally, raising an exception will cause the
# {.transaction}[rdoc-ref:Transactions::ClassMethods#transaction] method to rollback
# the database transaction *and* pass on the exception. But if you raise an
# ActiveRecord::Rollback exception, then the database transaction will be rolled back,
# without passing on the exception.
#
# For example, you could do this in your controller to rollback a transaction:
#
# class BooksController < ActionController::Base
# def create
# Book.transaction do
# book = Book.new(params[:book])
# book.save!
# if today_is_friday?
# # The system must fail on Friday so that our support department
# # won't be out of job. We silently rollback this transaction
# # without telling the user.
# raise ActiveRecord::Rollback, "Call tech support!"
# end
# end
# # ActiveRecord::Rollback is the only exception that won't be passed on
# # by ActiveRecord::Base.transaction, so this line will still be reached
# # even on Friday.
# redirect_to root_url
# end
# end
class Rollback < ActiveRecordError
end
# Raised when attribute has a name reserved by Active Record (when attribute
# has name of one of Active Record instance methods).
class DangerousAttributeError < ActiveRecordError
end
# Raised when unknown attributes are supplied via mass assignment.
UnknownAttributeError: untyped
# Raised when an error occurred while doing a mass assignment to an attribute through the
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
# The exception has an +attribute+ property that is the name of the offending attribute.
class AttributeAssignmentError < ActiveRecordError
attr_reader exception: untyped
attr_reader attribute: untyped
def initialize: (?untyped? message, ?untyped? exception, ?untyped? attribute) -> untyped
end
# Raised when there are multiple errors while doing a mass assignment through the
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=]
# method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
# objects, each corresponding to the error while assigning to an attribute.
class MultiparameterAssignmentErrors < ActiveRecordError
attr_reader errors: untyped
def initialize: (?untyped? errors) -> untyped
end
# Raised when a primary key is needed, but not specified in the schema or model.
class UnknownPrimaryKey < ActiveRecordError
attr_reader model: untyped
def initialize: (?untyped? model, ?untyped? description) -> untyped
end
# Raised when a relation cannot be mutated because it's already loaded.
#
# class Task < ActiveRecord::Base
# end
#
# relation = Task.all
# relation.loaded? # => true
#
# # Methods which try to mutate a loaded relation fail.
# relation.where!(title: 'TODO') # => ActiveRecord::ImmutableRelation
# relation.limit!(5) # => ActiveRecord::ImmutableRelation
class ImmutableRelation < ActiveRecordError
end
# TransactionIsolationError will be raised under the following conditions:
#
# * The adapter does not support setting the isolation level
# * You are joining an existing open transaction
# * You are creating a nested (savepoint) transaction
#
# The mysql2 and postgresql adapters support setting the transaction isolation level.
class TransactionIsolationError < ActiveRecordError
end
# TransactionRollbackError will be raised when a transaction is rolled
# back by the database due to a serialization failure or a deadlock.
#
# See the following:
#
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
# * https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_lock_deadlock
class TransactionRollbackError < StatementInvalid
end
# SerializationFailure will be raised when a transaction is rolled
# back by the database due to a serialization failure.
class SerializationFailure < TransactionRollbackError
end
# Deadlocked will be raised when a transaction is rolled
# back by the database when a deadlock is encountered.
class Deadlocked < TransactionRollbackError
end
# IrreversibleOrderError is raised when a relation's order is too complex for
# +reverse_order+ to automatically reverse.
class IrreversibleOrderError < ActiveRecordError
end
# LockWaitTimeout will be raised when lock wait timeout exceeded.
class LockWaitTimeout < StatementInvalid
end
# StatementTimeout will be raised when statement timeout exceeded.
class StatementTimeout < StatementInvalid
end
# QueryCanceled will be raised when canceling statement due to user request.
class QueryCanceled < StatementInvalid
end
# UnknownAttributeReference is raised when an unknown and potentially unsafe
# value is passed to a query method when allow_unsafe_raw_sql is set to
# :disabled. For example, passing a non column name value to a relation's
# #order method might cause this exception.
#
# When working around this exception, caution should be taken to avoid SQL
# injection vulnerabilities when passing user-provided values to query
# methods. Known-safe values can be passed to query methods by wrapping them
# in Arel.sql.
#
# For example, with allow_unsafe_raw_sql set to :disabled, the following
# code would raise this exception:
#
# Post.order("length(title)").first
#
# The desired result can be accomplished by wrapping the known-safe string
# in Arel.sql:
#
# Post.order(Arel.sql("length(title)")).first
#
# Again, such a workaround should *not* be used when passing user-provided
# values, such as request parameters or model attributes to query methods.
class UnknownAttributeReference < ActiveRecordError
end
end
module ActiveRecord
module Explain
def collecting_queries_for_explain: () { () -> untyped } -> untyped
def exec_explain: (untyped queries) -> untyped
def render_bind: (untyped attr) -> ::Array[untyped]
end
end
module ActiveRecord
class ExplainRegistry
# This is a thread locals registry for EXPLAIN. For example
#
# ActiveRecord::ExplainRegistry.queries
#
# returns the collected queries local to the current thread.
#
# See the documentation of ActiveSupport::PerThreadRegistry
# for further details.
# :nodoc:
extend ActiveSupport::PerThreadRegistry
attr_accessor queries: untyped
attr_accessor collect: untyped
def initialize: () -> untyped
def collect?: () -> untyped
def reset: () -> untyped
end
end
module ActiveRecord
class ExplainSubscriber
# :nodoc:
def start: (untyped name, untyped id, untyped payload) -> nil
def finish: (untyped name, untyped id, untyped payload) -> untyped
# SCHEMA queries cannot be EXPLAINed, also we do not want to run EXPLAIN on
# our own EXPLAINs no matter how loopingly beautiful that would be.
#
# On the other hand, we want to monitor the performance of our real database
# queries, not the performance of the access to the query cache.
IGNORED_PAYLOADS: ::Array[untyped]
EXPLAINED_SQLS: untyped
def ignore_payload?: (untyped payload) -> untyped
end
end
module ActiveRecord
class FixtureSet
class File
# :nodoc:
include Enumerable[untyped, untyped]
#
# Open a fixture file named +file+. When called with a block, the block
# is called with the filehandle and the filehandle is automatically closed
# when the block finishes.
def self.open: (untyped file) { (untyped) -> untyped } -> untyped
def initialize: (untyped file) -> untyped
def each: () { () -> untyped } -> untyped
def model_class: () -> untyped
def rows: () -> untyped
def config_row: () -> untyped
def raw_rows: () -> untyped
def prepare_erb: (untyped content) -> untyped
def render: (untyped content) -> untyped
# Validate our unmarshalled data.
def validate: (untyped data) -> untyped
end
end
end
module ActiveRecord
class FixtureSet
class ModelMetadata
# :nodoc:
def initialize: (untyped model_class) -> untyped
def primary_key_name: () -> untyped
def primary_key_type: () -> untyped
def has_primary_key_column?: () -> untyped
def timestamp_column_names: () -> untyped
def inheritance_column_name: () -> untyped
end
end
end
class ActiveRecord::FixtureSet::RenderContext
# NOTE: This class has to be defined in compact style in
# order for rendering context subclassing to work correctly.
# :nodoc:
def self.create_subclass: () -> untyped
end
module ActiveRecord
class FixtureSet
class TableRow
class ReflectionProxy
# :nodoc:
# :nodoc:
def initialize: (untyped association) -> untyped
def join_table: () -> untyped
def name: () -> untyped
def primary_key_type: () -> untyped
end
class HasManyThroughProxy < ReflectionProxy
# :nodoc:
def rhs_key: () -> untyped
def lhs_key: () -> untyped
def join_table: () -> untyped
end
def initialize: (untyped fixture, now: untyped now, label: untyped label, table_rows: untyped table_rows) -> untyped
def to_hash: () -> untyped
def model_metadata: () -> untyped
def model_class: () -> untyped
def fill_row_model_attributes: () -> (nil | untyped)
def reflection_class: () -> untyped
def fill_timestamps: () -> untyped
def interpolate_label: () -> untyped
def generate_primary_key: () -> untyped
def resolve_enums: () -> untyped
def resolve_sti_reflections: () -> untyped
def add_join_records: (untyped association) -> untyped
end
end
end
module ActiveRecord
class FixtureSet
class TableRows
# :nodoc:
def initialize: (untyped table_name, config: untyped config, fixtures: untyped fixtures, model_class: untyped model_class) -> untyped
attr_reader tables: untyped
attr_reader model_class: untyped
def to_hash: () -> untyped
def model_metadata: () -> untyped
def build_table_rows_from: (untyped table_name, untyped fixtures, untyped config) -> untyped
end
end
end
module ActiveRecord
class FixtureClassNotFound < ActiveRecord::ActiveRecordError
end
# \Fixtures are a way of organizing data that you want to test against; in short, sample data.
#
# They are stored in YAML files, one file per model, which are placed in the directory
# appointed by ActiveSupport::TestCase.fixture_path=(path) (this is automatically
# configured for Rails, so you can just put your files in /test/fixtures/).
# The fixture file ends with the +.yml+ file extension, for example:
# /test/fixtures/web_sites.yml).
#
# The format of a fixture file looks like this:
#
# rubyonrails:
# id: 1
# name: Ruby on Rails
# url: http://www.rubyonrails.org
#
# google:
# id: 2
# name: Google
# url: http://www.google.com
#
# This fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and
# is followed by an indented list of key/value pairs in the "key: value" format. Records are
# separated by a blank line for your viewing pleasure.
#
# Note: Fixtures are unordered. If you want ordered fixtures, use the omap YAML type.
# See http://yaml.org/type/omap.html
# for the specification. You will need ordered fixtures when you have foreign key constraints
# on keys in the same table. This is commonly needed for tree structures. Example:
#
# --- !omap
# - parent:
# id: 1
# parent_id: NULL
# title: Parent
# - child:
# id: 2
# parent_id: 1
# title: Child
#
# = Using Fixtures in Test Cases
#
# Since fixtures are a testing construct, we use them in our unit and functional tests. There
# are two ways to use the fixtures, but first let's take a look at a sample unit test:
#
# require 'test_helper'
#
# class WebSiteTest < ActiveSupport::TestCase
# test "web_site_count" do
# assert_equal 2, WebSite.count
# end
# end
#
# By default, +test_helper.rb+ will load all of your fixtures into your test
# database, so this test will succeed.
#
# The testing environment will automatically load all the fixtures into the database before each
# test. To ensure consistent data, the environment deletes the fixtures before running the load.
#
# In addition to being available in the database, the fixture's data may also be accessed by
# using a special dynamic method, which has the same name as the model.
#
# Passing in a fixture name to this dynamic method returns the fixture matching this name:
#
# test "find one" do
# assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
# end
#
# Passing in multiple fixture names returns all fixtures matching these names:
#
# test "find all by name" do
# assert_equal 2, web_sites(:rubyonrails, :google).length
# end
#
# Passing in no arguments returns all fixtures:
#
# test "find all" do
# assert_equal 2, web_sites.length
# end
#
# Passing in any fixture name that does not exist will raise StandardError:
#
# test "find by name that does not exist" do
# assert_raise(StandardError) { web_sites(:reddit) }
# end
#
# Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the
# following tests:
#
# test "find_alt_method_1" do
# assert_equal "Ruby on Rails", @web_sites['rubyonrails']['name']
# end
#
# test "find_alt_method_2" do
# assert_equal "Ruby on Rails", @rubyonrails.name
# end
#
# In order to use these methods to access fixtured data within your test cases, you must specify one of the
# following in your ActiveSupport::TestCase-derived class:
#
# - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above)
# self.use_instantiated_fixtures = true
#
# - create only the hash for the fixtures, do not 'find' each instance (enable alternate method #1 only)
# self.use_instantiated_fixtures = :no_instances
#
# Using either of these alternate methods incurs a performance hit, as the fixtured data must be fully
# traversed in the database to create the fixture hash and/or instance variables. This is expensive for
# large sets of fixtured data.
#
# = Dynamic fixtures with ERB
#
# Sometimes you don't care about the content of the fixtures as much as you care about the volume.
# In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load
# testing, like:
#
# <% 1.upto(1000) do |i| %>
# fix_<%= i %>:
# id: <%= i %>
# name: guy_<%= i %>
# <% end %>
#
# This will create 1000 very simple fixtures.
#
# Using ERB, you can also inject dynamic values into your fixtures with inserts like
# <%= Date.today.strftime("%Y-%m-%d") %>.
# This is however a feature to be used with some caution. The point of fixtures are that they're
# stable units of predictable sample data. If you feel that you need to inject dynamic values, then
# perhaps you should reexamine whether your application is properly testable. Hence, dynamic values
# in fixtures are to be considered a code smell.
#
# Helper methods defined in a fixture will not be available in other fixtures, to prevent against
# unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module
# that is included in ActiveRecord::FixtureSet.context_class.
#
# - define a helper method in test_helper.rb
# module FixtureFileHelpers
# def file_sha(path)
# Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
# end
# end
# ActiveRecord::FixtureSet.context_class.include FixtureFileHelpers
#
# - use the helper method in a fixture
# photo:
# name: kitten.png
# sha: <%= file_sha 'files/kitten.png' %>
#
# = Transactional Tests
#
# Test cases can use begin+rollback to isolate their changes to the database instead of having to
# delete+insert for every test case.
#
# class FooTest < ActiveSupport::TestCase
# self.use_transactional_tests = true
#
# test "godzilla" do
# assert_not_empty Foo.all
# Foo.destroy_all
# assert_empty Foo.all
# end
#
# test "godzilla aftermath" do
# assert_not_empty Foo.all
# end
# end
#
# If you preload your test database with all fixture data (probably by running `rails db:fixtures:load`)
# and use transactional tests, then you may omit all fixtures declarations in your test cases since
# all the data's already there and every case rolls back its changes.
#
# In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to
# true. This will provide access to fixture data for every table that has been loaded through
# fixtures (depending on the value of +use_instantiated_fixtures+).
#
# When *not* to use transactional tests:
#
# 1. You're testing whether a transaction works correctly. Nested transactions don't commit until
# all parent transactions commit, particularly, the fixtures transaction which is begun in setup
# and rolled back in teardown. Thus, you won't be able to verify
# the results of your transaction until Active Record supports nested transactions or savepoints (in progress).
# 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM.
# Use InnoDB, MaxDB, or NDB instead.
#
# = Advanced Fixtures
#
# Fixtures that don't specify an ID get some extra features:
#
# * Stable, autogenerated IDs
# * Label references for associations (belongs_to, has_one, has_many)
# * HABTM associations as inline lists
#
# There are some more advanced features available even if the id is specified:
#
# * Autofilled timestamp columns
# * Fixture label interpolation
# * Support for YAML defaults
#
# == Stable, Autogenerated IDs
#
# Here, have a monkey fixture:
#
# george:
# id: 1
# name: George the Monkey
#
# reginald:
# id: 2
# name: Reginald the Pirate
#
# Each of these fixtures has two unique identifiers: one for the database
# and one for the humans. Why don't we generate the primary key instead?
# Hashing each fixture's label yields a consistent ID:
#
# george: # generated id: 503576764
# name: George the Monkey
#
# reginald: # generated id: 324201669
# name: Reginald the Pirate
#
# Active Record looks at the fixture's model class, discovers the correct
# primary key, and generates it right before inserting the fixture
# into the database.
#
# The generated ID for a given label is constant, so we can discover
# any fixture's ID without loading anything, as long as we know the label.
#
# == Label references for associations (belongs_to, has_one, has_many)
#
# Specifying foreign keys in fixtures can be very fragile, not to
# mention difficult to read. Since Active Record can figure out the ID of
# any fixture from its label, you can specify FK's by label instead of ID.
#
# === belongs_to
#
# Let's break out some more monkeys and pirates.
#
# ### in pirates.yml
#
# reginald:
# id: 1
# name: Reginald the Pirate
# monkey_id: 1
#
# ### in monkeys.yml
#
# george:
# id: 1
# name: George the Monkey
# pirate_id: 1
#
# Add a few more monkeys and pirates and break this into multiple files,
# and it gets pretty hard to keep track of what's going on. Let's
# use labels instead of IDs:
#
# ### in pirates.yml
#
# reginald:
# name: Reginald the Pirate
# monkey: george
#
# ### in monkeys.yml
#
# george:
# name: George the Monkey
# pirate: reginald
#
# Pow! All is made clear. Active Record reflects on the fixture's model class,
# finds all the +belongs_to+ associations, and allows you to specify
# a target *label* for the *association* (monkey: george) rather than
# a target *id* for the *FK* (monkey_id: 1).
#
# ==== Polymorphic belongs_to
#
# Supporting polymorphic relationships is a little bit more complicated, since
# Active Record needs to know what type your association is pointing at. Something
# like this should look familiar:
#
# ### in fruit.rb
#
# belongs_to :eater, polymorphic: true
#
# ### in fruits.yml
#
# apple:
# id: 1
# name: apple
# eater_id: 1
# eater_type: Monkey
#
# Can we do better? You bet!
#
# apple:
# eater: george (Monkey)
#
# Just provide the polymorphic target type and Active Record will take care of the rest.
#
# === has_and_belongs_to_many
#
# Time to give our monkey some fruit.
#
# ### in monkeys.yml
#
# george:
# id: 1
# name: George the Monkey
#
# ### in fruits.yml
#
# apple:
# id: 1
# name: apple
#
# orange:
# id: 2
# name: orange
#
# grape:
# id: 3
# name: grape
#
# ### in fruits_monkeys.yml
#
# apple_george:
# fruit_id: 1
# monkey_id: 1
#
# orange_george:
# fruit_id: 2
# monkey_id: 1
#
# grape_george:
# fruit_id: 3
# monkey_id: 1
#
# Let's make the HABTM fixture go away.
#
# ### in monkeys.yml
#
# george:
# id: 1
# name: George the Monkey
# fruits: apple, orange, grape
#
# ### in fruits.yml
#
# apple:
# name: apple
#
# orange:
# name: orange
#
# grape:
# name: grape
#
# Zap! No more fruits_monkeys.yml file. We've specified the list of fruits
# on George's fixture, but we could've just as easily specified a list
# of monkeys on each fruit. As with +belongs_to+, Active Record reflects on
# the fixture's model class and discovers the +has_and_belongs_to_many+
# associations.
#
# == Autofilled Timestamp Columns
#
# If your table/model specifies any of Active Record's
# standard timestamp columns (+created_at+, +created_on+, +updated_at+, +updated_on+),
# they will automatically be set to Time.now.
#
# If you've set specific values, they'll be left alone.
#
# == Fixture label interpolation
#
# The label of the current fixture is always available as a column value:
#
# geeksomnia:
# name: Geeksomnia's Account
# subdomain: $LABEL
# email: $LABEL@email.com
#
# Also, sometimes (like when porting older join table fixtures) you'll need
# to be able to get a hold of the identifier for a given label. ERB
# to the rescue:
#
# george_reginald:
# monkey_id: <%= ActiveRecord::FixtureSet.identify(:reginald) %>
# pirate_id: <%= ActiveRecord::FixtureSet.identify(:george) %>
#
# == Support for YAML defaults
#
# You can set and reuse defaults in your fixtures YAML file.
# This is the same technique used in the +database.yml+ file to specify
# defaults:
#
# DEFAULTS: &DEFAULTS
# created_on: <%= 3.weeks.ago.to_s(:db) %>
#
# first:
# name: Smurf
# <<: *DEFAULTS
#
# second:
# name: Fraggle
# <<: *DEFAULTS
#
# Any fixture labeled "DEFAULTS" is safely ignored.
#
# == Configure the fixture model class
#
# It's possible to set the fixture's model class directly in the YAML file.
# This is helpful when fixtures are loaded outside tests and
# +set_fixture_class+ is not available (e.g.
# when running rails db:fixtures:load).
#
# _fixture:
# model_class: User
# david:
# name: David
#
# Any fixtures labeled "_fixture" are safely ignored.
class FixtureSet
MAX_ID: untyped
class ClassCache
def initialize: (untyped class_names, untyped config) -> untyped
def []: (untyped fs_name) -> untyped
def insert_class: (untyped class_names, untyped name, untyped klass) -> untyped
def default_fixture_model: (untyped fs_name, untyped config) -> untyped
end
def self.default_fixture_model_name: (untyped fixture_set_name, ?untyped config) -> untyped
def self.default_fixture_table_name: (untyped fixture_set_name, ?untyped config) -> untyped
def self.reset_cache: () -> untyped
def self.cache_for_connection: (untyped connection) -> untyped
def self.fixture_is_cached?: (untyped connection, untyped table_name) -> untyped
def self.cached_fixtures: (untyped connection, ?untyped? keys_to_fetch) -> untyped
def self.cache_fixtures: (untyped connection, untyped fixtures_map) -> untyped
def self.instantiate_fixtures: (untyped object, untyped fixture_set, ?bool load_instances) -> (nil | untyped)
def self.instantiate_all_loaded_fixtures: (untyped object, ?bool load_instances) -> untyped
def self.create_fixtures: (untyped fixtures_directory, untyped fixture_set_names, ?::Hash[untyped, untyped] class_names, ?untyped config) { () -> untyped } -> untyped
# Returns a consistent, platform-independent identifier for +label+.
# Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.
def self.identify: (untyped label, ?::Symbol column_type) -> untyped
# Superclass for the evaluation contexts used by ERB fixtures.
def self.context_class: () -> untyped
def self.read_and_insert: (untyped fixtures_directory, untyped fixture_files, untyped class_names, untyped connection) -> untyped
def self.insert: (untyped fixture_sets, untyped connection) -> untyped
def self.update_all_loaded_fixtures: (untyped fixtures_map) -> untyped
attr_reader table_name: untyped
attr_reader name: untyped
attr_reader fixtures: untyped
attr_reader model_class: untyped
attr_reader config: untyped
def initialize: (untyped _, untyped name, untyped class_name, untyped path, ?untyped config) -> untyped
def []: (untyped x) -> untyped
def []=: (untyped k, untyped v) -> untyped
def each: () { () -> untyped } -> untyped
def size: () -> untyped
# Returns a hash of rows to be inserted. The key is the table, the value is
# a list of rows to insert to that table.
def table_rows: () -> untyped
def model_class=: (untyped class_name) -> untyped
# Loads the fixtures from the YAML file at +path+.
# If the file sets the +model_class+ and current instance value is not set,
# it uses the file value.
def read_fixture_files: (untyped path) -> untyped
def yaml_file_path: (untyped path) -> ::String
end
class Fixture
# nodoc:
include Enumerable[untyped, untyped]
class FixtureError < StandardError
end
class FormatError < FixtureError
end
attr_reader model_class: untyped
attr_reader fixture: untyped
def initialize: (untyped fixture, untyped model_class) -> untyped
def class_name: () -> untyped
def each: () { (untyped) -> untyped } -> untyped
def []: (untyped key) -> untyped
def find: () -> untyped
end
end
module ActiveRecord
# Returns the version of the currently loaded Active Record as a Gem::Version
def self.gem_version: () -> Gem::Version
module VERSION
MAJOR: ::Integer
MINOR: ::Integer
TINY: ::Integer
PRE: ::String
STRING: untyped
end
end
module ActiveRecord
# == Single table inheritance
#
# Active Record allows inheritance by storing the name of the class in a column that by
# default is named "type" (can be changed by overwriting Base.inheritance_column).
# This means that an inheritance looking like this:
#
# class Company < ActiveRecord::Base; end
# class Firm < Company; end
# class Client < Company; end
# class PriorityClient < Client; end
#
# When you do Firm.create(name: "37signals"), this record will be saved in
# the companies table with type = "Firm". You can then fetch this row again using
# Company.where(name: '37signals').first and it will return a Firm object.
#
# Be aware that because the type column is an attribute on the record every new
# subclass will instantly be marked as dirty and the type column will be included
# in the list of changed attributes on the record. This is different from non
# Single Table Inheritance(STI) classes:
#
# Company.new.changed? # => false
# Firm.new.changed? # => true
# Firm.new.changes # => {"type"=>["","Firm"]}
#
# If you don't have a type column defined in your table, single-table inheritance won't
# be triggered. In that case, it'll work just like normal subclasses with no special magic
# for differentiating between them or reloading the right type with find.
#
# Note, all the attributes for all the cases are kept in the same table. Read more:
# https://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
#
module Inheritance
extend ActiveSupport::Concern
module ClassMethods
# Determines if one of the attributes passed in is the inheritance column,
# and if the inheritance column is attr accessible, it initializes an
# instance of the given subclass instead of the base class.
def new: (?untyped? attributes) { () -> untyped } -> untyped
# Returns +true+ if this does not need STI type condition. Returns
# +false+ if STI type condition needs to be applied.
def descends_from_active_record?: () -> untyped
def finder_needs_type_condition?: () -> untyped
# Returns the class descending directly from ActiveRecord::Base, or
# an abstract class, if any, in the inheritance hierarchy.
#
# If A extends ActiveRecord::Base, A.base_class will return A. If B descends from A
# through some arbitrarily deep hierarchy, B.base_class will return A.
#
# If B < A and C < B and if A is an abstract_class then both B.base_class
# and C.base_class would return B as the answer since A is an abstract_class.
def base_class: () -> untyped
# Returns whether the class is a base class.
# See #base_class for more information.
def base_class?: () -> untyped
# Set this to +true+ if this is an abstract class (see
# abstract_class?).
# If you are using inheritance with Active Record and don't want a class
# to be considered as part of the STI hierarchy, you must set this to
# true.
# +ApplicationRecord+, for example, is generated as an abstract class.
#
# Consider the following default behaviour:
#
# Shape = Class.new(ActiveRecord::Base)
# Polygon = Class.new(Shape)
# Square = Class.new(Polygon)
#
# Shape.table_name # => "shapes"
# Polygon.table_name # => "shapes"
# Square.table_name # => "shapes"
# Shape.create! # => #
# Polygon.create! # => #
# Square.create! # => #
#
# However, when using abstract_class, +Shape+ is omitted from
# the hierarchy:
#
# class Shape < ActiveRecord::Base
# self.abstract_class = true
# end
# Polygon = Class.new(Shape)
# Square = Class.new(Polygon)
#
# Shape.table_name # => nil
# Polygon.table_name # => "polygons"
# Square.table_name # => "polygons"
# Shape.create! # => NotImplementedError: Shape is an abstract class and cannot be instantiated.
# Polygon.create! # => #
# Square.create! # => #
#
# Note that in the above example, to disallow the creation of a plain
# +Polygon+, you should use validates :type, presence: true,
# instead of setting it as an abstract class. This way, +Polygon+ will
# stay in the hierarchy, and Active Record will continue to correctly
# derive the table name.
attr_accessor abstract_class: untyped
# Returns whether this class is an abstract class or not.
def abstract_class?: () -> untyped
def sti_name: () -> untyped
def polymorphic_name: () -> untyped
def inherited: (untyped subclass) -> untyped
# Returns the class type of the record using the current module as a prefix. So descendants of
# MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
def compute_type: (untyped type_name) -> untyped
# Called by +instantiate+ to decide which class to use for a new
# record instance. For single-table inheritance, we check the record
# for a +type+ column and return the corresponding class.
def discriminate_class_for_record: (untyped record) -> untyped
def using_single_table_inheritance?: (untyped record) -> untyped
def find_sti_class: (untyped type_name) -> untyped
def type_condition: (?untyped table) -> untyped
# Detect the subclass from the inheritance column of attrs. If the inheritance column value
# is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
def subclass_from_attributes: (untyped attrs) -> untyped
end
def initialize_dup: (untyped other) -> untyped
def initialize_internals_callback: () -> untyped
# Sets the attribute used for single table inheritance to this class name if this is not the
# ActiveRecord::Base descendant.
# Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to
# do Reply.new without having to set Reply[Reply.inheritance_column] = "Reply" yourself.
# No such attribute would be set for objects of the Message class in that example.
def ensure_proper_type: () -> untyped
end
end
module ActiveRecord
class InsertAll
# :nodoc:
attr_reader model: untyped
# :nodoc:
attr_reader connection: untyped
# :nodoc:
attr_reader inserts: untyped
# :nodoc:
attr_reader keys: untyped
attr_reader on_duplicate: untyped
attr_reader returning: untyped
attr_reader unique_by: untyped
def initialize: (untyped model, untyped inserts, on_duplicate: untyped on_duplicate, ?unique_by: untyped? unique_by, ?returning: untyped? returning) -> untyped
def execute: () -> untyped
def updatable_columns: () -> untyped
def primary_keys: () -> untyped
def skip_duplicates?: () -> untyped
def update_duplicates?: () -> untyped
def map_key_with_value: () { (untyped, untyped) -> untyped } -> untyped
def find_unique_index_for: (untyped unique_by) -> untyped
def unique_indexes: () -> untyped
def ensure_valid_options_for_connection!: () -> untyped
def to_sql: () -> untyped
def readonly_columns: () -> untyped
def unique_by_columns: () -> untyped
def verify_attributes: (untyped attributes) -> untyped
class Builder
# :nodoc:
attr_reader model: untyped
def initialize: (untyped insert_all) -> untyped
def into: () -> ::String
def values_list: () -> untyped
def returning: () -> untyped
def conflict_target: () -> untyped
def updatable_columns: () -> untyped
attr_reader connection: untyped
attr_reader insert_all: untyped
def columns_list: () -> untyped
def extract_types_from_columns_on: (untyped table_name, keys: untyped keys) -> untyped
def format_columns: (untyped columns) -> untyped
def quote_columns: (untyped columns) -> untyped
end
end
end
module ActiveRecord
module Integration
extend ActiveSupport::Concern
# Returns a +String+, which Action Pack uses for constructing a URL to this
# object. The default implementation returns this record's id as a +String+,
# or +nil+ if this record's unsaved.
#
# For example, suppose that you have a User model, and that you have a
# resources :users route. Normally, +user_path+ will
# construct a path with the user object's 'id' in it:
#
# user = User.find_by(name: 'Phusion')
# user_path(user) # => "/users/1"
#
# You can override +to_param+ in your model to make +user_path+ construct
# a path using the user's name instead of the user's id:
#
# class User < ActiveRecord::Base
# def to_param # overridden
# name
# end
# end
#
# user = User.find_by(name: 'Phusion')
# user_path(user) # => "/users/Phusion"
def to_param: () -> untyped
# Returns a stable cache key that can be used to identify this record.
#
# Product.new.cache_key # => "products/new"
# Product.find(5).cache_key # => "products/5"
#
# If ActiveRecord::Base.cache_versioning is turned off, as it was in Rails 5.1 and earlier,
# the cache key will also include a version.
#
# Product.cache_versioning = false
# Product.find(5).cache_key # => "products/5-20071224150000" (updated_at available)
def cache_key: () -> untyped
# Returns a cache version that can be used together with the cache key to form
# a recyclable caching scheme. By default, the #updated_at column is used for the
# cache_version, but this method can be overwritten to return something else.
#
# Note, this method will return nil if ActiveRecord::Base.cache_versioning is set to
# +false+ (which it is by default until Rails 6.0).
def cache_version: () -> (nil | untyped)
# Returns a cache key along with the version.
def cache_key_with_version: () -> untyped
module ClassMethods
# Defines your model's +to_param+ method to generate "pretty" URLs
# using +method_name+, which can be any attribute or method that
# responds to +to_s+.
#
# class User < ActiveRecord::Base
# to_param :name
# end
#
# user = User.find_by(name: 'Fancy Pants')
# user.id # => 123
# user_path(user) # => "/users/123-fancy-pants"
#
# Values longer than 20 characters will be truncated. The value
# is truncated word by word.
#
# user = User.find_by(name: 'David Heinemeier Hansson')
# user.id # => 125
# user_path(user) # => "/users/125-david-heinemeier"
#
# Because the generated param begins with the record's +id+, it is
# suitable for passing to +find+. In a controller, for example:
#
# params[:id] # => "123-fancy-pants"
# User.find(params[:id]).id # => 123
def to_param: (?untyped? method_name) -> untyped
def collection_cache_key: (?untyped collection, ?::Symbol timestamp_column) -> untyped
end
# Detects if the value before type cast
# can be used to generate a cache_version.
#
# The fast cache version only works with a
# string value directly from the database.
#
# We also must check if the timestamp format has been changed
# or if the timezone is not set to UTC then
# we cannot apply our transformations correctly.
def can_use_fast_cache_version?: (untyped timestamp) -> untyped
# Converts a raw database string to `:usec`
# format.
#
# Example:
#
# timestamp = "2018-10-15 20:02:15.266505"
# raw_timestamp_to_cache_version(timestamp)
# # => "20181015200215266505"
#
# PostgreSQL truncates trailing zeros,
# https://github.com/postgres/postgres/commit/3e1beda2cde3495f41290e1ece5d544525810214
# to account for this we pad the output with zeros
def raw_timestamp_to_cache_version: (untyped timestamp) -> untyped
end
end
module ActiveRecord
class InternalMetadata < ActiveRecord::Base
def self._internal?: () -> ::TrueClass
def self.primary_key: () -> "key"
def self.table_name: () -> ::String
def self.[]=: (untyped key, untyped value) -> untyped
def self.[]: (untyped key) -> untyped
def self.table_exists?: () -> untyped
# Creates an internal metadata table with columns +key+ and +value+
def self.create_table: () -> untyped
def self.drop_table: () -> untyped
end
end
module ActiveRecord
module LegacyYamlAdapter
def self.convert: (untyped klass, untyped coder) -> untyped
module Rails420
def self.convert: (untyped klass, untyped coder) -> untyped
end
module Rails41
def self.convert: (untyped klass, untyped coder) -> ::Hash[::String, untyped]
end
end
end
module ActiveRecord
module Locking
# == What is Optimistic Locking
#
# Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of
# conflicts with the data. It does this by checking whether another process has made changes to a record since
# it was opened, an ActiveRecord::StaleObjectError exception is thrown if that has occurred
# and the update is ignored.
#
# Check out ActiveRecord::Locking::Pessimistic for an alternative.
#
# == Usage
#
# Active Record supports optimistic locking if the +lock_version+ field is present. Each update to the
# record increments the +lock_version+ column and the locking facilities ensure that records instantiated twice
# will let the last one saved raise a +StaleObjectError+ if the first was also updated. Example:
#
# p1 = Person.find(1)
# p2 = Person.find(1)
#
# p1.first_name = "Michael"
# p1.save
#
# p2.first_name = "should fail"
# p2.save # Raises an ActiveRecord::StaleObjectError
#
# Optimistic locking will also check for stale data when objects are destroyed. Example:
#
# p1 = Person.find(1)
# p2 = Person.find(1)
#
# p1.first_name = "Michael"
# p1.save
#
# p2.destroy # Raises an ActiveRecord::StaleObjectError
#
# You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging,
# or otherwise apply the business logic needed to resolve the conflict.
#
# This locking mechanism will function inside a single Ruby process. To make it work across all
# web requests, the recommended approach is to add +lock_version+ as a hidden field to your form.
#
# This behavior can be turned off by setting ActiveRecord::Base.lock_optimistically = false.
# To override the name of the +lock_version+ column, set the locking_column class attribute:
#
# class Person < ActiveRecord::Base
# self.locking_column = :lock_person
# end
#
module Optimistic
extend ActiveSupport::Concern
def locking_enabled?: () -> untyped
def _create_record: (?untyped attribute_names) -> untyped
def _touch_row: (untyped attribute_names, untyped time) -> untyped
def _update_row: (untyped attribute_names, ?::String attempted_action) -> untyped
def destroy_row: () -> untyped
module ClassMethods
DEFAULT_LOCKING_COLUMN: ::String
# Returns true if the +lock_optimistically+ flag is set to true
# (which it is, by default) and the table includes the
# +locking_column+ column (defaults to +lock_version+).
def locking_enabled?: () -> untyped
# Set the column to use for optimistic locking. Defaults to +lock_version+.
def locking_column=: (untyped value) -> untyped
# The version column used for optimistic locking. Defaults to +lock_version+.
def locking_column: () -> untyped
# Reset the column used for optimistic locking back to the +lock_version+ default.
def reset_locking_column: () -> untyped
# Make sure the lock version column gets updated when counters are
# updated.
def update_counters: (untyped id, untyped counters) -> untyped
# We need to apply this decorator here, rather than on module inclusion. The closure
# created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
# sub class being decorated. As such, changes to `lock_optimistically`, or
# `locking_column` would not be picked up.
def inherited: (untyped subclass) -> untyped
end
end
# Note: It inherits unnamed class, but omitted
class LockingType
# In de/serialize we change `nil` to 0, so that we can allow passing
# `nil` values to `lock_version`, and not result in `ActiveRecord::StaleObjectError`
# during update record.
# :nodoc:
def deserialize: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
def init_with: (untyped coder) -> untyped
def encode_with: (untyped coder) -> untyped
end
end
end
module ActiveRecord
module Locking
# Locking::Pessimistic provides support for row-level locking using
# SELECT ... FOR UPDATE and other lock types.
#
# Chain ActiveRecord::Base#find to ActiveRecord::QueryMethods#lock to obtain an exclusive
# lock on the selected rows:
# # select * from accounts where id=1 for update
# Account.lock.find(1)
#
# Call lock('some locking clause') to use a database-specific locking clause
# of your own such as 'LOCK IN SHARE MODE' or 'FOR UPDATE NOWAIT'. Example:
#
# Account.transaction do
# # select * from accounts where name = 'shugo' limit 1 for update nowait
# shugo = Account.lock("FOR UPDATE NOWAIT").find_by(name: "shugo")
# yuko = Account.lock("FOR UPDATE NOWAIT").find_by(name: "yuko")
# shugo.balance -= 100
# shugo.save!
# yuko.balance += 100
# yuko.save!
# end
#
# You can also use ActiveRecord::Base#lock! method to lock one record by id.
# This may be better if you don't need to lock every row. Example:
#
# Account.transaction do
# # select * from accounts where ...
# accounts = Account.where(...)
# account1 = accounts.detect { |account| ... }
# account2 = accounts.detect { |account| ... }
# # select * from accounts where id=? for update
# account1.lock!
# account2.lock!
# account1.balance -= 100
# account1.save!
# account2.balance += 100
# account2.save!
# end
#
# You can start a transaction and acquire the lock in one go by calling
# with_lock with a block. The block is called from within
# a transaction, the object is already locked. Example:
#
# account = Account.first
# account.with_lock do
# # This block is called within a transaction,
# # account is already locked.
# account.balance -= 100
# account.save!
# end
#
# Database-specific information on row locking:
# MySQL: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
# PostgreSQL: https://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE
module Pessimistic
# Obtain a row lock on this record. Reloads the record to obtain the requested
# lock. Pass an SQL locking clause to append the end of the SELECT statement
# or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns
# the locked record.
def lock!: (?bool lock) -> untyped
# Wraps the passed block in a transaction, locking the object
# before yielding. You can pass the SQL locking clause
# as argument (see lock!).
def with_lock: (?bool lock) { () -> untyped } -> untyped
end
end
end
module ActiveRecord
class LogSubscriber < ActiveSupport::LogSubscriber
IGNORE_PAYLOAD_NAMES: ::Array[untyped]
def self.runtime=: (untyped value) -> untyped
def self.runtime: () -> untyped
def self.reset_runtime: () -> untyped
def sql: (untyped event) -> (nil | untyped)
def type_casted_binds: (untyped casted_binds) -> untyped
def render_bind: (untyped attr, untyped value) -> ::Array[untyped]
def colorize_payload_name: (untyped name, untyped payload_name) -> untyped
def sql_color: (untyped sql) -> untyped
def logger: () -> untyped
def debug: (?untyped? progname) { () -> untyped } -> (nil | untyped)
def log_query_source: () -> untyped
def extract_query_source_location: (untyped locations) -> untyped
end
end
module ActiveRecord
module Middleware
# The DatabaseSelector Middleware provides a framework for automatically
# swapping from the primary to the replica database connection. Rails
# provides a basic framework to determine when to swap and allows for
# applications to write custom strategy classes to override the default
# behavior.
#
# The resolver class defines when the application should switch (i.e. read
# from the primary if a write occurred less than 2 seconds ago) and a
# resolver context class that sets a value that helps the resolver class
# decide when to switch.
#
# Rails default middleware uses the request's session to set a timestamp
# that informs the application when to read from a primary or read from a
# replica.
#
# To use the DatabaseSelector in your application with default settings add
# the following options to your environment config:
#
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
#
# New applications will include these lines commented out in the production.rb.
#
# The default behavior can be changed by setting the config options to a
# custom class:
#
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = MyResolver
# config.active_record.database_resolver_context = MyResolver::MySession
class DatabaseSelector
def initialize: (untyped app, ?untyped? resolver_klass, ?untyped? context_klass, ?::Hash[untyped, untyped] options) -> untyped
attr_reader resolver_klass: untyped
attr_reader context_klass: untyped
attr_reader options: untyped
# Middleware that determines which database connection to use in a multiple
# database application.
def call: (untyped env) -> untyped
def select_database: (untyped request) { () -> untyped } -> untyped
def reading_request?: (untyped request) -> untyped
end
end
end
module ActiveRecord
module Middleware
class DatabaseSelector
class Resolver
# The Resolver class is used by the DatabaseSelector middleware to
# determine which database the request should use.
#
# To change the behavior of the Resolver class in your application,
# create a custom resolver class that inherits from
# DatabaseSelector::Resolver and implements the methods that need to
# be changed.
#
# By default the Resolver class will send read traffic to the replica
# if it's been 2 seconds since the last write.
# :nodoc:
SEND_TO_REPLICA_DELAY: untyped
def self.call: (untyped context, ?::Hash[untyped, untyped] options) -> untyped
def initialize: (untyped context, ?::Hash[untyped, untyped] options) -> untyped
attr_reader context: untyped
attr_reader delay: untyped
attr_reader instrumenter: untyped
def read: () { () -> untyped } -> untyped
def write: () { () -> untyped } -> untyped
def read_from_primary: () { () -> untyped } -> untyped
def read_from_replica: () { () -> untyped } -> untyped
def write_to_primary: () { () -> untyped } -> untyped
def read_from_primary?: () -> untyped
def send_to_replica_delay: () -> untyped
def time_since_last_write_ok?: () -> untyped
end
end
end
end
module ActiveRecord
module Middleware
class DatabaseSelector
class Resolver
class Session
# The session class is used by the DatabaseSelector::Resolver to save
# timestamps of the last write in the session.
#
# The last_write is used to determine whether it's safe to read
# from the replica or the request needs to be sent to the primary.
# :nodoc:
def self.call: (untyped request) -> untyped
# Converts time to a timestamp that represents milliseconds since
# epoch.
def self.convert_time_to_timestamp: (untyped time) -> untyped
# Converts milliseconds since epoch timestamp into a time object.
def self.convert_timestamp_to_time: (untyped timestamp) -> untyped
def initialize: (untyped session) -> untyped
attr_reader session: untyped
def last_write_timestamp: () -> untyped
def update_last_write_timestamp: () -> untyped
end
end
end
end
end
module ActiveRecord
class Migration
# ActiveRecord::Migration::CommandRecorder records commands done during
# a migration and knows how to reverse those commands. The CommandRecorder
# knows how to invert the following commands:
#
# * add_column
# * add_foreign_key
# * add_index
# * add_reference
# * add_timestamps
# * change_column
# * change_column_default (must supply a :from and :to option)
# * change_column_null
# * change_column_comment (must supply a :from and :to option)
# * change_table_comment (must supply a :from and :to option)
# * create_join_table
# * create_table
# * disable_extension
# * drop_join_table
# * drop_table (must supply a block)
# * enable_extension
# * remove_column (must supply a type)
# * remove_columns (must specify at least one column name or more)
# * remove_foreign_key (must supply a second table)
# * remove_index
# * remove_reference
# * remove_timestamps
# * rename_column
# * rename_index
# * rename_table
class CommandRecorder
ReversibleAndIrreversibleMethods: ::Array[untyped]
include JoinTable
attr_accessor commands: untyped
attr_accessor delegate: untyped
attr_accessor reverting: untyped
def initialize: (?untyped? delegate) -> untyped
# While executing the given block, the recorded will be in reverting mode.
# All commands recorded will end up being recorded reverted
# and in reverse order.
# For example:
#
# recorder.revert{ recorder.record(:rename_table, [:old, :new]) }
# # same effect as recorder.record(:rename_table, [:new, :old])
def revert: () { () -> untyped } -> untyped
# Record +command+. +command+ should be a method name and arguments.
# For example:
#
# recorder.record(:method_name, [:arg1, :arg2])
def record: (*untyped command) { () -> untyped } -> untyped
# Returns the inverse of the given command. For example:
#
# recorder.inverse_of(:rename_table, [:old, :new])
# # => [:rename_table, [:new, :old]]
#
# This method will raise an +IrreversibleMigration+ exception if it cannot
# invert the +command+.
def inverse_of: (untyped command, untyped args) { () -> untyped } -> untyped
def change_table: (untyped table_name, **untyped options) { (untyped) -> untyped } -> untyped
def replay: (untyped migration) -> untyped
module StraightReversions
end
include StraightReversions
def invert_transaction: (untyped args) { () -> untyped } -> ::Array[:transaction | untyped]
def invert_drop_table: (untyped args) { () -> untyped } -> untyped
def invert_rename_table: (untyped args) -> ::Array[:rename_table | untyped]
def invert_remove_column: (untyped args) -> untyped
def invert_rename_index: (untyped args) -> ::Array[:rename_index | untyped]
def invert_rename_column: (untyped args) -> ::Array[:rename_column | untyped]
def invert_add_index: (untyped args) -> ::Array[:remove_index | ::Array[untyped]]
def invert_remove_index: (untyped args) -> untyped
def invert_change_column_default: (untyped args) -> ::Array[:change_column_default | ::Array[untyped | { from: untyped, to: untyped }]]
def invert_change_column_null: (untyped args) -> ::Array[:change_column_null | untyped]
def invert_remove_foreign_key: (untyped args) -> ::Array[:add_foreign_key | untyped]
def invert_change_column_comment: (untyped args) -> ::Array[:change_column_comment | ::Array[untyped | { from: untyped, to: untyped }]]
def invert_change_table_comment: (untyped args) -> ::Array[:change_table_comment | ::Array[untyped | { from: untyped, to: untyped }]]
def respond_to_missing?: (untyped method, untyped _) -> untyped
# Forwards any missing method call to the \target.
def method_missing: (untyped method, *untyped args) { () -> untyped } -> untyped
end
end
end
module ActiveRecord
class Migration
module Compatibility
# :nodoc: all
def self.find: (untyped version) -> untyped
# workaround: V6_0 and Current are the same object, but RBS doesn't have a syntax for class alias?
class V6_0 < Current
end
class V5_2 < V6_0
module TableDefinition
def timestamps: (**untyped options) -> untyped
end
module CommandRecorder
def invert_transaction: (untyped args) { () -> untyped } -> ::Array[:transaction | untyped]
def invert_change_column_comment: (untyped args) -> ::Array[:change_column_comment | ::Array[untyped | { from: untyped, to: untyped }]]
def invert_change_table_comment: (untyped args) -> ::Array[:change_table_comment | ::Array[untyped | { from: untyped, to: untyped }]]
end
def create_table: (untyped table_name, **untyped options) { (untyped) -> untyped } -> untyped
def change_table: (untyped table_name, **untyped options) { (untyped) -> untyped } -> untyped
def create_join_table: (untyped table_1, untyped table_2, **untyped options) { (untyped) -> untyped } -> untyped
def add_timestamps: (untyped table_name, **untyped options) -> untyped
def compatible_table_definition: (untyped t) -> untyped
def command_recorder: () -> untyped
end
class V5_1 < V5_2
def change_column: (untyped table_name, untyped column_name, untyped `type`, ?::Hash[untyped, untyped] options) -> untyped
def create_table: (untyped table_name, **untyped options) -> untyped
end
class V5_0 < V5_1
module TableDefinition
def primary_key: (untyped name, ?::Symbol `type`, **untyped options) -> untyped
def references: (*untyped args, **untyped options) -> untyped
end
def create_table: (untyped table_name, **untyped options) -> untyped
def create_join_table: (untyped table_1, untyped table_2, ?column_options: ::Hash[untyped, untyped] column_options, **untyped options) -> untyped
def add_column: (untyped table_name, untyped column_name, untyped `type`, **untyped options) -> untyped
def add_reference: (untyped table_name, untyped ref_name, **untyped options) -> untyped
def compatible_table_definition: (untyped t) -> untyped
end
class V4_2 < V5_0
module TableDefinition
def references: (**untyped options) -> untyped
def timestamps: (**untyped options) -> untyped
end
def add_reference: (untyped table_name, untyped ref_name, **untyped options) -> untyped
def add_timestamps: (untyped table_name, **untyped options) -> untyped
def index_exists?: (untyped table_name, untyped column_name, ?::Hash[untyped, untyped] options) -> untyped
def remove_index: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
def compatible_table_definition: (untyped t) -> untyped
def index_name_for_remove: (untyped table_name, ?::Hash[untyped, untyped] options) -> untyped
end
end
end
end
module ActiveRecord
class Migration
module JoinTable
def find_join_table_name: (untyped table_1, untyped table_2, ?::Hash[untyped, untyped] options) -> untyped
def join_table_name: (untyped table_1, untyped table_2) -> untyped
end
end
end
module ActiveRecord
class MigrationError < ActiveRecordError
# nodoc:
def initialize: (?untyped? message) -> untyped
end
# Exception that can be raised to stop migrations from being rolled back.
# For example the following migration is not reversible.
# Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
#
# class IrreversibleMigrationExample < ActiveRecord::Migration[5.0]
# def change
# create_table :distributors do |t|
# t.string :zipcode
# end
#
# execute <<~SQL
# ALTER TABLE distributors
# ADD CONSTRAINT zipchk
# CHECK (char_length(zipcode) = 5) NO INHERIT;
# SQL
# end
# end
#
# There are two ways to mitigate this problem.
#
# 1. Define #up and #down methods instead of #change:
#
# class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
# def up
# create_table :distributors do |t|
# t.string :zipcode
# end
#
# execute <<~SQL
# ALTER TABLE distributors
# ADD CONSTRAINT zipchk
# CHECK (char_length(zipcode) = 5) NO INHERIT;
# SQL
# end
#
# def down
# execute <<~SQL
# ALTER TABLE distributors
# DROP CONSTRAINT zipchk
# SQL
#
# drop_table :distributors
# end
# end
#
# 2. Use the #reversible method in #change method:
#
# class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
# def change
# create_table :distributors do |t|
# t.string :zipcode
# end
#
# reversible do |dir|
# dir.up do
# execute <<~SQL
# ALTER TABLE distributors
# ADD CONSTRAINT zipchk
# CHECK (char_length(zipcode) = 5) NO INHERIT;
# SQL
# end
#
# dir.down do
# execute <<~SQL
# ALTER TABLE distributors
# DROP CONSTRAINT zipchk
# SQL
# end
# end
# end
# end
class IrreversibleMigration < MigrationError
end
class DuplicateMigrationVersionError < MigrationError
# nodoc:
def initialize: (?untyped? version) -> untyped
end
class DuplicateMigrationNameError < MigrationError
# nodoc:
def initialize: (?untyped? name) -> untyped
end
class UnknownMigrationVersionError < MigrationError
# nodoc:
def initialize: (?untyped? version) -> untyped
end
class IllegalMigrationNameError < MigrationError
# nodoc:
def initialize: (?untyped? name) -> untyped
end
class PendingMigrationError < MigrationError
# nodoc:
include ActiveSupport::ActionableError
extend ::ActiveSupport::ActionableError::ClassMethods
def initialize: (?untyped? message) -> untyped
end
class ConcurrentMigrationError < MigrationError
# nodoc:
DEFAULT_MESSAGE: ::String
RELEASE_LOCK_FAILED_MESSAGE: ::String
def initialize: (?untyped message) -> untyped
end
class NoEnvironmentInSchemaError < MigrationError
# nodoc:
def initialize: () -> untyped
end
class ProtectedEnvironmentError < ActiveRecordError
# nodoc:
def initialize: (?::String env) -> untyped
end
class EnvironmentMismatchError < ActiveRecordError
def initialize: (?stored: untyped? stored, ?current: untyped? current) -> untyped
end
# = Active Record Migrations
#
# Migrations can manage the evolution of a schema used by several physical
# databases. It's a solution to the common problem of adding a field to make
# a new feature work in your local database, but being unsure of how to
# push that change to other developers and to the production server. With
# migrations, you can describe the transformations in self-contained classes
# that can be checked into version control systems and executed against
# another database that might be one, two, or five versions behind.
#
# Example of a simple migration:
#
# class AddSsl < ActiveRecord::Migration[5.0]
# def up
# add_column :accounts, :ssl_enabled, :boolean, default: true
# end
#
# def down
# remove_column :accounts, :ssl_enabled
# end
# end
#
# This migration will add a boolean flag to the accounts table and remove it
# if you're backing out of the migration. It shows how all migrations have
# two methods +up+ and +down+ that describes the transformations
# required to implement or remove the migration. These methods can consist
# of both the migration specific methods like +add_column+ and +remove_column+,
# but may also contain regular Ruby code for generating data needed for the
# transformations.
#
# Example of a more complex migration that also needs to initialize data:
#
# class AddSystemSettings < ActiveRecord::Migration[5.0]
# def up
# create_table :system_settings do |t|
# t.string :name
# t.string :label
# t.text :value
# t.string :type
# t.integer :position
# end
#
# SystemSetting.create name: 'notice',
# label: 'Use notice?',
# value: 1
# end
#
# def down
# drop_table :system_settings
# end
# end
#
# This migration first adds the +system_settings+ table, then creates the very
# first row in it using the Active Record model that relies on the table. It
# also uses the more advanced +create_table+ syntax where you can specify a
# complete table schema in one block call.
#
# == Available transformations
#
# === Creation
#
# * create_join_table(table_1, table_2, options): Creates a join
# table having its name as the lexical order of the first two
# arguments. See
# ActiveRecord::ConnectionAdapters::SchemaStatements#create_join_table for
# details.
# * create_table(name, options): Creates a table called +name+ and
# makes the table object available to a block that can then add columns to it,
# following the same format as +add_column+. See example above. The options hash
# is for fragments like "DEFAULT CHARSET=UTF-8" that are appended to the create
# table definition.
# * add_column(table_name, column_name, type, options): Adds a new column
# to the table called +table_name+
# named +column_name+ specified to be one of the following types:
# :string, :text, :integer, :float,
# :decimal, :datetime, :timestamp, :time,
# :date, :binary, :boolean. A default value can be
# specified by passing an +options+ hash like { default: 11 }.
# Other options include :limit and :null (e.g.
# { limit: 50, null: false }) -- see
# ActiveRecord::ConnectionAdapters::TableDefinition#column for details.
# * add_foreign_key(from_table, to_table, options): Adds a new
# foreign key. +from_table+ is the table with the key column, +to_table+ contains
# the referenced primary key.
# * add_index(table_name, column_names, options): Adds a new index
# with the name of the column. Other options include
# :name, :unique (e.g.
# { name: 'users_name_index', unique: true }) and :order
# (e.g. { order: { name: :desc } }).
# * add_reference(:table_name, :reference_name): Adds a new column
# +reference_name_id+ by default an integer. See
# ActiveRecord::ConnectionAdapters::SchemaStatements#add_reference for details.
# * add_timestamps(table_name, options): Adds timestamps (+created_at+
# and +updated_at+) columns to +table_name+.
#
# === Modification
#
# * change_column(table_name, column_name, type, options): Changes
# the column to a different type using the same parameters as add_column.
# * change_column_default(table_name, column_name, default_or_changes):
# Sets a default value for +column_name+ defined by +default_or_changes+ on
# +table_name+. Passing a hash containing :from and :to
# as +default_or_changes+ will make this change reversible in the migration.
# * change_column_null(table_name, column_name, null, default = nil):
# Sets or removes a +NOT NULL+ constraint on +column_name+. The +null+ flag
# indicates whether the value can be +NULL+. See
# ActiveRecord::ConnectionAdapters::SchemaStatements#change_column_null for
# details.
# * change_table(name, options): Allows to make column alterations to
# the table called +name+. It makes the table object available to a block that
# can then add/remove columns, indexes or foreign keys to it.
# * rename_column(table_name, column_name, new_column_name): Renames
# a column but keeps the type and content.
# * rename_index(table_name, old_name, new_name): Renames an index.
# * rename_table(old_name, new_name): Renames the table called +old_name+
# to +new_name+.
#
# === Deletion
#
# * drop_table(name): Drops the table called +name+.
# * drop_join_table(table_1, table_2, options): Drops the join table
# specified by the given arguments.
# * remove_column(table_name, column_name, type, options): Removes the column
# named +column_name+ from the table called +table_name+.
# * remove_columns(table_name, *column_names): Removes the given
# columns from the table definition.
# * remove_foreign_key(from_table, to_table = nil, **options): Removes the
# given foreign key from the table called +table_name+.
# * remove_index(table_name, column: column_names): Removes the index
# specified by +column_names+.
# * remove_index(table_name, name: index_name): Removes the index
# specified by +index_name+.
# * remove_reference(table_name, ref_name, options): Removes the
# reference(s) on +table_name+ specified by +ref_name+.
# * remove_timestamps(table_name, options): Removes the timestamp
# columns (+created_at+ and +updated_at+) from the table definition.
#
# == Irreversible transformations
#
# Some transformations are destructive in a manner that cannot be reversed.
# Migrations of that kind should raise an ActiveRecord::IrreversibleMigration
# exception in their +down+ method.
#
# == Running migrations from within Rails
#
# The Rails package has several tools to help create and apply migrations.
#
# To generate a new migration, you can use
# rails generate migration MyNewMigration
#
# where MyNewMigration is the name of your migration. The generator will
# create an empty migration file timestamp_my_new_migration.rb
# in the db/migrate/ directory where timestamp is the
# UTC formatted date and time that the migration was generated.
#
# There is a special syntactic shortcut to generate migrations that add fields to a table.
#
# rails generate migration add_fieldname_to_tablename fieldname:string
#
# This will generate the file timestamp_add_fieldname_to_tablename.rb, which will look like this:
# class AddFieldnameToTablename < ActiveRecord::Migration[5.0]
# def change
# add_column :tablenames, :fieldname, :string
# end
# end
#
# To run migrations against the currently configured database, use
# rails db:migrate. This will update the database by running all of the
# pending migrations, creating the schema_migrations table
# (see "About the schema_migrations table" section below) if missing. It will also
# invoke the db:schema:dump command, which will update your db/schema.rb file
# to match the structure of your database.
#
# To roll the database back to a previous migration version, use
# rails db:rollback VERSION=X where X is the version to which
# you wish to downgrade. Alternatively, you can also use the STEP option if you
# wish to rollback last few migrations. rails db:rollback STEP=2 will rollback
# the latest two migrations.
#
# If any of the migrations throw an ActiveRecord::IrreversibleMigration exception,
# that step will fail and you'll have some manual work to do.
#
# == Database support
#
# Migrations are currently supported in MySQL, PostgreSQL, SQLite,
# SQL Server, and Oracle (all supported databases except DB2).
#
# == More examples
#
# Not all migrations change the schema. Some just fix the data:
#
# class RemoveEmptyTags < ActiveRecord::Migration[5.0]
# def up
# Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
# end
#
# def down
# # not much we can do to restore deleted data
# raise ActiveRecord::IrreversibleMigration, "Can't recover the deleted tags"
# end
# end
#
# Others remove columns when they migrate up instead of down:
#
# class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[5.0]
# def up
# remove_column :items, :incomplete_items_count
# remove_column :items, :completed_items_count
# end
#
# def down
# add_column :items, :incomplete_items_count
# add_column :items, :completed_items_count
# end
# end
#
# And sometimes you need to do something in SQL not abstracted directly by migrations:
#
# class MakeJoinUnique < ActiveRecord::Migration[5.0]
# def up
# execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
# end
#
# def down
# execute "ALTER TABLE `pages_linked_pages` DROP INDEX `page_id_linked_page_id`"
# end
# end
#
# == Using a model after changing its table
#
# Sometimes you'll want to add a column in a migration and populate it
# immediately after. In that case, you'll need to make a call to
# Base#reset_column_information in order to ensure that the model has the
# latest column data from after the new column was added. Example:
#
# class AddPeopleSalary < ActiveRecord::Migration[5.0]
# def up
# add_column :people, :salary, :integer
# Person.reset_column_information
# Person.all.each do |p|
# p.update_attribute :salary, SalaryCalculator.compute(p)
# end
# end
# end
#
# == Controlling verbosity
#
# By default, migrations will describe the actions they are taking, writing
# them to the console as they happen, along with benchmarks describing how
# long each step took.
#
# You can quiet them down by setting ActiveRecord::Migration.verbose = false.
#
# You can also insert your own messages and benchmarks by using the +say_with_time+
# method:
#
# def up
# ...
# say_with_time "Updating salaries..." do
# Person.all.each do |p|
# p.update_attribute :salary, SalaryCalculator.compute(p)
# end
# end
# ...
# end
#
# The phrase "Updating salaries..." would then be printed, along with the
# benchmark for the block when the block completes.
#
# == Timestamped Migrations
#
# By default, Rails generates migrations that look like:
#
# 20080717013526_your_migration_name.rb
#
# The prefix is a generation timestamp (in UTC).
#
# If you'd prefer to use numeric prefixes, you can turn timestamped migrations
# off by setting:
#
# config.active_record.timestamped_migrations = false
#
# In application.rb.
#
# == Reversible Migrations
#
# Reversible migrations are migrations that know how to go +down+ for you.
# You simply supply the +up+ logic, and the Migration system figures out
# how to execute the down commands for you.
#
# To define a reversible migration, define the +change+ method in your
# migration like this:
#
# class TenderloveMigration < ActiveRecord::Migration[5.0]
# def change
# create_table(:horses) do |t|
# t.column :content, :text
# t.column :remind_at, :datetime
# end
# end
# end
#
# This migration will create the horses table for you on the way up, and
# automatically figure out how to drop the table on the way down.
#
# Some commands cannot be reversed. If you care to define how to move up
# and down in these cases, you should define the +up+ and +down+ methods
# as before.
#
# If a command cannot be reversed, an
# ActiveRecord::IrreversibleMigration exception will be raised when
# the migration is moving down.
#
# For a list of commands that are reversible, please see
# ActiveRecord::Migration::CommandRecorder.
#
# == Transactional Migrations
#
# If the database adapter supports DDL transactions, all migrations will
# automatically be wrapped in a transaction. There are queries that you
# can't execute inside a transaction though, and for these situations
# you can turn the automatic transactions off.
#
# class ChangeEnum < ActiveRecord::Migration[5.0]
# disable_ddl_transaction!
#
# def up
# execute "ALTER TYPE model_size ADD VALUE 'new_value'"
# end
# end
#
# Remember that you can still open your own transactions, even if you
# are in a Migration with self.disable_ddl_transaction!.
class Migration
class Current < Migration
end
def self.inherited: (untyped subclass) -> untyped
def self.[]: (untyped version) -> untyped
def self.current_version: () -> untyped
MigrationFilenameRegexp: untyped
# This class is used to verify that all migrations have been run before
# loading a web page if config.active_record.migration_error is set to :page_load
class CheckPending
def initialize: (untyped app) -> untyped
def call: (untyped env) -> untyped
def connection: () -> untyped
end
attr_accessor delegate: untyped
attr_accessor disable_ddl_transaction: untyped
def self.nearest_delegate: () -> untyped
# Raises ActiveRecord::PendingMigrationError error if any migrations are pending.
def self.check_pending!: (?untyped connection) -> untyped
def self.load_schema_if_pending!: () -> untyped
def self.maintain_test_schema!: () -> untyped
def self.method_missing: (untyped name, *untyped args) { () -> untyped } -> untyped
def self.migrate: (untyped direction) -> untyped
# Disable the transaction wrapping this migration.
# You can still create your own transactions even after calling #disable_ddl_transaction!
#
# For more details read the {"Transactional Migrations" section above}[rdoc-ref:Migration].
def self.disable_ddl_transaction!: () -> untyped
def disable_ddl_transaction: () -> untyped
attr_accessor name: untyped
attr_accessor version: untyped
def initialize: (?untyped name, ?untyped? version) -> untyped
# Reverses the migration commands for the given block and
# the given migrations.
#
# The following migration will remove the table 'horses'
# and create the table 'apples' on the way up, and the reverse
# on the way down.
#
# class FixTLMigration < ActiveRecord::Migration[5.0]
# def change
# revert do
# create_table(:horses) do |t|
# t.text :content
# t.datetime :remind_at
# end
# end
# create_table(:apples) do |t|
# t.string :variety
# end
# end
# end
#
# Or equivalently, if +TenderloveMigration+ is defined as in the
# documentation for Migration:
#
# require_relative '20121212123456_tenderlove_migration'
#
# class FixupTLMigration < ActiveRecord::Migration[5.0]
# def change
# revert TenderloveMigration
#
# create_table(:apples) do |t|
# t.string :variety
# end
# end
# end
#
# This command can be nested.
def revert: (*untyped migration_classes) { () -> untyped } -> untyped
def reverting?: () -> untyped
class ReversibleBlockHelper < ::Struct[untyped]
attr_accessor reverting(): untyped
# nodoc:
def up: () { () -> untyped } -> untyped
def down: () { () -> untyped } -> untyped
end
# Used to specify an operation that can be run in one direction or another.
# Call the methods +up+ and +down+ of the yielded object to run a block
# only in one given direction.
# The whole block will be called in the right order within the migration.
#
# In the following example, the looping on users will always be done
# when the three columns 'first_name', 'last_name' and 'full_name' exist,
# even when migrating down:
#
# class SplitNameMigration < ActiveRecord::Migration[5.0]
# def change
# add_column :users, :first_name, :string
# add_column :users, :last_name, :string
#
# reversible do |dir|
# User.reset_column_information
# User.all.each do |u|
# dir.up { u.first_name, u.last_name = u.full_name.split(' ') }
# dir.down { u.full_name = "#{u.first_name} #{u.last_name}" }
# u.save
# end
# end
#
# revert { add_column :users, :full_name, :string }
# end
# end
def reversible: () { (untyped) -> untyped } -> untyped
# Used to specify an operation that is only run when migrating up
# (for example, populating a new column with its initial values).
#
# In the following example, the new column +published+ will be given
# the value +true+ for all existing records.
#
# class AddPublishedToPosts < ActiveRecord::Migration[5.2]
# def change
# add_column :posts, :published, :boolean, default: false
# up_only do
# execute "update posts set published = 'true'"
# end
# end
# end
def up_only: () { () -> untyped } -> untyped
# Runs the given migration classes.
# Last argument can specify options:
# - :direction (default is :up)
# - :revert (default is false)
def run: (*untyped migration_classes) -> untyped
def up: () -> (nil | untyped)
def down: () -> (nil | untyped)
# Execute this migration in the named direction
def migrate: (untyped direction) -> (nil | untyped)
def exec_migration: (untyped conn, untyped direction) -> untyped
def write: (?::String text) -> untyped
def announce: (untyped message) -> untyped
# Takes a message argument and outputs it as is.
# A second boolean argument can be passed to specify whether to indent or not.
def say: (untyped message, ?bool subitem) -> untyped
# Outputs text along with how long it took to run its block.
# If the block returns an integer it assumes it is the number of rows affected.
def say_with_time: (untyped message) { () -> untyped } -> untyped
# Takes a block as an argument and suppresses any output generated by the block.
def suppress_messages: () { () -> untyped } -> untyped
def connection: () -> untyped
def method_missing: (untyped method, *untyped arguments) { () -> untyped } -> untyped
def copy: (untyped destination, untyped sources, ?::Hash[untyped, untyped] options) -> untyped
# Finds the correct table name given an Active Record object.
# Uses the Active Record object's own table_name, or pre/suffix from the
# options passed in.
def proper_table_name: (untyped name, ?::Hash[untyped, untyped] options) -> untyped
# Determines the version number of the next migration.
def next_migration_number: (untyped number) -> untyped
def table_name_options: (?untyped config) -> { table_name_prefix: untyped, table_name_suffix: untyped }
def execute_block: () { () -> untyped } -> untyped
def command_recorder: () -> CommandRecorder
end
# MigrationProxy is used to defer loading of the actual migration classes
# until they are needed
class MigrationProxy < ::Struct[untyped]
attr_accessor name(): untyped
attr_accessor version(): untyped
attr_accessor filename(): untyped
attr_accessor scope(): untyped
def initialize: (untyped name, untyped version, untyped filename, untyped scope) -> untyped
def basename: () -> untyped
def mtime: () -> untyped
def migration: () -> untyped
def load_migration: () -> untyped
end
class NullMigration < MigrationProxy
# nodoc:
def initialize: () -> untyped
def mtime: () -> 0
end
class MigrationContext
# nodoc:
attr_reader migrations_paths: untyped
# nodoc:
attr_reader schema_migration: untyped
def initialize: (untyped migrations_paths, untyped schema_migration) -> untyped
def migrate: (?untyped? target_version) { () -> untyped } -> untyped
def rollback: (?::Integer steps) -> untyped
def forward: (?::Integer steps) -> untyped
def up: (?untyped? target_version) { (untyped) -> untyped } -> untyped
def down: (?untyped? target_version) { (untyped) -> untyped } -> untyped
def run: (untyped direction, untyped target_version) -> untyped
def open: () -> Migrator
def get_all_versions: () -> untyped
def current_version: () -> untyped
def needs_migration?: () -> untyped
def any_migrations?: () -> untyped
def last_migration: () -> untyped
def migrations: () -> untyped
def migrations_status: () -> untyped
def current_environment: () -> untyped
def protected_environment?: () -> untyped
def last_stored_environment: () -> (nil | untyped)
def migration_files: () -> untyped
def parse_migration_filename: (untyped filename) -> untyped
def move: (untyped direction, untyped steps) -> untyped
end
class Migrator
attr_accessor migrations_paths: untyped
# For cases where a table doesn't exist like loading from schema cache
def self.current_version: () -> untyped
def initialize: (untyped direction, untyped migrations, untyped schema_migration, ?untyped? target_version) -> untyped
def current_version: () -> untyped
def current_migration: () -> untyped
def run: () -> untyped
def migrate: () -> untyped
def runnable: () -> untyped
def migrations: () -> untyped
def pending_migrations: () -> untyped
def migrated: () -> untyped
def load_migrated: () -> untyped
# Used for running a specific migration.
def run_without_lock: () -> untyped
# Used for running multiple migrations up to or down to a certain value.
def migrate_without_lock: () -> untyped
# Stores the current environment in the database.
def record_environment: () -> (nil | untyped)
def ran?: (untyped migration) -> untyped
# Return true if a valid version is not provided.
def invalid_target?: () -> untyped
def execute_migration_in_transaction: (untyped migration, untyped direction) -> untyped
def target: () -> untyped
def finish: () -> untyped
def start: () -> untyped
def validate: (untyped migrations) -> untyped
def record_version_state_after_migrating: (untyped version) -> untyped
def up?: () -> untyped
def down?: () -> untyped
# Wrap the migration in a transaction only if supported by the adapter.
def ddl_transaction: (untyped migration) { () -> untyped } -> untyped
def use_transaction?: (untyped migration) -> untyped
def use_advisory_lock?: () -> untyped
def with_advisory_lock: () { () -> untyped } -> untyped
MIGRATOR_SALT: ::Integer
def generate_migrator_advisory_lock_id: () -> untyped
end
end
module ActiveRecord
module ModelSchema
extend ActiveSupport::Concern
def self.derive_join_table_name: (untyped first_table, untyped second_table) -> untyped
module ClassMethods
# Guesses the table name (in forced lower-case) based on the name of the class in the
# inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy
# looks like: Reply < Message < ActiveRecord::Base, then Message is used
# to guess the table name even when called on Reply. The rules used to do the guess
# are handled by the Inflector class in Active Support, which knows almost all common
# English inflections. You can add new inflections in config/initializers/inflections.rb.
#
# Nested classes are given table names prefixed by the singular form of
# the parent's table name. Enclosing modules are not considered.
#
# ==== Examples
#
# class Invoice < ActiveRecord::Base
# end
#
# file class table_name
# invoice.rb Invoice invoices
#
# class Invoice < ActiveRecord::Base
# class Lineitem < ActiveRecord::Base
# end
# end
#
# file class table_name
# invoice.rb Invoice::Lineitem invoice_lineitems
#
# module Invoice
# class Lineitem < ActiveRecord::Base
# end
# end
#
# file class table_name
# invoice/lineitem.rb Invoice::Lineitem lineitems
#
# Additionally, the class-level +table_name_prefix+ is prepended and the
# +table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
# the table name guess for an Invoice class becomes "myapp_invoices".
# Invoice::Lineitem becomes "myapp_invoice_lineitems".
#
# You can also set your own table name explicitly:
#
# class Mouse < ActiveRecord::Base
# self.table_name = "mice"
# end
def table_name: () -> untyped
# Sets the table name explicitly. Example:
#
# class Project < ActiveRecord::Base
# self.table_name = "project"
# end
def table_name=: (untyped value) -> (nil | untyped)
# Returns a quoted version of the table name, used to construct SQL statements.
def quoted_table_name: () -> untyped
def reset_table_name: () -> untyped
def full_table_name_prefix: () -> untyped
def full_table_name_suffix: () -> untyped
# The array of names of environments where destructive actions should be prohibited. By default,
# the value is ["production"].
def protected_environments: () -> untyped
# Sets an array of names of environments where destructive actions should be prohibited.
def protected_environments=: (untyped environments) -> untyped
# Defines the name of the table column which will store the class name on single-table
# inheritance situations.
#
# The default inheritance column name is +type+, which means it's a
# reserved word inside Active Record. To be able to use single-table
# inheritance with another column name, or to use the column +type+ in
# your own model for something else, you can set +inheritance_column+:
#
# self.inheritance_column = 'zoink'
def inheritance_column: () -> untyped
# Sets the value of inheritance_column
def inheritance_column=: (untyped value) -> untyped
# The list of columns names the model should ignore. Ignored columns won't have attribute
# accessors defined, and won't be referenced in SQL queries.
def ignored_columns: () -> untyped
# Sets the columns names the model should ignore. Ignored columns won't have attribute
# accessors defined, and won't be referenced in SQL queries.
def ignored_columns=: (untyped columns) -> untyped
def sequence_name: () -> untyped
def reset_sequence_name: () -> untyped
# Sets the name of the sequence to use when generating ids to the given
# value, or (if the value is +nil+ or +false+) to the value returned by the
# given block. This is required for Oracle and is useful for any
# database which relies on sequences for primary key generation.
#
# If a sequence name is not explicitly set when using Oracle,
# it will default to the commonly used pattern of: #{table_name}_seq
#
# If a sequence name is not explicitly set when using PostgreSQL, it
# will discover the sequence corresponding to your primary key for you.
#
# class Project < ActiveRecord::Base
# self.sequence_name = "projectseq" # default would have been "project_seq"
# end
def sequence_name=: (untyped value) -> untyped
# Determines if the primary key values should be selected from their
# corresponding sequence before the insert statement.
def prefetch_primary_key?: () -> untyped
# Returns the next value that will be used as the primary key on
# an insert statement.
def next_sequence_value: () -> untyped
# Indicates whether the table associated with this class exists
def table_exists?: () -> untyped
def attributes_builder: () -> untyped
def columns_hash: () -> untyped
def columns: () -> untyped
def attribute_types: () -> untyped
def yaml_encoder: () -> untyped
# Returns the type of the attribute with the given name, after applying
# all modifiers. This method is the only valid source of information for
# anything related to the types of a model's attributes. This method will
# access the database and load the model's schema if it is required.
#
# The return value of this method will implement the interface described
# by ActiveModel::Type::Value (though the object itself may not subclass
# it).
#
# +attr_name+ The name of the attribute to retrieve the type for. Must be
# a string or a symbol.
def type_for_attribute: (untyped attr_name) { () -> untyped } -> untyped
# Returns a hash where the keys are column names and the values are
# default values when instantiating the Active Record object for this table.
def column_defaults: () -> untyped
def _default_attributes: () -> untyped
# Returns an array of column names as strings.
def column_names: () -> untyped
def symbol_column_to_string: (untyped name_symbol) -> untyped
# Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
# and columns used for single table inheritance have been removed.
def content_columns: () -> untyped
# Resets all the cached information about columns, which will cause them
# to be reloaded on the next request.
#
# The most common usage pattern for this method is probably in a migration,
# when just after creating a table you want to populate it with some default
# values, eg:
#
# class CreateJobLevels < ActiveRecord::Migration[5.0]
# def up
# create_table :job_levels do |t|
# t.integer :id
# t.string :name
#
# t.timestamps
# end
#
# JobLevel.reset_column_information
# %w{assistant executive manager director}.each do |type|
# JobLevel.create(name: type)
# end
# end
#
# def down
# drop_table :job_levels
# end
# end
def reset_column_information: () -> untyped
def initialize_load_schema_monitor: () -> untyped
def inherited: (untyped child_class) -> untyped
def schema_loaded?: () -> untyped
def load_schema: () -> (nil | untyped)
def load_schema!: () -> untyped
def reload_schema_from_cache: () -> untyped
# Guesses the table name, but does not decorate it with prefix and suffix information.
def undecorated_table_name: (?untyped class_name) -> untyped
# Computes and returns a table name according to default conventions.
def compute_table_name: () -> untyped
end
end
end
module ActiveRecord
module NestedAttributes
# nodoc:
class TooManyRecords < ActiveRecordError
end
extend ActiveSupport::Concern
# = Active Record Nested Attributes
#
# Nested attributes allow you to save attributes on associated records
# through the parent. By default nested attribute updating is turned off
# and you can enable it using the accepts_nested_attributes_for class
# method. When you enable nested attributes an attribute writer is
# defined on the model.
#
# The attribute writer is named after the association, which means that
# in the following example, two new methods are added to your model:
#
# author_attributes=(attributes) and
# pages_attributes=(attributes).
#
# class Book < ActiveRecord::Base
# has_one :author
# has_many :pages
#
# accepts_nested_attributes_for :author, :pages
# end
#
# Note that the :autosave option is automatically enabled on every
# association that accepts_nested_attributes_for is used for.
#
# === One-to-one
#
# Consider a Member model that has one Avatar:
#
# class Member < ActiveRecord::Base
# has_one :avatar
# accepts_nested_attributes_for :avatar
# end
#
# Enabling nested attributes on a one-to-one association allows you to
# create the member and avatar in one go:
#
# params = { member: { name: 'Jack', avatar_attributes: { icon: 'smiling' } } }
# member = Member.create(params[:member])
# member.avatar.id # => 2
# member.avatar.icon # => 'smiling'
#
# It also allows you to update the avatar through the member:
#
# params = { member: { avatar_attributes: { id: '2', icon: 'sad' } } }
# member.update params[:member]
# member.avatar.icon # => 'sad'
#
# If you want to update the current avatar without providing the id, you must add :update_only option.
#
# class Member < ActiveRecord::Base
# has_one :avatar
# accepts_nested_attributes_for :avatar, update_only: true
# end
#
# params = { member: { avatar_attributes: { icon: 'sad' } } }
# member.update params[:member]
# member.avatar.id # => 2
# member.avatar.icon # => 'sad'
#
# By default you will only be able to set and update attributes on the
# associated model. If you want to destroy the associated model through the
# attributes hash, you have to enable it first using the
# :allow_destroy option.
#
# class Member < ActiveRecord::Base
# has_one :avatar
# accepts_nested_attributes_for :avatar, allow_destroy: true
# end
#
# Now, when you add the _destroy key to the attributes hash, with a
# value that evaluates to +true+, you will destroy the associated model:
#
# member.avatar_attributes = { id: '2', _destroy: '1' }
# member.avatar.marked_for_destruction? # => true
# member.save
# member.reload.avatar # => nil
#
# Note that the model will _not_ be destroyed until the parent is saved.
#
# Also note that the model will not be destroyed unless you also specify
# its id in the updated hash.
#
# === One-to-many
#
# Consider a member that has a number of posts:
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts
# end
#
# You can now set or update attributes on the associated posts through
# an attribute hash for a member: include the key +:posts_attributes+
# with an array of hashes of post attributes as a value.
#
# For each hash that does _not_ have an id key a new record will
# be instantiated, unless the hash also contains a _destroy key
# that evaluates to +true+.
#
# params = { member: {
# name: 'joe', posts_attributes: [
# { title: 'Kari, the awesome Ruby documentation browser!' },
# { title: 'The egalitarian assumption of the modern citizen' },
# { title: '', _destroy: '1' } # this will be ignored
# ]
# }}
#
# member = Member.create(params[:member])
# member.posts.length # => 2
# member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
# member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
#
# You may also set a +:reject_if+ proc to silently ignore any new record
# hashes if they fail to pass your criteria. For example, the previous
# example could be rewritten as:
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, reject_if: proc { |attributes| attributes['title'].blank? }
# end
#
# params = { member: {
# name: 'joe', posts_attributes: [
# { title: 'Kari, the awesome Ruby documentation browser!' },
# { title: 'The egalitarian assumption of the modern citizen' },
# { title: '' } # this will be ignored because of the :reject_if proc
# ]
# }}
#
# member = Member.create(params[:member])
# member.posts.length # => 2
# member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
# member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
#
# Alternatively, +:reject_if+ also accepts a symbol for using methods:
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, reject_if: :new_record?
# end
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, reject_if: :reject_posts
#
# def reject_posts(attributes)
# attributes['title'].blank?
# end
# end
#
# If the hash contains an id key that matches an already
# associated record, the matching record will be modified:
#
# member.attributes = {
# name: 'Joe',
# posts_attributes: [
# { id: 1, title: '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' },
# { id: 2, title: '[UPDATED] other post' }
# ]
# }
#
# member.posts.first.title # => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!'
# member.posts.second.title # => '[UPDATED] other post'
#
# However, the above applies if the parent model is being updated as well.
# For example, If you wanted to create a +member+ named _joe_ and wanted to
# update the +posts+ at the same time, that would give an
# ActiveRecord::RecordNotFound error.
#
# By default the associated records are protected from being destroyed. If
# you want to destroy any of the associated records through the attributes
# hash, you have to enable it first using the :allow_destroy
# option. This will allow you to also use the _destroy key to
# destroy existing records:
#
# class Member < ActiveRecord::Base
# has_many :posts
# accepts_nested_attributes_for :posts, allow_destroy: true
# end
#
# params = { member: {
# posts_attributes: [{ id: '2', _destroy: '1' }]
# }}
#
# member.attributes = params[:member]
# member.posts.detect { |p| p.id == 2 }.marked_for_destruction? # => true
# member.posts.length # => 2
# member.save
# member.reload.posts.length # => 1
#
# Nested attributes for an associated collection can also be passed in
# the form of a hash of hashes instead of an array of hashes:
#
# Member.create(
# name: 'joe',
# posts_attributes: {
# first: { title: 'Foo' },
# second: { title: 'Bar' }
# }
# )
#
# has the same effect as
#
# Member.create(
# name: 'joe',
# posts_attributes: [
# { title: 'Foo' },
# { title: 'Bar' }
# ]
# )
#
# The keys of the hash which is the value for +:posts_attributes+ are
# ignored in this case.
# However, it is not allowed to use 'id' or :id for one of
# such keys, otherwise the hash will be wrapped in an array and
# interpreted as an attribute hash for a single post.
#
# Passing attributes for an associated collection in the form of a hash
# of hashes can be used with hashes generated from HTTP/HTML parameters,
# where there may be no natural way to submit an array of hashes.
#
# === Saving
#
# All changes to models, including the destruction of those marked for
# destruction, are saved and destroyed automatically and atomically when
# the parent model is saved. This happens inside the transaction initiated
# by the parent's save method. See ActiveRecord::AutosaveAssociation.
#
# === Validating the presence of a parent model
#
# If you want to validate that a child record is associated with a parent
# record, you can use the +validates_presence_of+ method and the +:inverse_of+
# key as this example illustrates:
#
# class Member < ActiveRecord::Base
# has_many :posts, inverse_of: :member
# accepts_nested_attributes_for :posts
# end
#
# class Post < ActiveRecord::Base
# belongs_to :member, inverse_of: :posts
# validates_presence_of :member
# end
#
# Note that if you do not specify the +:inverse_of+ option, then
# Active Record will try to automatically guess the inverse association
# based on heuristics.
#
# For one-to-one nested associations, if you build the new (in-memory)
# child object yourself before assignment, then this module will not
# overwrite it, e.g.:
#
# class Member < ActiveRecord::Base
# has_one :avatar
# accepts_nested_attributes_for :avatar
#
# def avatar
# super || build_avatar(width: 200)
# end
# end
#
# member = Member.new
# member.avatar_attributes = {icon: 'sad'}
# member.avatar.width # => 200
module ClassMethods
REJECT_ALL_BLANK_PROC: untyped
# Defines an attributes writer for the specified association(s).
#
# Supported options:
# [:allow_destroy]
# If true, destroys any members from the attributes hash with a
# _destroy key and a value that evaluates to +true+
# (eg. 1, '1', true, or 'true'). This option is off by default.
# [:reject_if]
# Allows you to specify a Proc or a Symbol pointing to a method
# that checks whether a record should be built for a certain attribute
# hash. The hash is passed to the supplied Proc or the method
# and it should return either +true+ or +false+. When no +:reject_if+
# is specified, a record will be built for all attribute hashes that
# do not have a _destroy value that evaluates to true.
# Passing :all_blank instead of a Proc will create a proc
# that will reject a record where all the attributes are blank excluding
# any value for +_destroy+.
# [:limit]
# Allows you to specify the maximum number of associated records that
# can be processed with the nested attributes. Limit also can be specified
# as a Proc or a Symbol pointing to a method that should return a number.
# If the size of the nested attributes array exceeds the specified limit,
# NestedAttributes::TooManyRecords exception is raised. If omitted, any
# number of associations can be processed.
# Note that the +:limit+ option is only applicable to one-to-many
# associations.
# [:update_only]
# For a one-to-one association, this option allows you to specify how
# nested attributes are going to be used when an associated record already
# exists. In general, an existing record may either be updated with the
# new set of attribute values or be replaced by a wholly new record
# containing those values. By default the +:update_only+ option is +false+
# and the nested attributes are used to update the existing record only
# if they include the record's :id value. Otherwise a new
# record will be instantiated and used to replace the existing one.
# However if the +:update_only+ option is +true+, the nested attributes
# are used to update the record's attributes always, regardless of
# whether the :id is present. The option is ignored for collection
# associations.
#
# Examples:
# # creates avatar_attributes=
# accepts_nested_attributes_for :avatar, reject_if: proc { |attributes| attributes['name'].blank? }
# # creates avatar_attributes=
# accepts_nested_attributes_for :avatar, reject_if: :all_blank
# # creates avatar_attributes= and posts_attributes=
# accepts_nested_attributes_for :avatar, :posts, allow_destroy: true
def accepts_nested_attributes_for: (*untyped attr_names) -> untyped
# Generates a writer method for this association. Serves as a point for
# accessing the objects in the association. For example, this method
# could generate the following:
#
# def pirate_attributes=(attributes)
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
# end
#
# This redirects the attempts to write objects in an association through
# the helper methods defined below. Makes it seem like the nested
# associations are just regular associations.
def generate_association_writer: (untyped association_name, untyped `type`) -> untyped
end
# Returns ActiveRecord::AutosaveAssociation::marked_for_destruction? It's
# used in conjunction with fields_for to build a form element for the
# destruction of this association.
#
# See ActionView::Helpers::FormHelper::fields_for for more info.
def _destroy: () -> untyped
# Attribute hash keys that should not be assigned as normal attributes.
# These hash keys are nested attributes implementation details.
UNASSIGNABLE_KEYS: ::Array[untyped]
# Assigns the given attributes to the association.
#
# If an associated record does not yet exist, one will be instantiated. If
# an associated record already exists, the method's behavior depends on
# the value of the update_only option. If update_only is +false+ and the
# given attributes include an :id that matches the existing record's
# id, then the existing record will be modified. If no :id is provided
# it will be replaced with a new record. If update_only is +true+ the existing
# record will be modified regardless of whether an :id is provided.
#
# If the given attributes include a matching :id attribute, or
# update_only is true, and a :_destroy key set to a truthy value,
# then the existing record will be marked for destruction.
def assign_nested_attributes_for_one_to_one_association: (untyped association_name, untyped attributes) -> untyped
# Assigns the given attributes to the collection association.
#
# Hashes with an :id value matching an existing associated record
# will update that record. Hashes without an :id value will build
# a new record for the association. Hashes with a matching :id
# value and a :_destroy key set to a truthy value will mark the
# matched record for destruction.
#
# For example:
#
# assign_nested_attributes_for_collection_association(:people, {
# '1' => { id: '1', name: 'Peter' },
# '2' => { name: 'John' },
# '3' => { id: '2', _destroy: true }
# })
#
# Will update the name of the Person with ID 1, build a new associated
# person with the name 'John', and mark the associated Person with ID 2
# for destruction.
#
# Also accepts an Array of attribute hashes:
#
# assign_nested_attributes_for_collection_association(:people, [
# { id: '1', name: 'Peter' },
# { name: 'John' },
# { id: '2', _destroy: true }
# ])
def assign_nested_attributes_for_collection_association: (untyped association_name, untyped attributes_collection) -> untyped
# Takes in a limit and checks if the attributes_collection has too many
# records. It accepts limit in the form of symbol, proc, or
# number-like object (anything that can be compared with an integer).
#
# Raises TooManyRecords error if the attributes_collection is
# larger than the limit.
def check_record_limit!: (untyped limit, untyped attributes_collection) -> untyped
# Updates a record with the +attributes+ or marks it for destruction if
# +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
def assign_to_or_mark_for_destruction: (untyped record, untyped attributes, untyped allow_destroy) -> untyped
# Determines if a hash contains a truthy _destroy key.
def has_destroy_flag?: (untyped hash) -> untyped
# Determines if a new record should be rejected by checking
# has_destroy_flag? or if a :reject_if proc exists for this
# association and evaluates to +true+.
def reject_new_record?: (untyped association_name, untyped attributes) -> untyped
# Determines if a record with the particular +attributes+ should be
# rejected by calling the reject_if Symbol or Proc (if defined).
# The reject_if option is defined by +accepts_nested_attributes_for+.
#
# Returns false if there is a +destroy_flag+ on the attributes.
def call_reject_if: (untyped association_name, untyped attributes) -> (::FalseClass | untyped)
# Only take into account the destroy flag if :allow_destroy is true
def will_be_destroyed?: (untyped association_name, untyped attributes) -> untyped
def allow_destroy?: (untyped association_name) -> untyped
def raise_nested_attributes_record_not_found!: (untyped association_name, untyped record_id) -> untyped
end
end
module ActiveRecord
# = Active Record No Touching
module NoTouching
extend ActiveSupport::Concern
module ClassMethods
# Lets you selectively disable calls to +touch+ for the
# duration of a block.
#
# ==== Examples
# ActiveRecord::Base.no_touching do
# Project.first.touch # does nothing
# Message.first.touch # does nothing
# end
#
# Project.no_touching do
# Project.first.touch # does nothing
# Message.first.touch # works, but does not touch the associated project
# end
#
def no_touching: () { () -> untyped } -> untyped
end
def self.apply_to: (untyped klass) { () -> untyped } -> untyped
def self.applied_to?: (untyped klass) -> untyped
def self.klasses: () -> untyped
# Returns +true+ if the class has +no_touching+ set, +false+ otherwise.
#
# Project.no_touching do
# Project.first.no_touching? # true
# Message.first.no_touching? # false
# end
#
def no_touching?: () -> untyped
def touch_later: () -> untyped
def touch: () -> untyped
end
end
module ActiveRecord
module NullRelation
# :nodoc:
def pluck: (*untyped column_names) -> ::Array[untyped]
def delete_all: () -> 0
def update_all: (untyped _updates) -> 0
def delete: (untyped _id_or_array) -> 0
def empty?: () -> ::TrueClass
def none?: () -> ::TrueClass
def any?: () -> ::FalseClass
def one?: () -> ::FalseClass
def many?: () -> ::FalseClass
def to_sql: () -> ::String
def calculate: (untyped operation, untyped _column_name) -> untyped
def exists?: (?::Symbol _conditions) -> ::FalseClass
def or: (untyped other) -> untyped
def exec_queries: () -> untyped
end
end
module ActiveRecord
# = Active Record \Persistence
module Persistence
extend ActiveSupport::Concern
module ClassMethods
# Creates an object (or multiple objects) and saves it to the database, if validations pass.
# The resulting object is returned whether the object was saved successfully to the database or not.
#
# The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the
# attributes on the objects that are to be created.
#
# ==== Examples
# # Create a single new object
# User.create(first_name: 'Jamie')
#
# # Create an Array of new objects
# User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
#
# # Create a single object and pass it into a block to set other attributes.
# User.create(first_name: 'Jamie') do |u|
# u.is_admin = false
# end
#
# # Creating an Array of new objects using a block, where the block is executed for each object:
# User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
# u.is_admin = false
# end
def create: (?untyped? attributes) { () -> untyped } -> untyped
# Creates an object (or multiple objects) and saves it to the database,
# if validations pass. Raises a RecordInvalid error if validations fail,
# unlike Base#create.
#
# The +attributes+ parameter can be either a Hash or an Array of Hashes.
# These describe which attributes to be created on the object, or
# multiple objects when given an Array of Hashes.
def create!: (?untyped? attributes) { () -> untyped } -> untyped
# Inserts a single record into the database in a single SQL INSERT
# statement. It does not instantiate any models nor does it trigger
# Active Record callbacks or validations. Though passed values
# go through Active Record's type casting and serialization.
#
# See ActiveRecord::Persistence#insert_all for documentation.
def insert: (untyped attributes, ?unique_by: untyped? unique_by, ?returning: untyped? returning) -> untyped
# Inserts multiple records into the database in a single SQL INSERT
# statement. It does not instantiate any models nor does it trigger
# Active Record callbacks or validations. Though passed values
# go through Active Record's type casting and serialization.
#
# The +attributes+ parameter is an Array of Hashes. Every Hash determines
# the attributes for a single row and must have the same keys.
#
# Rows are considered to be unique by every unique index on the table. Any
# duplicate rows are skipped.
# Override with :unique_by (see below).
#
# Returns an ActiveRecord::Result with its contents based on
# :returning (see below).
#
# ==== Options
#
# [:returning]
# (PostgreSQL only) An array of attributes to return for all successfully
# inserted records, which by default is the primary key.
# Pass returning: %w[ id name ] for both id and name
# or returning: false to omit the underlying RETURNING SQL
# clause entirely.
#
# [:unique_by]
# (PostgreSQL and SQLite only) By default rows are considered to be unique
# by every unique index on the table. Any duplicate rows are skipped.
#
# To skip rows according to just one unique index pass :unique_by.
#
# Consider a Book model where no duplicate ISBNs make sense, but if any
# row has an existing id, or is not unique by another unique index,
# ActiveRecord::RecordNotUnique is raised.
#
# Unique indexes can be identified by columns or name:
#
# unique_by: :isbn
# unique_by: %i[ author_id name ]
# unique_by: :index_books_on_isbn
#
# Because it relies on the index information from the database
# :unique_by is recommended to be paired with
# Active Record's schema_cache.
#
# ==== Example
#
# # Insert records and skip inserting any duplicates.
# # Here "Eloquent Ruby" is skipped because its id is not unique.
#
# Book.insert_all([
# { id: 1, title: "Rework", author: "David" },
# { id: 1, title: "Eloquent Ruby", author: "Russ" }
# ])
def insert_all: (untyped attributes, ?unique_by: untyped? unique_by, ?returning: untyped? returning) -> untyped
# Inserts a single record into the database in a single SQL INSERT
# statement. It does not instantiate any models nor does it trigger
# Active Record callbacks or validations. Though passed values
# go through Active Record's type casting and serialization.
#
# See ActiveRecord::Persistence#insert_all! for more.
def insert!: (untyped attributes, ?returning: untyped? returning) -> untyped
# Inserts multiple records into the database in a single SQL INSERT
# statement. It does not instantiate any models nor does it trigger
# Active Record callbacks or validations. Though passed values
# go through Active Record's type casting and serialization.
#
# The +attributes+ parameter is an Array of Hashes. Every Hash determines
# the attributes for a single row and must have the same keys.
#
# Raises ActiveRecord::RecordNotUnique if any rows violate a
# unique index on the table. In that case, no rows are inserted.
#
# To skip duplicate rows, see ActiveRecord::Persistence#insert_all.
# To replace them, see ActiveRecord::Persistence#upsert_all.
#
# Returns an ActiveRecord::Result with its contents based on
# :returning (see below).
#
# ==== Options
#
# [:returning]
# (PostgreSQL only) An array of attributes to return for all successfully
# inserted records, which by default is the primary key.
# Pass returning: %w[ id name ] for both id and name
# or returning: false to omit the underlying RETURNING SQL
# clause entirely.
#
# ==== Examples
#
# # Insert multiple records
# Book.insert_all!([
# { title: "Rework", author: "David" },
# { title: "Eloquent Ruby", author: "Russ" }
# ])
#
# # Raises ActiveRecord::RecordNotUnique because "Eloquent Ruby"
# # does not have a unique id.
# Book.insert_all!([
# { id: 1, title: "Rework", author: "David" },
# { id: 1, title: "Eloquent Ruby", author: "Russ" }
# ])
def insert_all!: (untyped attributes, ?returning: untyped? returning) -> untyped
# Updates or inserts (upserts) a single record into the database in a
# single SQL INSERT statement. It does not instantiate any models nor does
# it trigger Active Record callbacks or validations. Though passed values
# go through Active Record's type casting and serialization.
#
# See ActiveRecord::Persistence#upsert_all for documentation.
def upsert: (untyped attributes, ?unique_by: untyped? unique_by, ?returning: untyped? returning) -> untyped
# Updates or inserts (upserts) multiple records into the database in a
# single SQL INSERT statement. It does not instantiate any models nor does
# it trigger Active Record callbacks or validations. Though passed values
# go through Active Record's type casting and serialization.
#
# The +attributes+ parameter is an Array of Hashes. Every Hash determines
# the attributes for a single row and must have the same keys.
#
# Returns an ActiveRecord::Result with its contents based on
# :returning (see below).
#
# ==== Options
#
# [:returning]
# (PostgreSQL only) An array of attributes to return for all successfully
# inserted records, which by default is the primary key.
# Pass returning: %w[ id name ] for both id and name
# or returning: false to omit the underlying RETURNING SQL
# clause entirely.
#
# [:unique_by]
# (PostgreSQL and SQLite only) By default rows are considered to be unique
# by every unique index on the table. Any duplicate rows are skipped.
#
# To skip rows according to just one unique index pass :unique_by.
#
# Consider a Book model where no duplicate ISBNs make sense, but if any
# row has an existing id, or is not unique by another unique index,
# ActiveRecord::RecordNotUnique is raised.
#
# Unique indexes can be identified by columns or name:
#
# unique_by: :isbn
# unique_by: %i[ author_id name ]
# unique_by: :index_books_on_isbn
#
# Because it relies on the index information from the database
# :unique_by is recommended to be paired with
# Active Record's schema_cache.
#
# ==== Examples
#
# # Inserts multiple records, performing an upsert when records have duplicate ISBNs.
# # Here "Eloquent Ruby" overwrites "Rework" because its ISBN is duplicate.
#
# Book.upsert_all([
# { title: "Rework", author: "David", isbn: "1" },
# { title: "Eloquent Ruby", author: "Russ", isbn: "1" }
# ], unique_by: :isbn)
#
# Book.find_by(isbn: "1").title # => "Eloquent Ruby"
def upsert_all: (untyped attributes, ?unique_by: untyped? unique_by, ?returning: untyped? returning) -> untyped
# Given an attributes hash, +instantiate+ returns a new instance of
# the appropriate class. Accepts only keys as strings.
#
# For example, +Post.all+ may return Comments, Messages, and Emails
# by storing the record's subclass in a +type+ attribute. By calling
# +instantiate+ instead of +new+, finder methods ensure they get new
# instances of the appropriate class for each record.
#
# See ActiveRecord::Inheritance#discriminate_class_for_record to see
# how this "single-table" inheritance mapping is implemented.
def instantiate: (untyped attributes, ?::Hash[untyped, untyped] column_types) { () -> untyped } -> untyped
# Updates an object (or multiple objects) and saves it to the database, if validations pass.
# The resulting object is returned whether the object was saved successfully to the database or not.
#
# ==== Parameters
#
# * +id+ - This should be the id or an array of ids to be updated.
# * +attributes+ - This should be a hash of attributes or an array of hashes.
#
# ==== Examples
#
# # Updates one record
# Person.update(15, user_name: "Samuel", group: "expert")
#
# # Updates multiple records
# people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
# Person.update(people.keys, people.values)
#
# # Updates multiple records from the result of a relation
# people = Person.where(group: "expert")
# people.update(group: "masters")
#
# Note: Updating a large number of records will run an UPDATE
# query for each record, which may cause a performance issue.
# When running callbacks is not needed for each record update,
# it is preferred to use {update_all}[rdoc-ref:Relation#update_all]
# for updating all records in a single query.
def update: (?::Symbol id, untyped attributes) -> untyped
# Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
# therefore all callbacks and filters are fired off before the object is deleted. This method is
# less efficient than #delete but allows cleanup methods and other actions to be run.
#
# This essentially finds the object (or multiple objects) with the given id, creates a new object
# from the attributes, and then calls destroy on it.
#
# ==== Parameters
#
# * +id+ - This should be the id or an array of ids to be destroyed.
#
# ==== Examples
#
# # Destroy a single object
# Todo.destroy(1)
#
# # Destroy multiple objects
# todos = [1,2,3]
# Todo.destroy(todos)
def destroy: (untyped id) -> untyped
# Deletes the row with a primary key matching the +id+ argument, using an
# SQL +DELETE+ statement, and returns the number of rows deleted. Active
# Record objects are not instantiated, so the object's callbacks are not
# executed, including any :dependent association options.
#
# You can delete multiple rows at once by passing an Array of ids.
#
# Note: Although it is often much faster than the alternative, #destroy,
# skipping callbacks might bypass business logic in your application
# that ensures referential integrity or performs other essential jobs.
#
# ==== Examples
#
# # Delete a single row
# Todo.delete(1)
#
# # Delete multiple rows
# Todo.delete([2,3,4])
def delete: (untyped id_or_array) -> untyped
def _insert_record: (untyped values) -> untyped
def _update_record: (untyped values, untyped constraints) -> untyped
def _delete_record: (untyped constraints) -> untyped
# Given a class, an attributes hash, +instantiate_instance_of+ returns a
# new instance of the class. Accepts only keys as strings.
def instantiate_instance_of: (untyped klass, untyped attributes, ?::Hash[untyped, untyped] column_types) { () -> untyped } -> untyped
# Called by +instantiate+ to decide which class to use for a new
# record instance.
#
# See +ActiveRecord::Inheritance#discriminate_class_for_record+ for
# the single-table inheritance discriminator.
def discriminate_class_for_record: (untyped record) -> untyped
def _substitute_values: (untyped values) -> untyped
end
# Returns true if this object hasn't been saved yet -- that is, a record
# for the object doesn't exist in the database yet; otherwise, returns false.
def new_record?: () -> untyped
# Returns true if this object has been destroyed, otherwise returns false.
def destroyed?: () -> untyped
# Returns true if the record is persisted, i.e. it's not a new record and it was
# not destroyed, otherwise returns false.
def persisted?: () -> untyped
#
# :call-seq:
# save(*args)
#
# Saves the model.
#
# If the model is new, a record gets created in the database, otherwise
# the existing record gets updated.
#
# By default, save always runs validations. If any of them fail the action
# is cancelled and #save returns +false+, and the record won't be saved. However, if you supply
# validate: false, validations are bypassed altogether. See
# ActiveRecord::Validations for more information.
#
# By default, #save also sets the +updated_at+/+updated_on+ attributes to
# the current time. However, if you supply touch: false, these
# timestamps will not be updated.
#
# There's a series of callbacks associated with #save. If any of the
# before_* callbacks throws +:abort+ the action is cancelled and
# #save returns +false+. See ActiveRecord::Callbacks for further
# details.
#
# Attributes marked as readonly are silently ignored if the record is
# being updated.
def save: (*untyped args, **untyped options) { () -> untyped } -> untyped
#
# :call-seq:
# save!(*args)
#
# Saves the model.
#
# If the model is new, a record gets created in the database, otherwise
# the existing record gets updated.
#
# By default, #save! always runs validations. If any of them fail
# ActiveRecord::RecordInvalid gets raised, and the record won't be saved. However, if you supply
# validate: false, validations are bypassed altogether. See
# ActiveRecord::Validations for more information.
#
# By default, #save! also sets the +updated_at+/+updated_on+ attributes to
# the current time. However, if you supply touch: false, these
# timestamps will not be updated.
#
# There's a series of callbacks associated with #save!. If any of
# the before_* callbacks throws +:abort+ the action is cancelled
# and #save! raises ActiveRecord::RecordNotSaved. See
# ActiveRecord::Callbacks for further details.
#
# Attributes marked as readonly are silently ignored if the record is
# being updated.
#
# Unless an error is raised, returns true.
def save!: (*untyped args, **untyped options) { () -> untyped } -> untyped
# Deletes the record in the database and freezes this instance to
# reflect that no changes should be made (since they can't be
# persisted). Returns the frozen instance.
#
# The row is simply removed with an SQL +DELETE+ statement on the
# record's primary key, and no callbacks are executed.
#
# Note that this will also delete records marked as {#readonly?}[rdoc-ref:Core#readonly?].
#
# To enforce the object's +before_destroy+ and +after_destroy+
# callbacks or any :dependent association
# options, use #destroy.
def delete: () -> untyped
# Deletes the record in the database and freezes this instance to reflect
# that no changes should be made (since they can't be persisted).
#
# There's a series of callbacks associated with #destroy. If the
# before_destroy callback throws +:abort+ the action is cancelled
# and #destroy returns +false+.
# See ActiveRecord::Callbacks for further details.
def destroy: () -> untyped
# Deletes the record in the database and freezes this instance to reflect
# that no changes should be made (since they can't be persisted).
#
# There's a series of callbacks associated with #destroy!. If the
# before_destroy callback throws +:abort+ the action is cancelled
# and #destroy! raises ActiveRecord::RecordNotDestroyed.
# See ActiveRecord::Callbacks for further details.
def destroy!: () -> untyped
# Returns an instance of the specified +klass+ with the attributes of the
# current record. This is mostly useful in relation to single-table
# inheritance structures where you want a subclass to appear as the
# superclass. This can be used along with record identification in
# Action Pack to allow, say, Client < Company to do something
# like render partial: @client.becomes(Company) to render that
# instance using the companies/company partial instead of clients/client.
#
# Note: The new instance will share a link to the same attributes as the original class.
# Therefore the sti column value will still be the same.
# Any change to the attributes on either instance will affect both instances.
# If you want to change the sti column as well, use #becomes! instead.
def becomes: (untyped klass) -> untyped
# Wrapper around #becomes that also changes the instance's sti column value.
# This is especially useful if you want to persist the changed class in your
# database.
#
# Note: The old instance's sti column value will be changed too, as both objects
# share the same set of attributes.
def becomes!: (untyped klass) -> untyped
# Updates a single attribute and saves the record.
# This is especially useful for boolean flags on existing records. Also note that
#
# * Validation is skipped.
# * \Callbacks are invoked.
# * updated_at/updated_on column is updated if that column is available.
# * Updates all the attributes that are dirty in this object.
#
# This method raises an ActiveRecord::ActiveRecordError if the
# attribute is marked as readonly.
#
# Also see #update_column.
def update_attribute: (untyped name, untyped value) -> untyped
# Updates the attributes of the model from the passed-in hash and saves the
# record, all wrapped in a transaction. If the object is invalid, the saving
# will fail and false will be returned.
def update: (untyped attributes) -> untyped
# Updates its receiver just like #update but calls #save! instead
# of +save+, so an exception is raised if the record is invalid and saving will fail.
def update!: (untyped attributes) -> untyped
# Equivalent to update_columns(name => value)
.
def update_column: (untyped name, untyped value) -> untyped
# Updates the attributes directly in the database issuing an UPDATE SQL
# statement and sets them in the receiver:
#
# user.update_columns(last_request_at: Time.current)
#
# This is the fastest way to update attributes because it goes straight to
# the database, but take into account that in consequence the regular update
# procedures are totally bypassed. In particular:
#
# * \Validations are skipped.
# * \Callbacks are skipped.
# * +updated_at+/+updated_on+ are not updated.
# * However, attributes are serialized with the same rules as ActiveRecord::Relation#update_all
#
# This method raises an ActiveRecord::ActiveRecordError when called on new
# objects, or when at least one of the attributes is marked as readonly.
def update_columns: (untyped attributes) -> untyped
# Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
# The increment is performed directly on the underlying attribute, no setter is invoked.
# Only makes sense for number-based attributes. Returns +self+.
def increment: (untyped attribute, ?::Integer by) -> untyped
# Wrapper around #increment that writes the update to the database.
# Only +attribute+ is updated; the record itself is not saved.
# This means that any other modified attributes will still be dirty.
# Validations and callbacks are skipped. Supports the +touch+ option from
# +update_counters+, see that for more.
# Returns +self+.
def increment!: (untyped attribute, ?::Integer by, ?touch: untyped? touch) -> untyped
# Initializes +attribute+ to zero if +nil+ and subtracts the value passed as +by+ (default is 1).
# The decrement is performed directly on the underlying attribute, no setter is invoked.
# Only makes sense for number-based attributes. Returns +self+.
def decrement: (untyped attribute, ?::Integer by) -> untyped
# Wrapper around #decrement that writes the update to the database.
# Only +attribute+ is updated; the record itself is not saved.
# This means that any other modified attributes will still be dirty.
# Validations and callbacks are skipped. Supports the +touch+ option from
# +update_counters+, see that for more.
# Returns +self+.
def decrement!: (untyped attribute, ?::Integer by, ?touch: untyped? touch) -> untyped
# Assigns to +attribute+ the boolean opposite of attribute?. So
# if the predicate returns +true+ the attribute will become +false+. This
# method toggles directly the underlying value without calling any setter.
# Returns +self+.
#
# Example:
#
# user = User.first
# user.banned? # => false
# user.toggle(:banned)
# user.banned? # => true
#
def toggle: (untyped attribute) -> untyped
# Wrapper around #toggle that saves the record. This method differs from
# its non-bang version in the sense that it passes through the attribute setter.
# Saving is not subjected to validation checks. Returns +true+ if the
# record could be saved.
def toggle!: (untyped attribute) -> untyped
# Reloads the record from the database.
#
# This method finds the record by its primary key (which could be assigned
# manually) and modifies the receiver in-place:
#
# account = Account.new
# # => #
# account.id = 1
# account.reload
# # Account Load (1.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT 1 [["id", 1]]
# # => #
#
# Attributes are reloaded from the database, and caches busted, in
# particular the associations cache and the QueryCache.
#
# If the record no longer exists in the database ActiveRecord::RecordNotFound
# is raised. Otherwise, in addition to the in-place modification the method
# returns +self+ for convenience.
#
# The optional :lock flag option allows you to lock the reloaded record:
#
# reload(lock: true) # reload with pessimistic locking
#
# Reloading is commonly used in test suites to test something is actually
# written to the database, or when some action modifies the corresponding
# row in the database but not the object in memory:
#
# assert account.deposit!(25)
# assert_equal 25, account.credit # check it is updated in memory
# assert_equal 25, account.reload.credit # check it is also persisted
#
# Another common use case is optimistic locking handling:
#
# def with_optimistic_retry
# begin
# yield
# rescue ActiveRecord::StaleObjectError
# begin
# # Reload lock_version in particular.
# reload
# rescue ActiveRecord::RecordNotFound
# # If the record is gone there is nothing to do.
# else
# retry
# end
# end
# end
#
def reload: (?untyped? options) -> untyped
# Saves the record with the updated_at/on attributes set to the current time
# or the time specified.
# Please note that no validation is performed and only the +after_touch+,
# +after_commit+ and +after_rollback+ callbacks are executed.
#
# This method can be passed attribute names and an optional time argument.
# If attribute names are passed, they are updated along with updated_at/on
# attributes. If no time argument is passed, the current time is used as default.
#
# product.touch # updates updated_at/on with current time
# product.touch(time: Time.new(2015, 2, 16, 0, 0, 0)) # updates updated_at/on with specified time
# product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
# product.touch(:started_at, :ended_at) # updates started_at, ended_at and updated_at/on attributes
#
# If used along with {belongs_to}[rdoc-ref:Associations::ClassMethods#belongs_to]
# then +touch+ will invoke +touch+ method on associated object.
#
# class Brake < ActiveRecord::Base
# belongs_to :car, touch: true
# end
#
# class Car < ActiveRecord::Base
# belongs_to :corporation, touch: true
# end
#
# # triggers @brake.car.touch and @brake.car.corporation.touch
# @brake.touch
#
# Note that +touch+ must be used on a persisted object, or else an
# ActiveRecordError will be thrown. For example:
#
# ball = Ball.new
# ball.touch(:updated_at) # => raises ActiveRecordError
#
def touch: (*untyped names, ?time: untyped? time) -> untyped
# A hook to be overridden by association modules.
def destroy_associations: () -> nil
def destroy_row: () -> untyped
def _delete_row: () -> untyped
def _touch_row: (untyped attribute_names, untyped time) -> untyped
def _update_row: (untyped attribute_names, ?::String attempted_action) -> untyped
def create_or_update: () { () -> untyped } -> (::FalseClass | untyped)
# Updates the associated record with values matching those of the instance attributes.
# Returns the number of affected rows.
def _update_record: (?untyped attribute_names) { (untyped) -> untyped } -> untyped
# Creates a record with values matching those of the instance attributes
# and returns its id.
def _create_record: (?untyped attribute_names) { (untyped) -> untyped } -> untyped
def verify_readonly_attribute: (untyped name) -> untyped
def _raise_record_not_destroyed: () -> untyped
# The name of the method used to touch a +belongs_to+ association when the
# +:touch+ option is used.
def belongs_to_touch_method: () -> :touch
def _raise_readonly_record_error: () -> untyped
end
end
module ActiveRecord
# = Active Record Query Cache
class QueryCache
module ClassMethods
# Enable the query cache within the block if Active Record is configured.
# If it's not, it will execute the given block.
def cache: () { () -> untyped } -> untyped
# Disable the query cache within the block if Active Record is configured.
# If it's not, it will execute the given block.
def uncached: () { () -> untyped } -> untyped
end
def self.run: () -> untyped
def self.complete: (untyped pools) -> untyped
def self.install_executor_hooks: (?untyped executor) -> untyped
end
end
module ActiveRecord
module Querying
QUERYING_METHODS: untyped
# Executes a custom SQL query against your database and returns all the results. The results will
# be returned as an array, with the requested columns encapsulated as attributes of the model you call
# this method from. For example, if you call Product.find_by_sql, then the results will be returned in
# a +Product+ object with the attributes you specified in the SQL query.
#
# If you call a complicated SQL query which spans multiple tables, the columns specified by the
# SELECT will be attributes of the model, whether or not they are columns of the corresponding
# table.
#
# The +sql+ parameter is a full SQL query as a string. It will be called as is; there will be
# no database agnostic conversions performed. This should be a last resort because using
# database-specific terms will lock you into using that particular database engine, or require you to
# change your call if you switch engines.
#
# # A simple SQL query spanning multiple tables
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
# # => [#"Ruby Meetup", "author"=>"Quentin"}>, ...]
#
# You can use the same string replacement techniques as you can with ActiveRecord::QueryMethods#where:
#
# Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
# Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
def find_by_sql: (untyped sql, ?untyped binds, ?preparable: untyped? preparable) { () -> untyped } -> untyped
# Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
# The use of this method should be restricted to complicated SQL queries that can't be executed
# using the ActiveRecord::Calculations class methods. Look into those before using this method,
# as it could lock you into a specific database engine or require a code change to switch
# database engines.
#
# Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
# # => 12
#
# ==== Parameters
#
# * +sql+ - An SQL statement which should return a count query from the database, see the example above.
def count_by_sql: (untyped sql) -> untyped
end
end
module ActiveRecord
class Railtie < Rails::Railtie
include ActiveRecord::Railties::ControllerRuntime
extend ::ActiveRecord::Railties::ControllerRuntime::ClassMethods
end
end
module ActiveRecord
module Railties
module CollectionCacheAssociationLoading
# :nodoc:
# nodoc:
def setup: (untyped context, untyped options, untyped as, untyped block) -> untyped
def relation_from_options: (?collection: untyped? collection, ?partial: untyped? partial, ?cached: untyped? cached, **untyped _) -> (nil | untyped)
def collection_without_template: () -> untyped
def collection_with_template: () -> untyped
end
end
end
module ActiveRecord
module Railties
module ControllerRuntime
# :nodoc:
# nodoc:
extend ActiveSupport::Concern
module ClassMethods
# :nodoc:
def log_process_action: (untyped payload) -> untyped
end
def process_action: (untyped action, *untyped args) -> untyped
def cleanup_view_runtime: () -> untyped
def append_info_to_payload: (untyped payload) -> untyped
end
end
end
module ActiveRecord
extend ActiveSupport::Autoload
module Coders
end
module AttributeMethods
extend ActiveSupport::Autoload
end
module Locking
extend ActiveSupport::Autoload
end
module ConnectionAdapters
extend ActiveSupport::Autoload
end
module Scoping
extend ::ActiveRecord::Scoping::Named::ClassMethods
extend ::ActiveRecord::Scoping::Default::ClassMethods
extend ActiveSupport::Autoload
end
module Middleware
extend ActiveSupport::Autoload
end
module Tasks
extend ActiveSupport::Autoload
end
def self.eager_load!: () -> untyped
end
module ActiveRecord
module ReadonlyAttributes
extend ActiveSupport::Concern
module ClassMethods
# Attributes listed as readonly will be used to create a new record but update operations will
# ignore these fields.
def attr_readonly: (*untyped attributes) -> untyped
# Returns an array of all the attributes that have been specified as readonly.
def readonly_attributes: () -> untyped
end
end
end
module ActiveRecord
module Reflection
# = Active Record Reflection
# :nodoc:
extend ActiveSupport::Concern
def self.create: (untyped macro, untyped name, untyped scope, untyped options, untyped ar) -> untyped
def self.add_reflection: (untyped ar, untyped name, untyped reflection) -> untyped
def self.add_aggregate_reflection: (untyped ar, untyped name, untyped reflection) -> untyped
def self.reflection_class_for: (untyped macro) -> untyped
# \Reflection enables the ability to examine the associations and aggregations of
# Active Record classes and objects. This information, for example,
# can be used in a form builder that takes an Active Record object
# and creates input fields for all of the attributes depending on their type
# and displays the associations to other objects.
#
# MacroReflection class has info for AggregateReflection and AssociationReflection
# classes.
module ClassMethods
# Returns an array of AggregateReflection objects for all the aggregations in the class.
def reflect_on_all_aggregations: () -> untyped
# Returns the AggregateReflection object for the named +aggregation+ (use the symbol).
#
# Account.reflect_on_aggregation(:balance) # => the balance AggregateReflection
#
def reflect_on_aggregation: (untyped aggregation) -> untyped
# Returns a Hash of name of the reflection as the key and an AssociationReflection as the value.
#
# Account.reflections # => {"balance" => AggregateReflection}
#
def reflections: () -> untyped
# Returns an array of AssociationReflection objects for all the
# associations in the class. If you only want to reflect on a certain
# association type, pass in the symbol (:has_many, :has_one,
# :belongs_to) as the first parameter.
#
# Example:
#
# Account.reflect_on_all_associations # returns an array of all associations
# Account.reflect_on_all_associations(:has_many) # returns an array of all has_many associations
#
def reflect_on_all_associations: (?untyped? macro) -> untyped
# Returns the AssociationReflection object for the +association+ (use the symbol).
#
# Account.reflect_on_association(:owner) # returns the owner AssociationReflection
# Invoice.reflect_on_association(:line_items).macro # returns :has_many
#
def reflect_on_association: (untyped association) -> untyped
def _reflect_on_association: (untyped association) -> untyped
# Returns an array of AssociationReflection objects for all associations which have :autosave enabled.
def reflect_on_all_autosave_associations: () -> untyped
def clear_reflections_cache: () -> untyped
end
class AbstractReflection
# Holds all the methods that are shared between MacroReflection and ThroughReflection.
#
# AbstractReflection
# MacroReflection
# AggregateReflection
# AssociationReflection
# HasManyReflection
# HasOneReflection
# BelongsToReflection
# HasAndBelongsToManyReflection
# ThroughReflection
# PolymorphicReflection
# RuntimeReflection
# :nodoc:
def through_reflection?: () -> ::FalseClass
def table_name: () -> untyped
# Returns a new, unsaved instance of the associated class. +attributes+ will
# be passed to the class's constructor.
def build_association: (untyped attributes) { () -> untyped } -> untyped
# Returns the class name for the macro.
#
# composed_of :balance, class_name: 'Money' returns 'Money'
# has_many :clients returns 'Client'
def class_name: () -> untyped
class JoinKeys < ::Struct[untyped]
attr_accessor key(): untyped
attr_accessor foreign_key(): untyped
end
def join_keys: () -> untyped
# Returns a list of scopes that should be applied for this Reflection
# object when querying the database.
def scopes: () -> untyped
def join_scope: (untyped table, untyped foreign_table, untyped foreign_klass) -> untyped
def join_scopes: (untyped table, untyped predicate_builder) -> untyped
def klass_join_scope: (untyped table, untyped predicate_builder) -> untyped
def constraints: () -> untyped
def counter_cache_column: () -> untyped
def inverse_of: () -> (nil | untyped)
def check_validity_of_inverse!: () -> untyped
# This shit is nasty. We need to avoid the following situation:
#
# * An associated record is deleted via record.destroy
# * Hence the callbacks run, and they find a belongs_to on the record with a
# :counter_cache options which points back at our owner. So they update the
# counter cache.
# * In which case, we must make sure to *not* update the counter cache, or else
# it will be decremented twice.
#
# Hence this method.
def inverse_which_updates_counter_cache: () -> untyped
def inverse_updates_counter_in_memory?: () -> untyped
# Returns whether a counter cache should be used for this association.
#
# The counter_cache option must be given on either the owner or inverse
# association, and the column must be present on the owner.
def has_cached_counter?: () -> untyped
def counter_must_be_updated_by_has_many?: () -> untyped
def alias_candidate: (untyped name) -> ::String
def chain: () -> untyped
def get_join_keys: (untyped association_klass) -> JoinKeys
def build_scope: (untyped table, ?untyped predicate_builder) -> untyped
def join_primary_key: () -> untyped
def join_foreign_key: () -> untyped
def actual_source_reflection: () -> untyped
def predicate_builder: (untyped table) -> PredicateBuilder
def primary_key: (untyped klass) -> untyped
end
# Base class for AggregateReflection and AssociationReflection. Objects of
# AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods.
class MacroReflection < AbstractReflection
# Returns the name of the macro.
#
# composed_of :balance, class_name: 'Money' returns :balance
# has_many :clients returns :clients
attr_reader name: untyped
attr_reader scope: untyped
# Returns the hash of options used for the macro.
#
# composed_of :balance, class_name: 'Money' returns { class_name: "Money" }
# has_many :clients returns {}
attr_reader options: untyped
attr_reader active_record: untyped
attr_reader plural_name: untyped
def initialize: (untyped name, untyped scope, untyped options, untyped active_record) -> untyped
def autosave=: (untyped autosave) -> untyped
# Returns the class for the macro.
#
# composed_of :balance, class_name: 'Money' returns the Money class
# has_many :clients returns the Client class
#
# class Company < ActiveRecord::Base
# has_many :clients
# end
#
# Company.reflect_on_association(:clients).klass
# # => Client
#
# Note: Do not call +klass.new+ or +klass.create+ to instantiate
# a new association object. Use +build_association+ or +create_association+
# instead. This allows plugins to hook into association object creation.
def klass: () -> untyped
def compute_class: (untyped name) -> untyped
# Returns +true+ if +self+ and +other_aggregation+ have the same +name+ attribute, +active_record+ attribute,
# and +other_aggregation+ has an options hash assigned to it.
def ==: (untyped other_aggregation) -> untyped
def scope_for: (untyped relation, ?untyped? owner) -> untyped
def derive_class_name: () -> untyped
end
class AggregateReflection < MacroReflection
# Holds all the metadata about an aggregation as it was specified in the
# Active Record class.
# nodoc:
def mapping: () -> untyped
end
class AssociationReflection < MacroReflection
# Holds all the metadata about an association as it was specified in the
# Active Record class.
# nodoc:
def compute_class: (untyped name) -> untyped
attr_reader type: untyped
attr_reader foreign_type: untyped
attr_accessor parent_reflection: untyped
def initialize: (untyped name, untyped scope, untyped options, untyped active_record) -> untyped
def association_scope_cache: (untyped conn, untyped owner) { () -> untyped } -> untyped
def constructable?: () -> untyped
def join_table: () -> untyped
def foreign_key: () -> untyped
def association_foreign_key: () -> untyped
# klass option is necessary to support loading polymorphic associations
def association_primary_key: (?untyped? klass) -> untyped
def active_record_primary_key: () -> untyped
def check_validity!: () -> untyped
def check_preloadable!: () -> (nil | untyped)
def join_id_for: (untyped owner) -> untyped
def through_reflection: () -> nil
def source_reflection: () -> untyped
# A chain of reflections from this one back to the owner. For more see the explanation in
# ThroughReflection.
def collect_join_chain: () -> ::Array[untyped]
def clear_association_scope_cache: () -> untyped
def nested?: () -> ::FalseClass
def has_scope?: () -> untyped
def has_inverse?: () -> untyped
def polymorphic_inverse_of: (untyped associated_class) -> untyped
# Returns the macro type.
#
# has_many :clients returns :has_many
def macro: () -> untyped
# Returns whether or not this association reflection is for a collection
# association. Returns +true+ if the +macro+ is either +has_many+ or
# +has_and_belongs_to_many+, +false+ otherwise.
def collection?: () -> ::FalseClass
# Returns whether or not the association should be validated as part of
# the parent's validation.
#
# Unless you explicitly disable validation with
# validate: false, validation will take place when:
#
# * you explicitly enable validation; validate: true
# * you use autosave; autosave: true
# * the association is a +has_many+ association
def validate?: () -> untyped
# Returns +true+ if +self+ is a +belongs_to+ reflection.
def belongs_to?: () -> ::FalseClass
# Returns +true+ if +self+ is a +has_one+ reflection.
def has_one?: () -> ::FalseClass
def association_class: () -> untyped
def polymorphic?: () -> untyped
VALID_AUTOMATIC_INVERSE_MACROS: ::Array[untyped]
INVALID_AUTOMATIC_INVERSE_OPTIONS: ::Array[untyped]
def add_as_source: (untyped seed) -> untyped
def add_as_polymorphic_through: (untyped reflection, untyped seed) -> untyped
def add_as_through: (untyped seed) -> untyped
def extensions: () -> untyped
def calculate_constructable: (untyped macro, untyped options) -> ::TrueClass
# Attempts to find the inverse association name automatically.
# If it cannot find a suitable inverse association name, it returns
# +nil+.
def inverse_name: () -> untyped
# returns either +nil+ or the inverse association name that it finds.
def automatic_inverse_of: () -> untyped
# Checks if the inverse reflection that is returned from the
# +automatic_inverse_of+ method is a valid reflection. We must
# make sure that the reflection's active_record name matches up
# with the current reflection's klass name.
def valid_inverse_reflection?: (untyped reflection) -> untyped
# Checks to see if the reflection doesn't have any options that prevent
# us from being able to guess the inverse automatically. First, the
# inverse_of option cannot be set to false. Second, we must
# have has_many, has_one, belongs_to associations.
# Third, we must not have options such as :foreign_key
# which prevent us from correctly guessing the inverse association.
#
# Anything with a scope can additionally ruin our attempt at finding an
# inverse, so we exclude reflections with scopes.
def can_find_inverse_of_automatically?: (untyped reflection) -> untyped
def derive_class_name: () -> untyped
def derive_foreign_key: () -> untyped
def derive_join_table: () -> untyped
end
class HasManyReflection < AssociationReflection
# :nodoc:
def macro: () -> :has_many
def collection?: () -> ::TrueClass
def association_class: () -> untyped
def association_primary_key: (?untyped? klass) -> untyped
end
class HasOneReflection < AssociationReflection
# :nodoc:
def macro: () -> :has_one
def has_one?: () -> ::TrueClass
def association_class: () -> untyped
def calculate_constructable: (untyped macro, untyped options) -> untyped
end
class BelongsToReflection < AssociationReflection
# :nodoc:
def macro: () -> :belongs_to
def belongs_to?: () -> ::TrueClass
def association_class: () -> untyped
def join_primary_key: (?untyped? klass) -> untyped
def join_foreign_key: () -> untyped
def can_find_inverse_of_automatically?: (untyped _) -> untyped
def calculate_constructable: (untyped macro, untyped options) -> untyped
end
class HasAndBelongsToManyReflection < AssociationReflection
# :nodoc:
def macro: () -> :has_and_belongs_to_many
def collection?: () -> ::TrueClass
end
class ThroughReflection < AbstractReflection
def initialize: (untyped delegate_reflection) -> untyped
def through_reflection?: () -> ::TrueClass
def klass: () -> untyped
# Returns the source of the through reflection. It checks both a singularized
# and pluralized form for :belongs_to or :has_many.
#
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, through: :taggings
# end
#
# class Tagging < ActiveRecord::Base
# belongs_to :post
# belongs_to :tag
# end
#
# tags_reflection = Post.reflect_on_association(:tags)
# tags_reflection.source_reflection
# # =>
#
def source_reflection: () -> untyped
# Returns the AssociationReflection object specified in the :through option
# of a HasManyThrough or HasOneThrough association.
#
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, through: :taggings
# end
#
# tags_reflection = Post.reflect_on_association(:tags)
# tags_reflection.through_reflection
# # =>
#
def through_reflection: () -> untyped
# Returns an array of reflections which are involved in this association. Each item in the
# array corresponds to a table which will be part of the query for this association.
#
# The chain is built by recursively calling #chain on the source reflection and the through
# reflection. The base case for the recursion is a normal association, which just returns
# [self] as its #chain.
#
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, through: :taggings
# end
#
# tags_reflection = Post.reflect_on_association(:tags)
# tags_reflection.chain
# # => [,
# ]
#
def collect_join_chain: () -> untyped
def clear_association_scope_cache: () -> untyped
def scopes: () -> untyped
def join_scopes: (untyped table, untyped predicate_builder) -> untyped
def has_scope?: () -> untyped
# A through association is nested if there would be more than one join table
def nested?: () -> untyped
# We want to use the klass from this reflection, rather than just delegate straight to
# the source_reflection, because the source_reflection may be polymorphic. We still
# need to respect the source_reflection's :primary_key option, though.
def association_primary_key: (?untyped? klass) -> untyped
# Gets an array of possible :through source reflection names in both singular and plural form.
#
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, through: :taggings
# end
#
# tags_reflection = Post.reflect_on_association(:tags)
# tags_reflection.source_reflection_names
# # => [:tag, :tags]
#
def source_reflection_names: () -> untyped
def source_reflection_name: () -> untyped
def source_options: () -> untyped
def through_options: () -> untyped
def check_validity!: () -> untyped
def constraints: () -> untyped
def add_as_source: (untyped seed) -> untyped
def add_as_polymorphic_through: (untyped reflection, untyped seed) -> untyped
def add_as_through: (untyped seed) -> untyped
def actual_source_reflection: () -> untyped
attr_reader delegate_reflection: untyped
def collect_join_reflections: (untyped seed) -> untyped
def inverse_name: () -> untyped
def derive_class_name: () -> untyped
end
class PolymorphicReflection < AbstractReflection
def initialize: (untyped reflection, untyped previous_reflection) -> untyped
def join_scopes: (untyped table, untyped predicate_builder) -> untyped
def constraints: () -> untyped
def source_type_scope: () -> untyped
end
class RuntimeReflection < AbstractReflection
def initialize: (untyped reflection, untyped association) -> untyped
def klass: () -> untyped
def aliased_table: () -> untyped
def all_includes: () { () -> untyped } -> untyped
end
end
end
module ActiveRecord
module Batches
class BatchEnumerator
include Enumerable[untyped, untyped]
def initialize: (relation: untyped relation, ?finish: untyped? finish, ?start: untyped? start, ?of: ::Integer of) -> untyped
# Looping through a collection of records from the database (using the
# +all+ method, for example) is very inefficient since it will try to
# instantiate all the objects at once.
#
# In that case, batch processing methods allow you to work with the
# records in batches, thereby greatly reducing memory consumption.
#
# Person.in_batches.each_record do |person|
# person.do_awesome_stuff
# end
#
# Person.where("age > 21").in_batches(of: 10).each_record do |person|
# person.party_all_night!
# end
#
# If you do not provide a block to #each_record, it will return an Enumerator
# for chaining with other methods:
#
# Person.in_batches.each_record.with_index do |person, index|
# person.award_trophy(index + 1)
# end
def each_record: () { (untyped) -> untyped } -> untyped
# Yields an ActiveRecord::Relation object for each batch of records.
#
# Person.in_batches.each do |relation|
# relation.update_all(awesome: true)
# end
def each: () { (untyped) -> untyped } -> untyped
end
end
end
module ActiveRecord
module Batches
ORDER_IGNORE_MESSAGE: ::String
# Looping through a collection of records from the database
# (using the Scoping::Named::ClassMethods.all method, for example)
# is very inefficient since it will try to instantiate all the objects at once.
#
# In that case, batch processing methods allow you to work
# with the records in batches, thereby greatly reducing memory consumption.
#
# The #find_each method uses #find_in_batches with a batch size of 1000 (or as
# specified by the +:batch_size+ option).
#
# Person.find_each do |person|
# person.do_awesome_stuff
# end
#
# Person.where("age > 21").find_each do |person|
# person.party_all_night!
# end
#
# If you do not provide a block to #find_each, it will return an Enumerator
# for chaining with other methods:
#
# Person.find_each.with_index do |person, index|
# person.award_trophy(index + 1)
# end
#
# ==== Options
# * :batch_size - Specifies the size of the batch. Defaults to 1000.
# * :start - Specifies the primary key value to start from, inclusive of the value.
# * :finish - Specifies the primary key value to end at, inclusive of the value.
# * :error_on_ignore - Overrides the application config to specify if an error should be raised when
# an order is present in the relation.
#
# Limits are honored, and if present there is no requirement for the batch
# size: it can be less than, equal to, or greater than the limit.
#
# The options +start+ and +finish+ are especially useful if you want
# multiple workers dealing with the same processing queue. You can make
# worker 1 handle all the records between id 1 and 9999 and worker 2
# handle from 10000 and beyond by setting the +:start+ and +:finish+
# option on each worker.
#
# # In worker 1, let's process until 9999 records.
# Person.find_each(finish: 9_999) do |person|
# person.party_all_night!
# end
#
# # In worker 2, let's process from record 10_000 and onwards.
# Person.find_each(start: 10_000) do |person|
# person.party_all_night!
# end
#
# NOTE: It's not possible to set the order. That is automatically set to
# ascending on the primary key ("id ASC") to make the batch ordering
# work. This also means that this method only works when the primary key is
# orderable (e.g. an integer or string).
#
# NOTE: By its nature, batch processing is subject to race conditions if
# other processes are modifying the database.
def find_each: (?error_on_ignore: untyped? error_on_ignore, ?batch_size: ::Integer batch_size, ?finish: untyped? finish, ?start: untyped? start) { (untyped) -> untyped } -> untyped
# Yields each batch of records that was found by the find options as
# an array.
#
# Person.where("age > 21").find_in_batches do |group|
# sleep(50) # Make sure it doesn't get too crowded in there!
# group.each { |person| person.party_all_night! }
# end
#
# If you do not provide a block to #find_in_batches, it will return an Enumerator
# for chaining with other methods:
#
# Person.find_in_batches.with_index do |group, batch|
# puts "Processing group ##{batch}"
# group.each(&:recover_from_last_night!)
# end
#
# To be yielded each record one by one, use #find_each instead.
#
# ==== Options
# * :batch_size - Specifies the size of the batch. Defaults to 1000.
# * :start - Specifies the primary key value to start from, inclusive of the value.
# * :finish - Specifies the primary key value to end at, inclusive of the value.
# * :error_on_ignore - Overrides the application config to specify if an error should be raised when
# an order is present in the relation.
#
# Limits are honored, and if present there is no requirement for the batch
# size: it can be less than, equal to, or greater than the limit.
#
# The options +start+ and +finish+ are especially useful if you want
# multiple workers dealing with the same processing queue. You can make
# worker 1 handle all the records between id 1 and 9999 and worker 2
# handle from 10000 and beyond by setting the +:start+ and +:finish+
# option on each worker.
#
# # Let's process from record 10_000 on.
# Person.find_in_batches(start: 10_000) do |group|
# group.each { |person| person.party_all_night! }
# end
#
# NOTE: It's not possible to set the order. That is automatically set to
# ascending on the primary key ("id ASC") to make the batch ordering
# work. This also means that this method only works when the primary key is
# orderable (e.g. an integer or string).
#
# NOTE: By its nature, batch processing is subject to race conditions if
# other processes are modifying the database.
def find_in_batches: (?error_on_ignore: untyped? error_on_ignore, ?batch_size: ::Integer batch_size, ?finish: untyped? finish, ?start: untyped? start) { (untyped) -> untyped } -> untyped
# Yields ActiveRecord::Relation objects to work with a batch of records.
#
# Person.where("age > 21").in_batches do |relation|
# relation.delete_all
# sleep(10) # Throttle the delete queries
# end
#
# If you do not provide a block to #in_batches, it will return a
# BatchEnumerator which is enumerable.
#
# Person.in_batches.each_with_index do |relation, batch_index|
# puts "Processing relation ##{batch_index}"
# relation.delete_all
# end
#
# Examples of calling methods on the returned BatchEnumerator object:
#
# Person.in_batches.delete_all
# Person.in_batches.update_all(awesome: true)
# Person.in_batches.each_record(&:party_all_night!)
#
# ==== Options
# * :of - Specifies the size of the batch. Defaults to 1000.
# * :load - Specifies if the relation should be loaded. Defaults to false.
# * :start - Specifies the primary key value to start from, inclusive of the value.
# * :finish - Specifies the primary key value to end at, inclusive of the value.
# * :error_on_ignore - Overrides the application config to specify if an error should be raised when
# an order is present in the relation.
#
# Limits are honored, and if present there is no requirement for the batch
# size, it can be less than, equal, or greater than the limit.
#
# The options +start+ and +finish+ are especially useful if you want
# multiple workers dealing with the same processing queue. You can make
# worker 1 handle all the records between id 1 and 9999 and worker 2
# handle from 10000 and beyond by setting the +:start+ and +:finish+
# option on each worker.
#
# # Let's process from record 10_000 on.
# Person.in_batches(start: 10_000).update_all(awesome: true)
#
# An example of calling where query method on the relation:
#
# Person.in_batches.each do |relation|
# relation.update_all('age = age + 1')
# relation.where('age > 21').update_all(should_party: true)
# relation.where('age <= 21').delete_all
# end
#
# NOTE: If you are going to iterate through each record, you should call
# #each_record on the yielded BatchEnumerator:
#
# Person.in_batches.each_record(&:party_all_night!)
#
# NOTE: It's not possible to set the order. That is automatically set to
# ascending on the primary key ("id ASC") to make the batch ordering
# consistent. Therefore the primary key must be orderable, e.g. an integer
# or a string.
#
# NOTE: By its nature, batch processing is subject to race conditions if
# other processes are modifying the database.
def in_batches: (?of: ::Integer of, ?start: untyped? start, ?finish: untyped? finish, ?load: bool load, ?error_on_ignore: untyped? error_on_ignore) { (untyped) -> untyped } -> (BatchEnumerator | untyped)
def apply_limits: (untyped relation, untyped start, untyped finish) -> untyped
def apply_start_limit: (untyped relation, untyped start) -> untyped
def apply_finish_limit: (untyped relation, untyped finish) -> untyped
def batch_order: () -> untyped
def act_on_ignored_order: (untyped error_on_ignore) -> untyped
end
end
module ActiveRecord
module Calculations
# Count the records.
#
# Person.count
# # => the total count of all people
#
# Person.count(:age)
# # => returns the total count of all people whose age is present in database
#
# Person.count(:all)
# # => performs a COUNT(*) (:all is an alias for '*')
#
# Person.distinct.count(:age)
# # => counts the number of different age values
#
# If #count is used with {Relation#group}[rdoc-ref:QueryMethods#group],
# it returns a Hash whose keys represent the aggregated column,
# and the values are the respective amounts:
#
# Person.group(:city).count
# # => { 'Rome' => 5, 'Paris' => 3 }
#
# If #count is used with {Relation#group}[rdoc-ref:QueryMethods#group] for multiple columns, it returns a Hash whose
# keys are an array containing the individual values of each column and the value
# of each key would be the #count.
#
# Article.group(:status, :category).count
# # => {["draft", "business"]=>10, ["draft", "technology"]=>4,
# ["published", "business"]=>0, ["published", "technology"]=>2}
#
# If #count is used with {Relation#select}[rdoc-ref:QueryMethods#select], it will count the selected columns:
#
# Person.select(:age).count
# # => counts the number of different age values
#
# Note: not all valid {Relation#select}[rdoc-ref:QueryMethods#select] expressions are valid #count expressions. The specifics differ
# between databases. In invalid cases, an error from the database is thrown.
def count: (?untyped? column_name) -> untyped
# Calculates the average value on a given column. Returns +nil+ if there's
# no row. See #calculate for examples with options.
#
# Person.average(:age) # => 35.8
def average: (untyped column_name) -> untyped
# Calculates the minimum value on a given column. The value is returned
# with the same data type of the column, or +nil+ if there's no row. See
# #calculate for examples with options.
#
# Person.minimum(:age) # => 7
def minimum: (untyped column_name) -> untyped
# Calculates the maximum value on a given column. The value is returned
# with the same data type of the column, or +nil+ if there's no row. See
# #calculate for examples with options.
#
# Person.maximum(:age) # => 93
def maximum: (untyped column_name) -> untyped
# Calculates the sum of values on a given column. The value is returned
# with the same data type of the column, +0+ if there's no row. See
# #calculate for examples with options.
#
# Person.sum(:age) # => 4562
def sum: (?untyped? column_name) -> untyped
# This calculates aggregate values in the given column. Methods for #count, #sum, #average,
# #minimum, and #maximum have been added as shortcuts.
#
# Person.calculate(:count, :all) # The same as Person.count
# Person.average(:age) # SELECT AVG(age) FROM people...
#
# # Selects the minimum age for any family without any minors
# Person.group(:last_name).having("min(age) > 17").minimum(:age)
#
# Person.sum("2 * age")
#
# There are two basic forms of output:
#
# * Single aggregate value: The single value is type cast to Integer for COUNT, Float
# for AVG, and the given column's type for everything else.
#
# * Grouped values: This returns an ordered hash of the values and groups them. It
# takes either a column name, or the name of a belongs_to association.
#
# values = Person.group('last_name').maximum(:age)
# puts values["Drake"]
# # => 43
#
# drake = Family.find_by(last_name: 'Drake')
# values = Person.group(:family).maximum(:age) # Person belongs_to :family
# puts values[drake]
# # => 43
#
# values.each do |family, max_age|
# ...
# end
def calculate: (untyped operation, untyped column_name) -> untyped
# Use #pluck as a shortcut to select one or more attributes without
# loading a bunch of records just to grab the attributes you want.
#
# Person.pluck(:name)
#
# instead of
#
# Person.all.map(&:name)
#
# Pluck returns an Array of attribute values type-casted to match
# the plucked column names, if they can be deduced. Plucking an SQL fragment
# returns String values by default.
#
# Person.pluck(:name)
# # SELECT people.name FROM people
# # => ['David', 'Jeremy', 'Jose']
#
# Person.pluck(:id, :name)
# # SELECT people.id, people.name FROM people
# # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
#
# Person.distinct.pluck(:role)
# # SELECT DISTINCT role FROM people
# # => ['admin', 'member', 'guest']
#
# Person.where(age: 21).limit(5).pluck(:id)
# # SELECT people.id FROM people WHERE people.age = 21 LIMIT 5
# # => [2, 3]
#
# Person.pluck(Arel.sql('DATEDIFF(updated_at, created_at)'))
# # SELECT DATEDIFF(updated_at, created_at) FROM people
# # => ['0', '27761', '173']
#
# See also #ids.
#
def pluck: (*untyped column_names) -> untyped
# Pick the value(s) from the named column(s) in the current relation.
# This is short-hand for relation.limit(1).pluck(*column_names).first, and is primarily useful
# when you have a relation that's already narrowed down to a single row.
#
# Just like #pluck, #pick will only load the actual value, not the entire record object, so it's also
# more efficient. The value is, again like with pluck, typecast by the column type.
#
# Person.where(id: 1).pick(:name)
# # SELECT people.name FROM people WHERE id = 1 LIMIT 1
# # => 'David'
#
# Person.where(id: 1).pick(:name, :email_address)
# # SELECT people.name, people.email_address FROM people WHERE id = 1 LIMIT 1
# # => [ 'David', 'david@loudthinking.com' ]
def pick: (*untyped column_names) -> untyped
# Pluck all the ID's for the relation using the table's primary key
#
# Person.ids # SELECT people.id FROM people
# Person.joins(:companies).ids # SELECT people.id FROM people INNER JOIN companies ON companies.person_id = people.id
def ids: () -> untyped
def has_include?: (untyped column_name) -> untyped
def perform_calculation: (untyped operation, untyped column_name) -> untyped
def distinct_select?: (untyped column_name) -> untyped
def aggregate_column: (untyped column_name) -> untyped
def operation_over_aggregate_column: (untyped column, untyped operation, untyped distinct) -> untyped
def execute_simple_calculation: (untyped operation, untyped column_name, untyped distinct) -> (0 | untyped)
def execute_grouped_calculation: (untyped operation, untyped column_name, untyped distinct) -> untyped
# Converts the given field to the value that the database adapter returns as
# a usable column name:
#
# column_alias_for("users.id") # => "users_id"
# column_alias_for("sum(id)") # => "sum_id"
# column_alias_for("count(distinct users.id)") # => "count_distinct_users_id"
# column_alias_for("count(*)") # => "count_all"
def column_alias_for: (untyped field) -> untyped
def type_for: (untyped field) { () -> untyped } -> untyped
def type_cast_calculated_value: (untyped value, untyped `type`, ?untyped? operation) -> untyped
def select_for_count: () -> untyped
def build_count_subquery: (untyped relation, untyped column_name, untyped distinct) -> untyped
end
end
module ActiveRecord
module Delegation
module DelegateCache
# :nodoc:
# :nodoc:
def relation_delegate_class: (untyped klass) -> untyped
def initialize_relation_delegate_cache: () -> untyped
def inherited: (untyped child_class) -> untyped
def generate_relation_method: (untyped method) -> untyped
def include_relation_methods: (untyped delegate) -> untyped
def generated_relation_methods: () -> untyped
end
class GeneratedRelationMethods < Module
# :nodoc:
include Mutex_m
def generate_method: (untyped method) -> untyped
end
extend ActiveSupport::Concern
module ClassSpecificRelation
# :nodoc:
extend ActiveSupport::Concern
module ClassMethods
# :nodoc:
def name: () -> untyped
end
def method_missing: (untyped method, *untyped args) { () -> untyped } -> untyped
end
module ClassMethods
# :nodoc:
def create: (untyped klass, *untyped args, **untyped kwargs) -> untyped
def relation_class_for: (untyped klass) -> untyped
end
def respond_to_missing?: (untyped method, untyped _) -> untyped
end
end
module ActiveRecord
module FinderMethods
ONE_AS_ONE: ::String
# Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
# If one or more records cannot be found for the requested ids, then ActiveRecord::RecordNotFound will be raised.
# If the primary key is an integer, find by id coerces its arguments by using +to_i+.
#
# Person.find(1) # returns the object for ID = 1
# Person.find("1") # returns the object for ID = 1
# Person.find("31-sarah") # returns the object for ID = 31
# Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
# Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
# Person.find([1]) # returns an array for the object with ID = 1
# Person.where("administrator = 1").order("created_on DESC").find(1)
#
# NOTE: The returned records are in the same order as the ids you provide.
# If you want the results to be sorted by database, you can use ActiveRecord::QueryMethods#where
# method and provide an explicit ActiveRecord::QueryMethods#order option.
# But ActiveRecord::QueryMethods#where method doesn't raise ActiveRecord::RecordNotFound.
#
# ==== Find with lock
#
# Example for find with a lock: Imagine two concurrent transactions:
# each will read person.visits == 2, add 1 to it, and save, resulting
# in two saves of person.visits = 3. By locking the row, the second
# transaction has to wait until the first is finished; we get the
# expected person.visits == 4.
#
# Person.transaction do
# person = Person.lock(true).find(1)
# person.visits += 1
# person.save!
# end
#
# ==== Variations of #find
#
# Person.where(name: 'Spartacus', rating: 4)
# # returns a chainable list (which can be empty).
#
# Person.find_by(name: 'Spartacus', rating: 4)
# # returns the first item or nil.
#
# Person.find_or_initialize_by(name: 'Spartacus', rating: 4)
# # returns the first item or returns a new instance (requires you call .save to persist against the database).
#
# Person.find_or_create_by(name: 'Spartacus', rating: 4)
# # returns the first item or creates it and returns it.
#
# ==== Alternatives for #find
#
# Person.where(name: 'Spartacus', rating: 4).exists?(conditions = :none)
# # returns a boolean indicating if any record with the given conditions exist.
#
# Person.where(name: 'Spartacus', rating: 4).select("field1, field2, field3")
# # returns a chainable list of instances with only the mentioned fields.
#
# Person.where(name: 'Spartacus', rating: 4).ids
# # returns an Array of ids.
#
# Person.where(name: 'Spartacus', rating: 4).pluck(:field1, :field2)
# # returns an Array of the required fields.
def find: (*untyped args) -> untyped
# Finds the first record matching the specified conditions. There
# is no implied ordering so if order matters, you should specify it
# yourself.
#
# If no record is found, returns nil.
#
# Post.find_by name: 'Spartacus', rating: 4
# Post.find_by "published_at < ?", 2.weeks.ago
def find_by: (untyped arg, *untyped args) -> untyped
# Like #find_by, except that if no record is found, raises
# an ActiveRecord::RecordNotFound error.
def find_by!: (untyped arg, *untyped args) -> untyped
# Gives a record (or N records if a parameter is supplied) without any implied
# order. The order will depend on the database implementation.
# If an order is supplied it will be respected.
#
# Person.take # returns an object fetched by SELECT * FROM people LIMIT 1
# Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5
# Person.where(["name LIKE '%?'", name]).take
def take: (?untyped? limit) -> untyped
# Same as #take but raises ActiveRecord::RecordNotFound if no record
# is found. Note that #take! accepts no arguments.
def take!: () -> untyped
# Find the first record (or first N records if a parameter is supplied).
# If no order is defined it will order by primary key.
#
# Person.first # returns the first object fetched by SELECT * FROM people ORDER BY people.id LIMIT 1
# Person.where(["user_name = ?", user_name]).first
# Person.where(["user_name = :u", { u: user_name }]).first
# Person.order("created_on DESC").offset(5).first
# Person.first(3) # returns the first three objects fetched by SELECT * FROM people ORDER BY people.id LIMIT 3
#
def first: (?untyped? limit) -> untyped
# Same as #first but raises ActiveRecord::RecordNotFound if no record
# is found. Note that #first! accepts no arguments.
def first!: () -> untyped
# Find the last record (or last N records if a parameter is supplied).
# If no order is defined it will order by primary key.
#
# Person.last # returns the last object fetched by SELECT * FROM people
# Person.where(["user_name = ?", user_name]).last
# Person.order("created_on DESC").offset(5).last
# Person.last(3) # returns the last three objects fetched by SELECT * FROM people.
#
# Take note that in that last case, the results are sorted in ascending order:
#
# [#, #, #]
#
# and not:
#
# [#, #, #]
def last: (?untyped? limit) -> untyped
# Same as #last but raises ActiveRecord::RecordNotFound if no record
# is found. Note that #last! accepts no arguments.
def last!: () -> untyped
# Find the second record.
# If no order is defined it will order by primary key.
#
# Person.second # returns the second object fetched by SELECT * FROM people
# Person.offset(3).second # returns the second object from OFFSET 3 (which is OFFSET 4)
# Person.where(["user_name = :u", { u: user_name }]).second
def second: () -> untyped
# Same as #second but raises ActiveRecord::RecordNotFound if no record
# is found.
def second!: () -> untyped
# Find the third record.
# If no order is defined it will order by primary key.
#
# Person.third # returns the third object fetched by SELECT * FROM people
# Person.offset(3).third # returns the third object from OFFSET 3 (which is OFFSET 5)
# Person.where(["user_name = :u", { u: user_name }]).third
def third: () -> untyped
# Same as #third but raises ActiveRecord::RecordNotFound if no record
# is found.
def third!: () -> untyped
# Find the fourth record.
# If no order is defined it will order by primary key.
#
# Person.fourth # returns the fourth object fetched by SELECT * FROM people
# Person.offset(3).fourth # returns the fourth object from OFFSET 3 (which is OFFSET 6)
# Person.where(["user_name = :u", { u: user_name }]).fourth
def fourth: () -> untyped
# Same as #fourth but raises ActiveRecord::RecordNotFound if no record
# is found.
def fourth!: () -> untyped
# Find the fifth record.
# If no order is defined it will order by primary key.
#
# Person.fifth # returns the fifth object fetched by SELECT * FROM people
# Person.offset(3).fifth # returns the fifth object from OFFSET 3 (which is OFFSET 7)
# Person.where(["user_name = :u", { u: user_name }]).fifth
def fifth: () -> untyped
# Same as #fifth but raises ActiveRecord::RecordNotFound if no record
# is found.
def fifth!: () -> untyped
# Find the forty-second record. Also known as accessing "the reddit".
# If no order is defined it will order by primary key.
#
# Person.forty_two # returns the forty-second object fetched by SELECT * FROM people
# Person.offset(3).forty_two # returns the forty-second object from OFFSET 3 (which is OFFSET 44)
# Person.where(["user_name = :u", { u: user_name }]).forty_two
def forty_two: () -> untyped
# Same as #forty_two but raises ActiveRecord::RecordNotFound if no record
# is found.
def forty_two!: () -> untyped
# Find the third-to-last record.
# If no order is defined it will order by primary key.
#
# Person.third_to_last # returns the third-to-last object fetched by SELECT * FROM people
# Person.offset(3).third_to_last # returns the third-to-last object from OFFSET 3
# Person.where(["user_name = :u", { u: user_name }]).third_to_last
def third_to_last: () -> untyped
# Same as #third_to_last but raises ActiveRecord::RecordNotFound if no record
# is found.
def third_to_last!: () -> untyped
# Find the second-to-last record.
# If no order is defined it will order by primary key.
#
# Person.second_to_last # returns the second-to-last object fetched by SELECT * FROM people
# Person.offset(3).second_to_last # returns the second-to-last object from OFFSET 3
# Person.where(["user_name = :u", { u: user_name }]).second_to_last
def second_to_last: () -> untyped
# Same as #second_to_last but raises ActiveRecord::RecordNotFound if no record
# is found.
def second_to_last!: () -> untyped
# Returns true if a record exists in the table that matches the +id+ or
# conditions given, or false otherwise. The argument can take six forms:
#
# * Integer - Finds the record with this primary key.
# * String - Finds the record with a primary key corresponding to this
# string (such as '5').
# * Array - Finds the record that matches these +find+-style conditions
# (such as ['name LIKE ?', "%#{query}%"]).
# * Hash - Finds the record that matches these +find+-style conditions
# (such as {name: 'David'}).
# * +false+ - Returns always +false+.
# * No args - Returns +false+ if the relation is empty, +true+ otherwise.
#
# For more information about specifying conditions as a hash or array,
# see the Conditions section in the introduction to ActiveRecord::Base.
#
# Note: You can't pass in a condition as a string (like name =
# 'Jamie'), since it would be sanitized and then queried against
# the primary key column, like id = 'name = \'Jamie\''.
#
# Person.exists?(5)
# Person.exists?('5')
# Person.exists?(['name LIKE ?', "%#{query}%"])
# Person.exists?(id: [1, 4, 8])
# Person.exists?(name: 'David')
# Person.exists?(false)
# Person.exists?
# Person.where(name: 'Spartacus', rating: 4).exists?
def exists?: (?::Symbol conditions) -> (::FalseClass | untyped)
def raise_record_not_found_exception!: (?untyped? ids, ?untyped? result_size, ?untyped? expected_size, ?untyped key, ?untyped? not_found_ids) -> untyped
def offset_index: () -> untyped
def construct_relation_for_exists: (untyped conditions) -> untyped
def apply_join_dependency: (?eager_loading: untyped eager_loading) { (untyped, untyped) -> untyped } -> untyped
def limited_ids_for: (untyped relation) -> untyped
def using_limitable_reflections?: (untyped reflections) -> untyped
def find_with_ids: (*untyped ids) -> (::Array[untyped] | untyped)
def find_one: (untyped id) -> untyped
def find_some: (untyped ids) -> untyped
def find_some_ordered: (untyped ids) -> untyped
def find_take: () -> untyped
def find_take_with_limit: (untyped limit) -> untyped
def find_nth: (untyped index) -> untyped
def find_nth_with_limit: (untyped index, untyped limit) -> untyped
def find_nth_from_last: (untyped index) -> untyped
def find_last: (untyped limit) -> untyped
def ordered_relation: () -> untyped
end
end
module ActiveRecord
class Relation
extend ::ActiveRecord::Delegation::ClassMethods
class FromClause
# :nodoc:
attr_reader value: untyped
# :nodoc:
attr_reader name: untyped
def initialize: (untyped value, untyped name) -> untyped
def merge: (untyped other) -> untyped
def empty?: () -> untyped
def ==: (untyped other) -> untyped
def self.empty: () -> untyped
end
end
end
module ActiveRecord
class Relation
class HashMerger
# :nodoc:
attr_reader relation: untyped
# :nodoc:
attr_reader hash: untyped
def initialize: (untyped relation, untyped hash) -> untyped
def merge: () -> untyped
# Applying values to a relation has some side effects. E.g.
# interpolation might take place for where values. So we should
# build a relation to merge in rather than directly merging
# the values.
def other: () -> untyped
end
class Merger
# :nodoc:
attr_reader relation: untyped
# :nodoc:
attr_reader values: untyped
# :nodoc:
attr_reader other: untyped
def initialize: (untyped relation, untyped other) -> untyped
NORMAL_VALUES: untyped
def normal_values: () -> untyped
def merge: () -> untyped
def merge_preloads: () -> (nil | untyped)
def merge_joins: () -> (nil | untyped)
def merge_outer_joins: () -> (nil | untyped)
def merge_multi_values: () -> untyped
def merge_single_values: () -> untyped
def merge_clauses: () -> untyped
def replace_from_clause?: () -> untyped
end
end
end
module ActiveRecord
class PredicateBuilder
class ArrayHandler
# :nodoc:
def initialize: (untyped predicate_builder) -> untyped
def call: (untyped attribute, untyped value) -> untyped
attr_reader predicate_builder: untyped
module NullPredicate
# :nodoc:
def self.or: (untyped other) -> untyped
end
end
end
end
module ActiveRecord
class PredicateBuilder
class AssociationQueryValue
# :nodoc:
def initialize: (untyped associated_table, untyped value) -> untyped
def queries: () -> ::Array[::Hash[untyped, untyped]]
attr_reader associated_table: untyped
attr_reader value: untyped
def ids: () -> untyped
def primary_key: () -> untyped
def convert_to_id: (untyped value) -> untyped
end
end
end
module ActiveRecord
class PredicateBuilder
class BaseHandler
# :nodoc:
def initialize: (untyped predicate_builder) -> untyped
def call: (untyped attribute, untyped value) -> untyped
attr_reader predicate_builder: untyped
end
end
end
module ActiveRecord
class PredicateBuilder
class BasicObjectHandler
# :nodoc:
def initialize: (untyped predicate_builder) -> untyped
def call: (untyped attribute, untyped value) -> untyped
attr_reader predicate_builder: untyped
end
end
end
module ActiveRecord
class PredicateBuilder
class PolymorphicArrayValue
# :nodoc:
def initialize: (untyped associated_table, untyped values) -> untyped
def queries: () -> untyped
attr_reader associated_table: untyped
attr_reader values: untyped
def type_to_ids_mapping: () -> untyped
def primary_key: (untyped value) -> untyped
def klass: (untyped value) -> untyped
def convert_to_id: (untyped value) -> untyped
end
end
end
module ActiveRecord
class PredicateBuilder
class RangeHandler
# :nodoc:
class RangeWithBinds < ::Struct[untyped]
attr_accessor begin(): untyped
attr_accessor end(): untyped
attr_accessor exclude_end?(): untyped
end
def initialize: (untyped predicate_builder) -> untyped
def call: (untyped attribute, untyped value) -> untyped
attr_reader predicate_builder: untyped
end
end
end
module ActiveRecord
class PredicateBuilder
def initialize: (untyped table) -> untyped
def build_from_hash: (untyped attributes) -> untyped
def self.references: (untyped attributes) -> untyped
# Define how a class is converted to Arel nodes when passed to +where+.
# The handler can be any object that responds to +call+, and will be used
# for any value that +===+ the class given. For example:
#
# MyCustomDateRange = Struct.new(:start, :end)
# handler = proc do |column, range|
# Arel::Nodes::Between.new(column,
# Arel::Nodes::And.new([range.start, range.end])
# )
# end
# ActiveRecord::PredicateBuilder.new("users").register_handler(MyCustomDateRange, handler)
def register_handler: (untyped klass, untyped handler) -> untyped
def build: (untyped attribute, untyped value) -> untyped
def build_bind_attribute: (untyped column_name, untyped value) -> Arel::Nodes::BindParam
def expand_from_hash: (untyped attributes) -> (::Array["1=0"] | untyped)
attr_reader table: untyped
def convert_dot_notation_to_hash: (untyped attributes) -> untyped
def handler_for: (untyped object) -> untyped
end
end
module ActiveRecord
class PredicateBuilder
class RelationHandler
# :nodoc:
def call: (untyped attribute, untyped value) -> untyped
end
end
end
module ActiveRecord
class Relation
class QueryAttribute < ActiveModel::Attribute
# :nodoc:
def type_cast: (untyped value) -> untyped
def value_for_database: () -> untyped
def with_cast_value: (untyped value) -> QueryAttribute
def nil?: () -> untyped
def infinite?: () -> untyped
def unboundable?: () -> untyped
def infinity?: (untyped value) -> untyped
end
end
end
module ActiveRecord
module QueryMethods
extend ActiveSupport::Concern
include ActiveModel::ForbiddenAttributesProtection
# WhereChain objects act as placeholder for queries in which #where does not have any parameter.
# In this case, #where must be chained with #not to return a new relation.
class WhereChain
include ActiveModel::ForbiddenAttributesProtection
def initialize: (untyped scope) -> untyped
# Returns a new relation expressing WHERE + NOT condition according to
# the conditions in the arguments.
#
# #not accepts conditions as a string, array, or hash. See QueryMethods#where for
# more details on each format.
#
# User.where.not("name = 'Jon'")
# # SELECT * FROM users WHERE NOT (name = 'Jon')
#
# User.where.not(["name = ?", "Jon"])
# # SELECT * FROM users WHERE NOT (name = 'Jon')
#
# User.where.not(name: "Jon")
# # SELECT * FROM users WHERE name != 'Jon'
#
# User.where.not(name: nil)
# # SELECT * FROM users WHERE name IS NOT NULL
#
# User.where.not(name: %w(Ko1 Nobu))
# # SELECT * FROM users WHERE name NOT IN ('Ko1', 'Nobu')
def not: (untyped opts, *untyped rest) -> untyped
def not_behaves_as_nor?: (untyped opts) -> (::FalseClass | untyped)
end
FROZEN_EMPTY_ARRAY: untyped
FROZEN_EMPTY_HASH: untyped
# Specify relationships to be included in the result set. For
# example:
#
# users = User.includes(:address)
# users.each do |user|
# user.address.city
# end
#
# allows you to access the +address+ attribute of the +User+ model without
# firing an additional query. This will often result in a
# performance improvement over a simple join.
#
# You can also specify multiple relationships, like this:
#
# users = User.includes(:address, :friends)
#
# Loading nested relationships is possible using a Hash:
#
# users = User.includes(:address, friends: [:address, :followers])
#
# === conditions
#
# If you want to add string conditions to your included models, you'll have
# to explicitly reference them. For example:
#
# User.includes(:posts).where('posts.name = ?', 'example')
#
# Will throw an error, but this will work:
#
# User.includes(:posts).where('posts.name = ?', 'example').references(:posts)
#
# Note that #includes works with association names while #references needs
# the actual table name.
#
# If you pass the conditions via hash, you don't need to call #references
# explicitly, as #where references the tables for you. For example, this
# will work correctly:
#
# User.includes(:posts).where(posts: { name: 'example' })
def includes: (*untyped args) -> untyped
def includes!: (*untyped args) -> untyped
# Forces eager loading by performing a LEFT OUTER JOIN on +args+:
#
# User.eager_load(:posts)
# # SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ...
# # FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
# # "users"."id"
def eager_load: (*untyped args) -> untyped
def eager_load!: (*untyped args) -> untyped
# Allows preloading of +args+, in the same way that #includes does:
#
# User.preload(:posts)
# # SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)
def preload: (*untyped args) -> untyped
def preload!: (*untyped args) -> untyped
# Extracts a named +association+ from the relation. The named association is first preloaded,
# then the individual association records are collected from the relation. Like so:
#
# account.memberships.extract_associated(:user)
# # => Returns collection of User records
#
# This is short-hand for:
#
# account.memberships.preload(:user).collect(&:user)
def extract_associated: (untyped association) -> untyped
# Use to indicate that the given +table_names+ are referenced by an SQL string,
# and should therefore be JOINed in any query rather than loaded separately.
# This method only works in conjunction with #includes.
# See #includes for more details.
#
# User.includes(:posts).where("posts.name = 'foo'")
# # Doesn't JOIN the posts table, resulting in an error.
#
# User.includes(:posts).where("posts.name = 'foo'").references(:posts)
# # Query now knows the string references posts, so adds a JOIN
def references: (*untyped table_names) -> untyped
def references!: (*untyped table_names) -> untyped
# Works in two unique ways.
#
# First: takes a block so it can be used just like Array#select.
#
# Model.all.select { |m| m.field == value }
#
# This will build an array of objects from the database for the scope,
# converting them into an array and iterating through them using
# Array#select.
#
# Second: Modifies the SELECT statement for the query so that only certain
# fields are retrieved:
#
# Model.select(:field)
# # => [#]
#
# Although in the above example it looks as though this method returns an
# array, it actually returns a relation object and can have other query
# methods appended to it, such as the other methods in ActiveRecord::QueryMethods.
#
# The argument to the method can also be an array of fields.
#
# Model.select(:field, :other_field, :and_one_more)
# # => [#]
#
# You can also use one or more strings, which will be used unchanged as SELECT fields.
#
# Model.select('field AS field_one', 'other_field AS field_two')
# # => [#]
#
# If an alias was specified, it will be accessible from the resulting objects:
#
# Model.select('field AS field_one').first.field_one
# # => "value"
#
# Accessing attributes of an object that do not have fields retrieved by a select
# except +id+ will throw ActiveModel::MissingAttributeError:
#
# Model.select(:field).first.other_field
# # => ActiveModel::MissingAttributeError: missing attribute: other_field
def select: (*untyped fields) -> untyped
def _select!: (*untyped fields) -> untyped
# Allows you to change a previously set select statement.
#
# Post.select(:title, :body)
# # SELECT `posts`.`title`, `posts`.`body` FROM `posts`
#
# Post.select(:title, :body).reselect(:created_at)
# # SELECT `posts`.`created_at` FROM `posts`
#
# This is short-hand for unscope(:select).select(fields).
# Note that we're unscoping the entire select statement.
def reselect: (*untyped args) -> untyped
def reselect!: (*untyped args) -> untyped
# Allows to specify a group attribute:
#
# User.group(:name)
# # SELECT "users".* FROM "users" GROUP BY name
#
# Returns an array with distinct records based on the +group+ attribute:
#
# User.select([:id, :name])
# # => [#, #, #]
#
# User.group(:name)
# # => [#, #]
#
# User.group('name AS grouped_name, age')
# # => [#, #, #]
#
# Passing in an array of attributes to group by is also supported.
#
# User.select([:id, :first_name]).group(:id, :first_name).first(3)
# # => [#, #, #]
def group: (*untyped args) -> untyped
def group!: (*untyped args) -> untyped
# Allows to specify an order attribute:
#
# User.order(:name)
# # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC
#
# User.order(email: :desc)
# # SELECT "users".* FROM "users" ORDER BY "users"."email" DESC
#
# User.order(:name, email: :desc)
# # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
#
# User.order('name')
# # SELECT "users".* FROM "users" ORDER BY name
#
# User.order('name DESC')
# # SELECT "users".* FROM "users" ORDER BY name DESC
#
# User.order('name DESC, email')
# # SELECT "users".* FROM "users" ORDER BY name DESC, email
def order: (*untyped args) -> untyped
def order!: (*untyped args) -> untyped
# Replaces any existing order defined on the relation with the specified order.
#
# User.order('email DESC').reorder('id ASC') # generated SQL has 'ORDER BY id ASC'
#
# Subsequent calls to order on the same relation will be appended. For example:
#
# User.order('email DESC').reorder('id ASC').order('name ASC')
#
# generates a query with 'ORDER BY id ASC, name ASC'.
def reorder: (*untyped args) -> untyped
def reorder!: (*untyped args) -> untyped
VALID_UNSCOPING_VALUES: untyped
# Removes an unwanted relation that is already defined on a chain of relations.
# This is useful when passing around chains of relations and would like to
# modify the relations without reconstructing the entire chain.
#
# User.order('email DESC').unscope(:order) == User.all
#
# The method arguments are symbols which correspond to the names of the methods
# which should be unscoped. The valid arguments are given in VALID_UNSCOPING_VALUES.
# The method can also be called with multiple arguments. For example:
#
# User.order('email DESC').select('id').where(name: "John")
# .unscope(:order, :select, :where) == User.all
#
# One can additionally pass a hash as an argument to unscope specific +:where+ values.
# This is done by passing a hash with a single key-value pair. The key should be
# +:where+ and the value should be the where value to unscope. For example:
#
# User.where(name: "John", active: true).unscope(where: :name)
# == User.where(active: true)
#
# This method is similar to #except, but unlike
# #except, it persists across merges:
#
# User.order('email').merge(User.except(:order))
# == User.order('email')
#
# User.order('email').merge(User.unscope(:order))
# == User.all
#
# This means it can be used in association definitions:
#
# has_many :comments, -> { unscope(where: :trashed) }
#
def unscope: (*untyped args) -> untyped
def unscope!: (*untyped args) -> untyped
# Performs a joins on +args+. The given symbol(s) should match the name of
# the association(s).
#
# User.joins(:posts)
# # SELECT "users".*
# # FROM "users"
# # INNER JOIN "posts" ON "posts"."user_id" = "users"."id"
#
# Multiple joins:
#
# User.joins(:posts, :account)
# # SELECT "users".*
# # FROM "users"
# # INNER JOIN "posts" ON "posts"."user_id" = "users"."id"
# # INNER JOIN "accounts" ON "accounts"."id" = "users"."account_id"
#
# Nested joins:
#
# User.joins(posts: [:comments])
# # SELECT "users".*
# # FROM "users"
# # INNER JOIN "posts" ON "posts"."user_id" = "users"."id"
# # INNER JOIN "comments" "comments_posts"
# # ON "comments_posts"."post_id" = "posts"."id"
#
# You can use strings in order to customize your joins:
#
# User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
# # SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
def joins: (*untyped args) -> untyped
def joins!: (*untyped args) -> untyped
# Performs a left outer joins on +args+:
#
# User.left_outer_joins(:posts)
# => SELECT "users".* FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
#
def left_outer_joins: (*untyped args) -> untyped
def left_outer_joins!: (*untyped args) -> untyped
# Returns a new relation, which is the result of filtering the current relation
# according to the conditions in the arguments.
#
# #where accepts conditions in one of several formats. In the examples below, the resulting
# SQL is given as an illustration; the actual query generated may be different depending
# on the database adapter.
#
# === string
#
# A single string, without additional arguments, is passed to the query
# constructor as an SQL fragment, and used in the where clause of the query.
#
# Client.where("orders_count = '2'")
# # SELECT * from clients where orders_count = '2';
#
# Note that building your own string from user input may expose your application
# to injection attacks if not done properly. As an alternative, it is recommended
# to use one of the following methods.
#
# === array
#
# If an array is passed, then the first element of the array is treated as a template, and
# the remaining elements are inserted into the template to generate the condition.
# Active Record takes care of building the query to avoid injection attacks, and will
# convert from the ruby type to the database type where needed. Elements are inserted
# into the string in the order in which they appear.
#
# User.where(["name = ? and email = ?", "Joe", "joe@example.com"])
# # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
#
# Alternatively, you can use named placeholders in the template, and pass a hash as the
# second element of the array. The names in the template are replaced with the corresponding
# values from the hash.
#
# User.where(["name = :name and email = :email", { name: "Joe", email: "joe@example.com" }])
# # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
#
# This can make for more readable code in complex queries.
#
# Lastly, you can use sprintf-style % escapes in the template. This works slightly differently
# than the previous methods; you are responsible for ensuring that the values in the template
# are properly quoted. The values are passed to the connector for quoting, but the caller
# is responsible for ensuring they are enclosed in quotes in the resulting SQL. After quoting,
# the values are inserted using the same escapes as the Ruby core method +Kernel::sprintf+.
#
# User.where(["name = '%s' and email = '%s'", "Joe", "joe@example.com"])
# # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
#
# If #where is called with multiple arguments, these are treated as if they were passed as
# the elements of a single array.
#
# User.where("name = :name and email = :email", { name: "Joe", email: "joe@example.com" })
# # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
#
# When using strings to specify conditions, you can use any operator available from
# the database. While this provides the most flexibility, you can also unintentionally introduce
# dependencies on the underlying database. If your code is intended for general consumption,
# test with multiple database backends.
#
# === hash
#
# #where will also accept a hash condition, in which the keys are fields and the values
# are values to be searched for.
#
# Fields can be symbols or strings. Values can be single values, arrays, or ranges.
#
# User.where({ name: "Joe", email: "joe@example.com" })
# # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'
#
# User.where({ name: ["Alice", "Bob"]})
# # SELECT * FROM users WHERE name IN ('Alice', 'Bob')
#
# User.where({ created_at: (Time.now.midnight - 1.day)..Time.now.midnight })
# # SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000')
#
# In the case of a belongs_to relationship, an association key can be used
# to specify the model if an ActiveRecord object is used as the value.
#
# author = Author.find(1)
#
# # The following queries will be equivalent:
# Post.where(author: author)
# Post.where(author_id: author)
#
# This also works with polymorphic belongs_to relationships:
#
# treasure = Treasure.create(name: 'gold coins')
# treasure.price_estimates << PriceEstimate.create(price: 125)
#
# # The following queries will be equivalent:
# PriceEstimate.where(estimate_of: treasure)
# PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure)
#
# === Joins
#
# If the relation is the result of a join, you may create a condition which uses any of the
# tables in the join. For string and array conditions, use the table name in the condition.
#
# User.joins(:posts).where("posts.created_at < ?", Time.now)
#
# For hash conditions, you can either use the table name in the key, or use a sub-hash.
#
# User.joins(:posts).where({ "posts.published" => true })
# User.joins(:posts).where({ posts: { published: true } })
#
# === no argument
#
# If no argument is passed, #where returns a new instance of WhereChain, that
# can be chained with #not to return a new relation that negates the where clause.
#
# User.where.not(name: "Jon")
# # SELECT * FROM users WHERE name != 'Jon'
#
# See WhereChain for more details on #not.
#
# === blank condition
#
# If the condition is any blank-ish object, then #where is a no-op and returns
# the current relation.
def where: (?::Symbol opts, *untyped rest) -> untyped
def where!: (untyped opts, *untyped rest) -> untyped
# Allows you to change a previously set where condition for a given attribute, instead of appending to that condition.
#
# Post.where(trashed: true).where(trashed: false)
# # WHERE `trashed` = 1 AND `trashed` = 0
#
# Post.where(trashed: true).rewhere(trashed: false)
# # WHERE `trashed` = 0
#
# Post.where(active: true).where(trashed: true).rewhere(trashed: false)
# # WHERE `active` = 1 AND `trashed` = 0
#
# This is short-hand for unscope(where: conditions.keys).where(conditions).
# Note that unlike reorder, we're only unscoping the named conditions -- not the entire where statement.
def rewhere: (untyped conditions) -> untyped
# Returns a new relation, which is the logical union of this relation and the one passed as an
# argument.
#
# The two relations must be structurally compatible: they must be scoping the same model, and
# they must differ only by #where (if no #group has been defined) or #having (if a #group is
# present). Neither relation may have a #limit, #offset, or #distinct set.
#
# Post.where("id = 1").or(Post.where("author_id = 3"))
# # SELECT `posts`.* FROM `posts` WHERE ((id = 1) OR (author_id = 3))
#
def or: (untyped other) -> untyped
def or!: (untyped other) -> untyped
# Allows to specify a HAVING clause. Note that you can't use HAVING
# without also specifying a GROUP clause.
#
# Order.having('SUM(price) > 30').group('user_id')
def having: (untyped opts, *untyped rest) -> untyped
def having!: (untyped opts, *untyped rest) -> untyped
# Specifies a limit for the number of records to retrieve.
#
# User.limit(10) # generated SQL has 'LIMIT 10'
#
# User.limit(10).limit(20) # generated SQL has 'LIMIT 20'
def limit: (untyped value) -> untyped
def limit!: (untyped value) -> untyped
# Specifies the number of rows to skip before returning rows.
#
# User.offset(10) # generated SQL has "OFFSET 10"
#
# Should be used with order.
#
# User.offset(10).order("name ASC")
def offset: (untyped value) -> untyped
def offset!: (untyped value) -> untyped
# Specifies locking settings (default to +true+). For more information
# on locking, please see ActiveRecord::Locking.
def lock: (?bool locks) -> untyped
def lock!: (?bool locks) -> untyped
# Returns a chainable relation with zero records.
#
# The returned relation implements the Null Object pattern. It is an
# object with defined null behavior and always returns an empty array of
# records without querying the database.
#
# Any subsequent condition chained to the returned relation will continue
# generating an empty relation and will not fire any query to the database.
#
# Used in cases where a method or scope could return zero records but the
# result needs to be chainable.
#
# For example:
#
# @posts = current_user.visible_posts.where(name: params[:name])
# # the visible_posts method is expected to return a chainable Relation
#
# def visible_posts
# case role
# when 'Country Manager'
# Post.where(country: country)
# when 'Reviewer'
# Post.published
# when 'Bad User'
# Post.none # It can't be chained if [] is returned.
# end
# end
#
def none: () -> untyped
def none!: () -> untyped
# Sets readonly attributes for the returned relation. If value is
# true (default), attempting to update a record will result in an error.
#
# users = User.readonly
# users.first.save
# => ActiveRecord::ReadOnlyRecord: User is marked as readonly
def readonly: (?bool value) -> untyped
def readonly!: (?bool value) -> untyped
# Sets attributes to be used when creating new records from a
# relation object.
#
# users = User.where(name: 'Oscar')
# users.new.name # => 'Oscar'
#
# users = users.create_with(name: 'DHH')
# users.new.name # => 'DHH'
#
# You can pass +nil+ to #create_with to reset attributes:
#
# users = users.create_with(nil)
# users.new.name # => 'Oscar'
def create_with: (untyped value) -> untyped
def create_with!: (untyped value) -> untyped
# Specifies table from which the records will be fetched. For example:
#
# Topic.select('title').from('posts')
# # SELECT title FROM posts
#
# Can accept other relation objects. For example:
#
# Topic.select('title').from(Topic.approved)
# # SELECT title FROM (SELECT * FROM topics WHERE approved = 't') subquery
#
# Topic.select('a.title').from(Topic.approved, :a)
# # SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a
#
def from: (untyped value, ?untyped? subquery_name) -> untyped
def from!: (untyped value, ?untyped? subquery_name) -> untyped
# Specifies whether the records should be unique or not. For example:
#
# User.select(:name)
# # Might return two records with the same name
#
# User.select(:name).distinct
# # Returns 1 record per distinct name
#
# User.select(:name).distinct.distinct(false)
# # You can also remove the uniqueness
def distinct: (?bool value) -> untyped
def distinct!: (?bool value) -> untyped
# Used to extend a scope with additional methods, either through
# a module or through a block provided.
#
# The object returned is a relation, which can be further extended.
#
# === Using a module
#
# module Pagination
# def page(number)
# # pagination code goes here
# end
# end
#
# scope = Model.all.extending(Pagination)
# scope.page(params[:page])
#
# You can also pass a list of modules:
#
# scope = Model.all.extending(Pagination, SomethingElse)
#
# === Using a block
#
# scope = Model.all.extending do
# def page(number)
# # pagination code goes here
# end
# end
# scope.page(params[:page])
#
# You can also use a block and a module list:
#
# scope = Model.all.extending(Pagination) do
# def per_page(number)
# # pagination code goes here
# end
# end
def extending: (*untyped modules) { () -> untyped } -> untyped
def extending!: (*untyped modules) { () -> untyped } -> untyped
# Specify optimizer hints to be used in the SELECT statement.
#
# Example (for MySQL):
#
# Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_MERGE(topics)")
# # SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
#
# Example (for PostgreSQL with pg_hint_plan):
#
# Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
# # SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
def optimizer_hints: (*untyped args) -> untyped
def optimizer_hints!: (*untyped args) -> untyped
# Reverse the existing order clause on the relation.
#
# User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC'
def reverse_order: () -> untyped
def reverse_order!: () -> untyped
def skip_query_cache!: (?bool value) -> untyped
def skip_preloading!: () -> untyped
# Adds an SQL comment to queries generated from this relation. For example:
#
# User.annotate("selecting user names").select(:name)
# # SELECT "users"."name" FROM "users" /* selecting user names */
#
# User.annotate("selecting", "user", "names").select(:name)
# # SELECT "users"."name" FROM "users" /* selecting */ /* user */ /* names */
#
# The SQL block comment delimiters, "/*" and "*/", will be added automatically.
def annotate: (*untyped args) -> untyped
def annotate!: (*untyped args) -> untyped
def arel: (?untyped? aliases) -> untyped
def construct_join_dependency: (untyped associations, untyped join_type) -> ActiveRecord::Associations::JoinDependency
def build_subquery: (untyped subquery_alias, untyped select_value) -> untyped
def assert_mutability!: () -> untyped
def build_arel: (untyped aliases) -> untyped
def build_from: () -> untyped
def select_association_list: (untyped associations) { () -> untyped } -> untyped
def valid_association_list: (untyped associations) -> untyped
def build_left_outer_joins: (untyped manager, untyped outer_joins, untyped aliases) -> untyped
def build_joins: (untyped manager, untyped joins, untyped aliases) -> untyped
def build_join_query: (untyped manager, untyped buckets, untyped join_type, untyped aliases) -> untyped
def build_select: (untyped arel) -> untyped
def arel_columns: (untyped columns) -> untyped
def arel_column: (untyped field) { (untyped) -> untyped } -> untyped
def table_name_matches?: (untyped from) -> untyped
def reverse_sql_order: (untyped order_query) -> (::Array[untyped] | untyped)
def does_not_support_reverse?: (untyped order) -> untyped
def build_order: (untyped arel) -> untyped
VALID_DIRECTIONS: untyped
def validate_order_args: (untyped args) -> untyped
def preprocess_order_args: (untyped order_args) -> untyped
def order_column: (untyped field) -> untyped
# Checks to make sure that the arguments are not blank. Note that if some
# blank-like object were initially passed into the query method, then this
# method will not raise an error.
#
# Example:
#
# Post.references() # raises an error
# Post.references([]) # does not raise an error
#
# This particular method should be called with a method_name and the args
# passed into that method as an input. For example:
#
# def references(*args)
# check_if_method_has_arguments!("references", args)
# ...
# end
def check_if_method_has_arguments!: (untyped method_name, untyped args) -> untyped
STRUCTURAL_OR_METHODS: untyped
def structurally_incompatible_values_for_or: (untyped other) -> untyped
def where_clause_factory: () -> untyped
DEFAULT_VALUES: ::Hash[untyped, untyped]
end
end
module ActiveRecord
# = Active Record \Relation
class Relation
MULTI_VALUE_METHODS: ::Array[untyped]
SINGLE_VALUE_METHODS: ::Array[untyped]
CLAUSE_METHODS: ::Array[untyped]
INVALID_METHODS_FOR_DELETE_ALL: ::Array[untyped]
VALUE_METHODS: untyped
include Enumerable[untyped, untyped]
include FinderMethods
include Calculations
include SpawnMethods
include QueryMethods
include Batches
include Explain
include Delegation
attr_reader table: untyped
attr_reader klass: untyped
attr_reader loaded: untyped
attr_reader predicate_builder: untyped
attr_accessor skip_preloading_value: untyped
def initialize: (untyped klass, ?values: ::Hash[untyped, untyped] values, ?predicate_builder: untyped predicate_builder, ?table: untyped table) -> untyped
def initialize_copy: (untyped other) -> untyped
def arel_attribute: (untyped name) -> untyped
def bind_attribute: (untyped name, untyped value) { (untyped, untyped) -> untyped } -> untyped
# Initializes new record from relation while maintaining the current
# scope.
#
# Expects arguments in the same format as {ActiveRecord::Base.new}[rdoc-ref:Core.new].
#
# users = User.where(name: 'DHH')
# user = users.new # => #
#
# You can also pass a block to new with the new record as argument:
#
# user = users.new { |user| user.name = 'Oscar' }
# user.name # => Oscar
def new: (?untyped? attributes) { () -> untyped } -> untyped
# Tries to create a new record with the same scoped attributes
# defined in the relation. Returns the initialized object if validation fails.
#
# Expects arguments in the same format as
# {ActiveRecord::Base.create}[rdoc-ref:Persistence::ClassMethods#create].
#
# ==== Examples
#
# users = User.where(name: 'Oscar')
# users.create # => #
#
# users.create(name: 'fxn')
# users.create # => #
#
# users.create { |user| user.name = 'tenderlove' }
# # => #
#
# users.create(name: nil) # validation on name
# # => #
def create: (?untyped? attributes) { () -> untyped } -> untyped
# Similar to #create, but calls
# {create!}[rdoc-ref:Persistence::ClassMethods#create!]
# on the base class. Raises an exception if a validation error occurs.
#
# Expects arguments in the same format as
# {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!].
def create!: (?untyped? attributes) { () -> untyped } -> untyped
def first_or_create: (?untyped? attributes) { () -> untyped } -> untyped
def first_or_create!: (?untyped? attributes) { () -> untyped } -> untyped
def first_or_initialize: (?untyped? attributes) { () -> untyped } -> untyped
# Finds the first record with the given attributes, or creates a record
# with the attributes if one is not found:
#
# # Find the first user named "Pen(trim non-ascii characters)lope" or create a new one.
# User.find_or_create_by(first_name: 'Pen(trim non-ascii characters)lope')
# # => #
#
# # Find the first user named "Pen(trim non-ascii characters)lope" or create a new one.
# # We already have one so the existing record will be returned.
# User.find_or_create_by(first_name: 'Pen(trim non-ascii characters)lope')
# # => #
#
# # Find the first user named "Scarlett" or create a new one with
# # a particular last name.
# User.create_with(last_name: 'Johansson').find_or_create_by(first_name: 'Scarlett')
# # => #
#
# This method accepts a block, which is passed down to #create. The last example
# above can be alternatively written this way:
#
# # Find the first user named "Scarlett" or create a new one with a
# # different last name.
# User.find_or_create_by(first_name: 'Scarlett') do |user|
# user.last_name = 'Johansson'
# end
# # => #
#
# This method always returns a record, but if creation was attempted and
# failed due to validation errors it won't be persisted, you get what
# #create returns in such situation.
#
# Please note this method is not atomic, it runs first a SELECT, and if
# there are no results an INSERT is attempted. If there are other threads
# or processes there is a race condition between both calls and it could
# be the case that you end up with two similar records.
#
# If this might be a problem for your application, please see #create_or_find_by.
def find_or_create_by: (untyped attributes) { () -> untyped } -> untyped
# Like #find_or_create_by, but calls
# {create!}[rdoc-ref:Persistence::ClassMethods#create!] so an exception
# is raised if the created record is invalid.
def find_or_create_by!: (untyped attributes) { () -> untyped } -> untyped
# Attempts to create a record with the given attributes in a table that has a unique constraint
# on one or several of its columns. If a row already exists with one or several of these
# unique constraints, the exception such an insertion would normally raise is caught,
# and the existing record with those attributes is found using #find_by!.
#
# This is similar to #find_or_create_by, but avoids the problem of stale reads between the SELECT
# and the INSERT, as that method needs to first query the table, then attempt to insert a row
# if none is found.
#
# There are several drawbacks to #create_or_find_by, though:
#
# * The underlying table must have the relevant columns defined with unique constraints.
# * A unique constraint violation may be triggered by only one, or at least less than all,
# of the given attributes. This means that the subsequent #find_by! may fail to find a
# matching record, which will then raise an ActiveRecord::RecordNotFound exception,
# rather than a record with the given attributes.
# * While we avoid the race condition between SELECT -> INSERT from #find_or_create_by,
# we actually have another race condition between INSERT -> SELECT, which can be triggered
# if a DELETE between those two statements is run by another client. But for most applications,
# that's a significantly less likely condition to hit.
# * It relies on exception handling to handle control flow, which may be marginally slower.
# * The primary key may auto-increment on each create, even if it fails. This can accelerate
# the problem of running out of integers, if the underlying table is still stuck on a primary
# key of type int (note: All Rails apps since 5.1+ have defaulted to bigint, which is not liable
# to this problem).
#
# This method will return a record if all given attributes are covered by unique constraints
# (unless the INSERT -> DELETE -> SELECT race condition is triggered), but if creation was attempted
# and failed due to validation errors it won't be persisted, you get what #create returns in
# such situation.
def create_or_find_by: (untyped attributes) { () -> untyped } -> untyped
# Like #create_or_find_by, but calls
# {create!}[rdoc-ref:Persistence::ClassMethods#create!] so an exception
# is raised if the created record is invalid.
def create_or_find_by!: (untyped attributes) { () -> untyped } -> untyped
# Like #find_or_create_by, but calls {new}[rdoc-ref:Core#new]
# instead of {create}[rdoc-ref:Persistence::ClassMethods#create].
def find_or_initialize_by: (untyped attributes) { () -> untyped } -> untyped
# Runs EXPLAIN on the query or queries triggered by this relation and
# returns the result as a string. The string is formatted imitating the
# ones printed by the database shell.
#
# Note that this method actually runs the queries, since the results of some
# are needed by the next ones when eager loading is going on.
#
# Please see further details in the
# {Active Record Query Interface guide}[https://guides.rubyonrails.org/active_record_querying.html#running-explain].
def explain: () -> untyped
# Converts relation objects to Array.
def to_ary: () -> untyped
def records: () -> untyped
# Serializes the relation objects Array.
def encode_with: (untyped coder) -> untyped
# Returns size of the records.
def size: () -> untyped
# Returns true if there are no records.
def empty?: () -> untyped
# Returns true if there are no records.
def none?: () -> untyped
# Returns true if there are any records.
def any?: () -> untyped
# Returns true if there is exactly one record.
def one?: () -> untyped
# Returns true if there is more than one record.
def many?: () -> untyped
# Returns a stable cache key that can be used to identify this query.
# The cache key is built with a fingerprint of the SQL query.
#
# Product.where("name like ?", "%Cosmic Encounter%").cache_key
# # => "products/query-1850ab3d302391b85b8693e941286659"
#
# If ActiveRecord::Base.collection_cache_versioning is turned off, as it was
# in Rails 6.0 and earlier, the cache key will also include a version.
#
# ActiveRecord::Base.collection_cache_versioning = false
# Product.where("name like ?", "%Cosmic Encounter%").cache_key
# # => "products/query-1850ab3d302391b85b8693e941286659-1-20150714212553907087000"
#
# You can also pass a custom timestamp column to fetch the timestamp of the
# last updated record.
#
# Product.where("name like ?", "%Game%").cache_key(:last_reviewed_at)
def cache_key: (?::Symbol timestamp_column) -> untyped
def compute_cache_key: (?::Symbol timestamp_column) -> untyped
# Returns a cache version that can be used together with the cache key to form
# a recyclable caching scheme. The cache version is built with the number of records
# matching the query, and the timestamp of the last updated record. When a new record
# comes to match the query, or any of the existing records is updated or deleted,
# the cache version changes.
#
# If the collection is loaded, the method will iterate through the records
# to generate the timestamp, otherwise it will trigger one SQL query like:
#
# SELECT COUNT(*), MAX("products"."updated_at") FROM "products" WHERE (name like '%Cosmic Encounter%')
def cache_version: (?::Symbol timestamp_column) -> untyped
def compute_cache_version: (untyped timestamp_column) -> untyped
# Returns a cache key along with the version.
def cache_key_with_version: () -> untyped
# Scope all queries to the current scope.
#
# Comment.where(post_id: 1).scoping do
# Comment.first
# end
# # => SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 ORDER BY "comments"."id" ASC LIMIT 1
#
# Please check unscoped if you want to remove all previous scopes (including
# the default_scope) during the execution of a block.
def scoping: () { () -> untyped } -> untyped
def _exec_scope: (untyped name, *untyped args) { () -> untyped } -> untyped
# Updates all records in the current relation with details given. This method constructs a single SQL UPDATE
# statement and sends it straight to the database. It does not instantiate the involved models and it does not
# trigger Active Record callbacks or validations. However, values passed to #update_all will still go through
# Active Record's normal type casting and serialization.
#
# Note: As Active Record callbacks are not triggered, this method will not automatically update +updated_at+/+updated_on+ columns.
#
# ==== Parameters
#
# * +updates+ - A string, array, or hash representing the SET part of an SQL statement.
#
# ==== Examples
#
# # Update all customers with the given attributes
# Customer.update_all wants_email: true
#
# # Update all books with 'Rails' in their title
# Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')
#
# # Update all books that match conditions, but limit it to 5 ordered by date
# Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(author: 'David')
#
# # Update all invoices and set the number column to its id value.
# Invoice.update_all('number = id')
def update_all: (untyped updates) -> untyped
def update: (?::Symbol id, untyped attributes) -> untyped
def update_counters: (untyped counters) -> untyped
# Touches all records in the current relation without instantiating records first with the +updated_at+/+updated_on+ attributes
# set to the current time or the time specified.
# This method can be passed attribute names and an optional time argument.
# If attribute names are passed, they are updated along with +updated_at+/+updated_on+ attributes.
# If no time argument is passed, the current time is used as default.
#
# === Examples
#
# # Touch all records
# Person.all.touch_all
# # => "UPDATE \"people\" SET \"updated_at\" = '2018-01-04 22:55:23.132670'"
#
# # Touch multiple records with a custom attribute
# Person.all.touch_all(:created_at)
# # => "UPDATE \"people\" SET \"updated_at\" = '2018-01-04 22:55:23.132670', \"created_at\" = '2018-01-04 22:55:23.132670'"
#
# # Touch multiple records with a specified time
# Person.all.touch_all(time: Time.new(2020, 5, 16, 0, 0, 0))
# # => "UPDATE \"people\" SET \"updated_at\" = '2020-05-16 00:00:00'"
#
# # Touch records with scope
# Person.where(name: 'David').touch_all
# # => "UPDATE \"people\" SET \"updated_at\" = '2018-01-04 22:55:23.132670' WHERE \"people\".\"name\" = 'David'"
def touch_all: (*untyped names, ?time: untyped? time) -> untyped
# Destroys the records by instantiating each
# record and calling its {#destroy}[rdoc-ref:Persistence#destroy] method.
# Each object's callbacks are executed (including :dependent association options).
# Returns the collection of objects that were destroyed; each will be frozen, to
# reflect that no changes should be made (since they can't be persisted).
#
# Note: Instantiation, callback execution, and deletion of each
# record can be time consuming when you're removing many records at
# once. It generates at least one SQL +DELETE+ query per record (or
# possibly more, to enforce your callbacks). If you want to delete many
# rows quickly, without concern for their associations or callbacks, use
# #delete_all instead.
#
# ==== Examples
#
# Person.where(age: 0..18).destroy_all
def destroy_all: () -> untyped
# Deletes the records without instantiating the records
# first, and hence not calling the {#destroy}[rdoc-ref:Persistence#destroy]
# method nor invoking callbacks.
# This is a single SQL DELETE statement that goes straight to the database, much more
# efficient than #destroy_all. Be careful with relations though, in particular
# :dependent rules defined on associations are not honored. Returns the
# number of rows affected.
#
# Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
#
# Both calls delete the affected posts all at once with a single DELETE statement.
# If you need to destroy dependent associations or call your before_* or
# +after_destroy+ callbacks, use the #destroy_all method instead.
#
# If an invalid method is supplied, #delete_all raises an ActiveRecordError:
#
# Post.distinct.delete_all
# # => ActiveRecord::ActiveRecordError: delete_all doesn't support distinct
def delete_all: () -> untyped
# Finds and destroys all records matching the specified conditions.
# This is short-hand for relation.where(condition).destroy_all.
# Returns the collection of objects that were destroyed.
#
# If no record is found, returns empty array.
#
# Person.destroy_by(id: 13)
# Person.destroy_by(name: 'Spartacus', rating: 4)
# Person.destroy_by("published_at < ?", 2.weeks.ago)
def destroy_by: (*untyped args) -> untyped
# Finds and deletes all records matching the specified conditions.
# This is short-hand for relation.where(condition).delete_all.
# Returns the number of rows affected.
#
# If no record is found, returns 0 as zero rows were affected.
#
# Person.delete_by(id: 13)
# Person.delete_by(name: 'Spartacus', rating: 4)
# Person.delete_by("published_at < ?", 2.weeks.ago)
def delete_by: (*untyped args) -> untyped
# Causes the records to be loaded from the database if they have not
# been loaded already. You can use this if for some reason you need
# to explicitly load some records before actually using them. The
# return value is the relation itself, not the records.
#
# Post.where(published: true).load # => #
def load: () { () -> untyped } -> untyped
# Forces reloading of relation.
def reload: () -> untyped
def reset: () -> untyped
# Returns sql statement for the relation.
#
# User.where(name: 'Oscar').to_sql
# # => SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar'
def to_sql: () -> untyped
# Returns a hash of where conditions.
#
# User.where(name: 'Oscar').where_values_hash
# # => {name: "Oscar"}
def where_values_hash: (?untyped relation_table_name) -> untyped
def scope_for_create: () -> untyped
# Returns true if relation needs eager loading.
def eager_loading?: () -> untyped
# Joins that are also marked for preloading. In which case we should just eager load them.
# Note that this is a naive implementation because we could have strings and symbols which
# represent the same association, but that aren't matched by this. Also, we could have
# nested hashes which partially match, e.g. { a: :b } & { a: [:b, :c] }
def joined_includes_values: () -> untyped
# Compares two relations for equality.
def ==: (untyped other) -> untyped
def pretty_print: (untyped q) -> untyped
# Returns true if relation is blank.
def blank?: () -> untyped
def values: () -> untyped
def inspect: () -> ::String
def empty_scope?: () -> untyped
def has_limit_or_offset?: () -> untyped
def alias_tracker: (?untyped joins, ?untyped? aliases) -> untyped
def preload_associations: (untyped records) -> untyped
attr_reader _deprecated_scope_source: untyped
attr_writer _deprecated_scope_source: untyped
def load_records: (untyped records) -> untyped
def null_relation?: () -> untyped
def already_in_scope?: () -> untyped
def _deprecated_spawn: (untyped name) -> untyped
def _deprecated_scope_block: (untyped name) { (untyped) -> untyped } -> untyped
def _scoping: (untyped scope) { () -> untyped } -> untyped
def _substitute_values: (untyped values) -> untyped
def _increment_attribute: (untyped attribute, ?::Integer value) -> untyped
def exec_queries: () { () -> untyped } -> untyped
def skip_query_cache_if_necessary: () { () -> untyped } -> untyped
def build_preloader: () -> ActiveRecord::Associations::Preloader
def references_eager_loaded_tables?: () -> untyped
def tables_in_string: (untyped string) -> (::Array[untyped] | untyped)
end
end
module ActiveRecord
class Relation
module RecordFetchWarning
# When this module is prepended to ActiveRecord::Relation and
# +config.active_record.warn_on_records_fetched_greater_than+ is
# set to an integer, if the number of records a query returns is
# greater than the value of +warn_on_records_fetched_greater_than+,
# a warning is logged. This allows for the detection of queries that
# return a large number of records, which could cause memory bloat.
#
# In most cases, fetching large number of records can be performed
# efficiently using the ActiveRecord::Batches methods.
# See ActiveRecord::Batches for more information.
def exec_queries: () -> untyped
class QueryRegistry
# :nodoc:
extend ActiveSupport::PerThreadRegistry
attr_reader queries: untyped
def initialize: () -> untyped
def reset: () -> untyped
end
end
end
end
module ActiveRecord
module SpawnMethods
def spawn: () -> untyped
# Merges in the conditions from other, if other is an ActiveRecord::Relation.
# Returns an array representing the intersection of the resulting records with other, if other is an array.
#
# Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
# # Performs a single join query with both where conditions.
#
# recent_posts = Post.order('created_at DESC').first(5)
# Post.where(published: true).merge(recent_posts)
# # Returns the intersection of all published posts with the 5 most recently created posts.
# # (This is just an example. You'd probably want to do this with a single query!)
#
# Procs will be evaluated by merge:
#
# Post.where(published: true).merge(-> { joins(:comments) })
# # => Post.where(published: true).joins(:comments)
#
# This is mainly intended for sharing common conditions between multiple associations.
def merge: (untyped other) -> untyped
def merge!: (untyped other) -> untyped
# Removes from the query the condition(s) specified in +skips+.
#
# Post.order('id asc').except(:order) # discards the order condition
# Post.where('id > 10').order('id asc').except(:where) # discards the where condition but keeps the order
def except: (*untyped skips) -> untyped
# Removes any condition from the query other than the one(s) specified in +onlies+.
#
# Post.order('id asc').only(:where) # discards the order condition
# Post.order('id asc').only(:where, :order) # uses the specified order
def only: (*untyped onlies) -> untyped
def relation_with: (untyped values) -> untyped
end
end
module ActiveRecord
class Relation
class WhereClauseFactory
# :nodoc:
def initialize: (untyped klass, untyped predicate_builder) -> untyped
def build: (untyped opts, untyped other) -> WhereClause
attr_reader klass: untyped
attr_reader predicate_builder: untyped
end
end
end
module ActiveRecord
class Relation
class WhereClause
def initialize: (untyped predicates) -> untyped
def +: (untyped other) -> WhereClause
def -: (untyped other) -> WhereClause
def merge: (untyped other) -> WhereClause
def except: (*untyped columns) -> WhereClause
def or: (untyped other) -> untyped
def to_h: (?untyped? table_name) -> untyped
def ast: () -> Arel::Nodes::And
def ==: (untyped other) -> untyped
def invert: (?::Symbol as) -> WhereClause
def self.empty: () -> untyped
attr_reader predicates: untyped
def referenced_columns: () -> untyped
def equalities: (untyped predicates) -> untyped
def predicates_unreferenced_by: (untyped other) -> untyped
def equality_node?: (untyped node) -> untyped
def invert_predicate: (untyped node) -> untyped
def except_predicates: (untyped columns) -> untyped
def predicates_with_wrapped_sql_literals: () -> untyped
ARRAY_WITH_EMPTY_STRING: ::Array[untyped]
def non_empty_predicates: () -> untyped
def wrap_sql_literal: (untyped node) -> Arel::Nodes::Grouping
def extract_node_value: (untyped node) -> untyped
end
end
end
module ActiveRecord
# #
# This class encapsulates a result returned from calling
# {#exec_query}[rdoc-ref:ConnectionAdapters::DatabaseStatements#exec_query]
# on any database connection adapter. For example:
#
# result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
# result # => #
#
# # Get the column names of the result:
# result.columns
# # => ["id", "title", "body"]
#
# # Get the record values of the result:
# result.rows
# # => [[1, "title_1", "body_1"],
# [2, "title_2", "body_2"],
# ...
# ]
#
# # Get an array of hashes representing the result (column => value):
# result.to_a
# # => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
# {"id" => 2, "title" => "title_2", "body" => "body_2"},
# ...
# ]
#
# # ActiveRecord::Result also includes Enumerable.
# result.each do |row|
# puts row['title'] + " " + row['body']
# end
class Result
include Enumerable[untyped, untyped]
attr_reader columns: untyped
attr_reader rows: untyped
attr_reader column_types: untyped
def initialize: (untyped columns, untyped rows, ?::Hash[untyped, untyped] column_types) -> untyped
# Returns true if this result set includes the column named +name+
def includes_column?: (untyped name) -> untyped
# Returns the number of elements in the rows array.
def length: () -> untyped
# Calls the given block once for each element in row collection, passing
# row as parameter.
#
# Returns an +Enumerator+ if no block is given.
def each: () { (untyped) -> untyped } -> untyped
def to_hash: () -> untyped
# Returns true if there are no records, otherwise false.
def empty?: () -> untyped
# Returns an array of hashes representing each row record.
def to_ary: () -> untyped
def []: (untyped idx) -> untyped
# Returns the first record from the rows collection.
# If the rows collection is empty, returns +nil+.
def first: () -> (nil | untyped)
# Returns the last record from the rows collection.
# If the rows collection is empty, returns +nil+.
def last: () -> (nil | untyped)
def cast_values: (?::Hash[untyped, untyped] type_overrides) -> untyped
def initialize_copy: (untyped other) -> untyped
def column_type: (untyped name, ?::Hash[untyped, untyped] type_overrides) -> untyped
def hash_rows: () -> untyped
end
end
module ActiveRecord
class RuntimeRegistry
# This is a thread locals registry for Active Record. For example:
#
# ActiveRecord::RuntimeRegistry.connection_handler
#
# returns the connection handler local to the current thread.
#
# See the documentation of ActiveSupport::PerThreadRegistry
# for further details.
# :nodoc:
extend ActiveSupport::PerThreadRegistry
attr_accessor connection_handler: untyped
attr_accessor sql_runtime: untyped
end
end
module ActiveRecord
module Sanitization
extend ActiveSupport::Concern
module ClassMethods
# Accepts an array or string of SQL conditions and sanitizes
# them into a valid SQL fragment for a WHERE clause.
#
# sanitize_sql_for_conditions(["name=? and group_id=?", "foo'bar", 4])
# # => "name='foo''bar' and group_id=4"
#
# sanitize_sql_for_conditions(["name=:name and group_id=:group_id", name: "foo'bar", group_id: 4])
# # => "name='foo''bar' and group_id='4'"
#
# sanitize_sql_for_conditions(["name='%s' and group_id='%s'", "foo'bar", 4])
# # => "name='foo''bar' and group_id='4'"
#
# sanitize_sql_for_conditions("name='foo''bar' and group_id='4'")
# # => "name='foo''bar' and group_id='4'"
def sanitize_sql_for_conditions: (untyped condition) -> (nil | untyped)
# Accepts an array, hash, or string of SQL conditions and sanitizes
# them into a valid SQL fragment for a SET clause.
#
# sanitize_sql_for_assignment(["name=? and group_id=?", nil, 4])
# # => "name=NULL and group_id=4"
#
# sanitize_sql_for_assignment(["name=:name and group_id=:group_id", name: nil, group_id: 4])
# # => "name=NULL and group_id=4"
#
# Post.sanitize_sql_for_assignment({ name: nil, group_id: 4 })
# # => "`posts`.`name` = NULL, `posts`.`group_id` = 4"
#
# sanitize_sql_for_assignment("name=NULL and group_id='4'")
# # => "name=NULL and group_id='4'"
def sanitize_sql_for_assignment: (untyped assignments, ?untyped default_table_name) -> untyped
# Accepts an array, or string of SQL conditions and sanitizes
# them into a valid SQL fragment for an ORDER clause.
#
# sanitize_sql_for_order(["field(id, ?)", [1,3,2]])
# # => "field(id, 1,3,2)"
#
# sanitize_sql_for_order("id ASC")
# # => "id ASC"
def sanitize_sql_for_order: (untyped condition) -> untyped
# Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
#
# sanitize_sql_hash_for_assignment({ status: nil, group_id: 1 }, "posts")
# # => "`posts`.`status` = NULL, `posts`.`group_id` = 1"
def sanitize_sql_hash_for_assignment: (untyped attrs, untyped table) -> untyped
# Sanitizes a +string+ so that it is safe to use within an SQL
# LIKE statement. This method uses +escape_character+ to escape all occurrences of "\", "_" and "%".
#
# sanitize_sql_like("100%")
# # => "100\\%"
#
# sanitize_sql_like("snake_cased_string")
# # => "snake\\_cased\\_string"
#
# sanitize_sql_like("100%", "!")
# # => "100!%"
#
# sanitize_sql_like("snake_cased_string", "!")
# # => "snake!_cased!_string"
def sanitize_sql_like: (untyped string, ?::String escape_character) -> untyped
# Accepts an array of conditions. The array has each value
# sanitized and interpolated into the SQL statement.
#
# sanitize_sql_array(["name=? and group_id=?", "foo'bar", 4])
# # => "name='foo''bar' and group_id=4"
#
# sanitize_sql_array(["name=:name and group_id=:group_id", name: "foo'bar", group_id: 4])
# # => "name='foo''bar' and group_id=4"
#
# sanitize_sql_array(["name='%s' and group_id='%s'", "foo'bar", 4])
# # => "name='foo''bar' and group_id='4'"
def sanitize_sql_array: (untyped ary) -> untyped
def disallow_raw_sql!: (untyped args, ?permit: untyped permit) -> (nil | untyped)
def replace_bind_variables: (untyped statement, untyped values) -> untyped
def replace_bind_variable: (untyped value, ?untyped c) -> untyped
def replace_named_bind_variables: (untyped statement, untyped bind_vars) -> untyped
def quote_bound_value: (untyped value, ?untyped c) -> untyped
def raise_if_bind_arity_mismatch: (untyped statement, untyped expected, untyped provided) -> untyped
end
end
end
module ActiveRecord
class SchemaDumper
def self.dump: (?untyped connection, ?untyped stream, ?untyped config) -> untyped
def self.generate_options: (untyped config) -> { table_name_prefix: untyped, table_name_suffix: untyped }
def dump: (untyped stream) -> untyped
attr_accessor table_name: untyped
def initialize: (untyped connection, ?::Hash[untyped, untyped] options) -> untyped
# turns 20170404131909 into "2017_04_04_131909"
def formatted_version: () -> untyped
def define_params: () -> untyped
def header: (untyped stream) -> untyped
def trailer: (untyped stream) -> untyped
# extensions are only supported by PostgreSQL
def extensions: (untyped stream) -> nil
def tables: (untyped stream) -> untyped
def table: (untyped table, untyped stream) -> untyped
# Keep it for indexing materialized views
def indexes: (untyped table, untyped stream) -> untyped
def indexes_in_create: (untyped table, untyped stream) -> untyped
def index_parts: (untyped index) -> untyped
def foreign_keys: (untyped table, untyped stream) -> untyped
def format_colspec: (untyped colspec) -> untyped
def format_options: (untyped options) -> untyped
def format_index_parts: (untyped options) -> untyped
def remove_prefix_and_suffix: (untyped table) -> untyped
def ignored?: (untyped table_name) -> untyped
end
end
module ActiveRecord
class SchemaMigration < ActiveRecord::Base
def self._internal?: () -> ::TrueClass
def self.primary_key: () -> "version"
def self.table_name: () -> ::String
def self.table_exists?: () -> untyped
def self.create_table: () -> untyped
def self.drop_table: () -> untyped
def self.normalize_migration_number: (untyped number) -> untyped
def self.normalized_versions: () -> untyped
def self.all_versions: () -> untyped
def version: () -> untyped
end
end
module ActiveRecord
# = Active Record \Schema
#
# Allows programmers to programmatically define a schema in a portable
# DSL. This means you can define tables, indexes, etc. without using SQL
# directly, so your applications can more easily support multiple
# databases.
#
# Usage:
#
# ActiveRecord::Schema.define do
# create_table :authors do |t|
# t.string :name, null: false
# end
#
# add_index :authors, :name, :unique
#
# create_table :posts do |t|
# t.integer :author_id, null: false
# t.string :subject
# t.text :body
# t.boolean :private, default: false
# end
#
# add_index :posts, :author_id
# end
#
# ActiveRecord::Schema is only supported by database adapters that also
# support migrations, the two features being very similar.
class Schema < Migration::Current
# Eval the given block. All methods available to the current connection
# adapter are available within the block, so you can easily use the
# database definition DSL to build up your schema (
# {create_table}[rdoc-ref:ConnectionAdapters::SchemaStatements#create_table],
# {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index], etc.).
#
# The +info+ hash is optional, and if given is used to define metadata
# about the current schema (currently, only the schema's version):
#
# ActiveRecord::Schema.define(version: 2038_01_19_000001) do
# ...
# end
def self.define: (?::Hash[untyped, untyped] info) { () -> untyped } -> untyped
def define: (untyped info) { () -> untyped } -> untyped
end
end
module ActiveRecord
module Scoping
module Default
extend ActiveSupport::Concern
module ClassMethods
# Returns a scope for the model without the previously set scopes.
#
# class Post < ActiveRecord::Base
# def self.default_scope
# where(published: true)
# end
# end
#
# Post.all # Fires "SELECT * FROM posts WHERE published = true"
# Post.unscoped.all # Fires "SELECT * FROM posts"
# Post.where(published: false).unscoped.all # Fires "SELECT * FROM posts"
#
# This method also accepts a block. All queries inside the block will
# not use the previously set scopes.
#
# Post.unscoped {
# Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
# }
def unscoped: () { () -> untyped } -> untyped
def scope_attributes?: () -> untyped
def before_remove_const: () -> untyped
def default_scope: (?untyped? scope) { () -> untyped } -> untyped
def build_default_scope: (?untyped relation) -> (nil | untyped)
def ignore_default_scope?: () -> untyped
def ignore_default_scope=: (untyped ignore) -> untyped
# The ignore_default_scope flag is used to prevent an infinite recursion
# situation where a default scope references a scope which has a default
# scope which references a scope...
def evaluate_default_scope: () { () -> untyped } -> (nil | untyped)
end
end
end
end
module ActiveRecord
# = Active Record \Named \Scopes
module Scoping
module Named
extend ActiveSupport::Concern
module ClassMethods
# Returns an ActiveRecord::Relation scope object.
#
# posts = Post.all
# posts.size # Fires "select count(*) from posts" and returns the count
# posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
#
# fruits = Fruit.all
# fruits = fruits.where(color: 'red') if options[:red_only]
# fruits = fruits.limit(10) if limited?
#
# You can define a scope that applies to all finders using
# {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope].
def all: () -> untyped
def scope_for_association: (?untyped scope) -> untyped
# Returns a scope for the model with default scopes.
def default_scoped: (?untyped scope) -> untyped
def default_extensions: () -> untyped
# Adds a class method for retrieving and querying objects.
# The method is intended to return an ActiveRecord::Relation
# object, which is composable with other scopes.
# If it returns +nil+ or +false+, an
# {all}[rdoc-ref:Scoping::Named::ClassMethods#all] scope is returned instead.
#
# A \scope represents a narrowing of a database query, such as
# where(color: :red).select('shirts.*').includes(:washing_instructions).
#
# class Shirt < ActiveRecord::Base
# scope :red, -> { where(color: 'red') }
# scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) }
# end
#
# The above calls to #scope define class methods Shirt.red and
# Shirt.dry_clean_only. Shirt.red, in effect,
# represents the query Shirt.where(color: 'red').
#
# You should always pass a callable object to the scopes defined
# with #scope. This ensures that the scope is re-evaluated each
# time it is called.
#
# Note that this is simply 'syntactic sugar' for defining an actual
# class method:
#
# class Shirt < ActiveRecord::Base
# def self.red
# where(color: 'red')
# end
# end
#
# Unlike Shirt.find(...), however, the object returned by
# Shirt.red is not an Array but an ActiveRecord::Relation,
# which is composable with other scopes; it resembles the association object
# constructed by a {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
# declaration. For instance, you can invoke Shirt.red.first, Shirt.red.count,
# Shirt.red.where(size: 'small'). Also, just as with the
# association objects, named \scopes act like an Array, implementing
# Enumerable; Shirt.red.each(&block), Shirt.red.first,
# and Shirt.red.inject(memo, &block) all behave as if
# Shirt.red really was an array.
#
# These named \scopes are composable. For instance,
# Shirt.red.dry_clean_only will produce all shirts that are
# both red and dry clean only. Nested finds and calculations also work
# with these compositions: Shirt.red.dry_clean_only.count
# returns the number of garments for which these criteria obtain.
# Similarly with Shirt.red.dry_clean_only.average(:thread_count).
#
# All scopes are available as class methods on the ActiveRecord::Base
# descendant upon which the \scopes were defined. But they are also
# available to {has_many}[rdoc-ref:Associations::ClassMethods#has_many]
# associations. If,
#
# class Person < ActiveRecord::Base
# has_many :shirts
# end
#
# then elton.shirts.red.dry_clean_only will return all of
# Elton's red, dry clean only shirts.
#
# \Named scopes can also have extensions, just as with
# {has_many}[rdoc-ref:Associations::ClassMethods#has_many] declarations:
#
# class Shirt < ActiveRecord::Base
# scope :red, -> { where(color: 'red') } do
# def dom_id
# 'red_shirts'
# end
# end
# end
#
# Scopes can also be used while creating/building a record.
#
# class Article < ActiveRecord::Base
# scope :published, -> { where(published: true) }
# end
#
# Article.published.new.published # => true
# Article.published.create.published # => true
#
# \Class methods on your model are automatically available
# on scopes. Assuming the following setup:
#
# class Article < ActiveRecord::Base
# scope :published, -> { where(published: true) }
# scope :featured, -> { where(featured: true) }
#
# def self.latest_article
# order('published_at desc').first
# end
#
# def self.titles
# pluck(:title)
# end
# end
#
# We are able to call the methods like this:
#
# Article.published.featured.latest_article
# Article.featured.titles
def scope: (untyped name, untyped body) { () -> untyped } -> untyped
def valid_scope_name?: (untyped name) -> untyped
end
end
end
end
module ActiveRecord
module Scoping
extend ActiveSupport::Concern
include Default
include Named
module ClassMethods
# :nodoc:
# Collects attributes from scopes that should be applied when creating
# an AR instance for the particular class this is called on.
def scope_attributes: () -> untyped
# Are there attributes associated with this scope?
def scope_attributes?: () -> untyped
def current_scope: (?bool skip_inherited_scope) -> untyped
def current_scope=: (untyped scope) -> untyped
end
def populate_with_current_scope_attributes: () -> (nil | untyped)
def initialize_internals_callback: () -> untyped
class ScopeRegistry
# This class stores the +:current_scope+ and +:ignore_default_scope+ values
# for different classes. The registry is stored as a thread local, which is
# accessed through +ScopeRegistry.current+.
#
# This class allows you to store and get the scope values on different
# classes and different types of scopes. For example, if you are attempting
# to get the current_scope for the +Board+ model, then you would use the
# following code:
#
# registry = ActiveRecord::Scoping::ScopeRegistry
# registry.set_value_for(:current_scope, Board, some_new_scope)
#
# Now when you run:
#
# registry.value_for(:current_scope, Board)
#
# You will obtain whatever was defined in +some_new_scope+. The #value_for
# and #set_value_for methods are delegated to the current ScopeRegistry
# object, so the above example code can also be called as:
#
# ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope,
# Board, some_new_scope)
# :nodoc:
extend ActiveSupport::PerThreadRegistry
VALID_SCOPE_TYPES: ::Array[untyped]
def initialize: () -> untyped
# Obtains the value for a given +scope_type+ and +model+.
def value_for: (untyped scope_type, untyped model, ?bool skip_inherited_scope) -> untyped
# Sets the +value+ for a given +scope_type+ and +model+.
def set_value_for: (untyped scope_type, untyped model, untyped value) -> untyped
def raise_invalid_scope_type!: (untyped scope_type) -> untyped
end
end
end
module ActiveRecord
module SecureToken
extend ActiveSupport::Concern
module ClassMethods
# Example using #has_secure_token
#
# # Schema: User(token:string, auth_token:string)
# class User < ActiveRecord::Base
# has_secure_token
# has_secure_token :auth_token
# end
#
# user = User.new
# user.save
# user.token # => "pX27zsMN2ViQKta1bGfLmVJE"
# user.auth_token # => "77TMHrHJFvFDwodq8w7Ev2m7"
# user.regenerate_token # => true
# user.regenerate_auth_token # => true
#
# SecureRandom::base58 is used to generate the 24-character unique token, so collisions are highly unlikely.
#
# Note that it's still possible to generate a race condition in the database in the same way that
# {validates_uniqueness_of}[rdoc-ref:Validations::ClassMethods#validates_uniqueness_of] can.
# You're encouraged to add a unique index in the database to deal with this even more unlikely scenario.
def has_secure_token: (?::Symbol attribute) -> untyped
def generate_unique_secure_token: () -> untyped
end
end
end
module ActiveRecord
# nodoc:
# = Active Record \Serialization
module Serialization
extend ActiveSupport::Concern
include ActiveModel::Serializers::JSON
def serializable_hash: (?untyped? options) -> untyped
end
end
module ActiveRecord
class StatementCache
class Substitute
end
class Query
# :nodoc:
def initialize: (untyped sql) -> untyped
def sql_for: (untyped binds, untyped connection) -> untyped
end
class PartialQuery < Query
# :nodoc:
def initialize: (untyped values) -> untyped
def sql_for: (untyped binds, untyped connection) -> untyped
end
class PartialQueryCollector
def initialize: () -> untyped
def <<: (untyped str) -> untyped
def add_bind: (untyped obj) -> untyped
def value: () -> ::Array[untyped]
end
def self.query: (untyped sql) -> Query
def self.partial_query: (untyped values) -> PartialQuery
def self.partial_query_collector: () -> PartialQueryCollector
class Params
# :nodoc:
def bind: () -> Substitute
end
class BindMap
# :nodoc:
def initialize: (untyped bound_attributes) -> untyped
def bind: (untyped values) -> untyped
end
def self.create: (untyped connection, ?untyped? callable) { () -> untyped } -> untyped
def initialize: (untyped query_builder, untyped bind_map, untyped klass) -> untyped
def execute: (untyped params, untyped connection) { () -> untyped } -> untyped
def self.unsupported_value?: (untyped value) -> untyped
attr_reader query_builder: untyped
attr_reader bind_map: untyped
attr_reader klass: untyped
end
end
module ActiveRecord
# Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column.
# It's like a simple key/value store baked into your record when you don't care about being able to
# query that store outside the context of a single record.
#
# You can then declare accessors to this store that are then accessible just like any other attribute
# of the model. This is very helpful for easily exposing store keys to a form or elsewhere that's
# already built around just accessing attributes on the model.
#
# Every accessor comes with dirty tracking methods (+key_changed?+, +key_was+ and +key_change+) and
# methods to access the changes made during the last save (+saved_change_to_key?+, +saved_change_to_key+ and
# +key_before_last_save+).
#
# NOTE: There is no +key_will_change!+ method for accessors, use +store_will_change!+ instead.
#
# Make sure that you declare the database column used for the serialized store as a text, so there's
# plenty of room.
#
# You can set custom coder to encode/decode your serialized attributes to/from different formats.
# JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides +load+ and +dump+.
#
# NOTE: If you are using structured database data types (eg. PostgreSQL +hstore+/+json+, or MySQL 5.7+
# +json+) there is no need for the serialization provided by {.store}[rdoc-ref:rdoc-ref:ClassMethods#store].
# Simply use {.store_accessor}[rdoc-ref:ClassMethods#store_accessor] instead to generate
# the accessor methods. Be aware that these columns use a string keyed hash and do not allow access
# using a symbol.
#
# NOTE: The default validations with the exception of +uniqueness+ will work.
# For example, if you want to check for +uniqueness+ with +hstore+ you will
# need to use a custom validation to handle it.
#
# Examples:
#
# class User < ActiveRecord::Base
# store :settings, accessors: [ :color, :homepage ], coder: JSON
# store :parent, accessors: [ :name ], coder: JSON, prefix: true
# store :spouse, accessors: [ :name ], coder: JSON, prefix: :partner
# store :settings, accessors: [ :two_factor_auth ], suffix: true
# store :settings, accessors: [ :login_retry ], suffix: :config
# end
#
# u = User.new(color: 'black', homepage: '37signals.com', parent_name: 'Mary', partner_name: 'Lily')
# u.color # Accessor stored attribute
# u.parent_name # Accessor stored attribute with prefix
# u.partner_name # Accessor stored attribute with custom prefix
# u.two_factor_auth_settings # Accessor stored attribute with suffix
# u.login_retry_config # Accessor stored attribute with custom suffix
# u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
#
# # There is no difference between strings and symbols for accessing custom attributes
# u.settings[:country] # => 'Denmark'
# u.settings['country'] # => 'Denmark'
#
# # Dirty tracking
# u.color = 'green'
# u.color_changed? # => true
# u.color_was # => 'black'
# u.color_change # => ['black', 'red']
#
# # Add additional accessors to an existing store through store_accessor
# class SuperUser < User
# store_accessor :settings, :privileges, :servants
# store_accessor :parent, :birthday, prefix: true
# store_accessor :settings, :secret_question, suffix: :config
# end
#
# The stored attribute names can be retrieved using {.stored_attributes}[rdoc-ref:rdoc-ref:ClassMethods#stored_attributes].
#
# User.stored_attributes[:settings] # [:color, :homepage, :two_factor_auth, :login_retry]
#
# == Overwriting default accessors
#
# All stored values are automatically available through accessors on the Active Record
# object, but sometimes you want to specialize this behavior. This can be done by overwriting
# the default accessors (using the same name as the attribute) and calling super
# to actually change things.
#
# class Song < ActiveRecord::Base
# # Uses a stored integer to hold the volume adjustment of the song
# store :settings, accessors: [:volume_adjustment]
#
# def volume_adjustment=(decibels)
# super(decibels.to_i)
# end
#
# def volume_adjustment
# super.to_i
# end
# end
module Store
extend ActiveSupport::Concern
attr_accessor local_stored_attributes: untyped
module ClassMethods
def store: (untyped store_attribute, ?::Hash[untyped, untyped] options) -> untyped
def store_accessor: (untyped store_attribute, *untyped keys, ?suffix: untyped? suffix, ?prefix: untyped? prefix) -> (::FalseClass | nil | untyped)
def _store_accessors_module: () -> untyped
def stored_attributes: () -> untyped
end
def read_store_attribute: (untyped store_attribute, untyped key) -> untyped
def write_store_attribute: (untyped store_attribute, untyped key, untyped value) -> untyped
def store_accessor_for: (untyped store_attribute) -> untyped
class HashAccessor
# :nodoc:
def self.read: (untyped object, untyped attribute, untyped key) -> untyped
def self.write: (untyped object, untyped attribute, untyped key, untyped value) -> untyped
def self.prepare: (untyped object, untyped attribute) -> untyped
end
class StringKeyedHashAccessor < HashAccessor
# :nodoc:
def self.read: (untyped object, untyped attribute, untyped key) -> untyped
def self.write: (untyped object, untyped attribute, untyped key, untyped value) -> untyped
end
class IndifferentHashAccessor < ActiveRecord::Store::HashAccessor
# :nodoc:
def self.prepare: (untyped object, untyped store_attribute) -> untyped
end
class IndifferentCoder
# :nodoc:
def initialize: (untyped attr_name, untyped coder_or_class_name) -> untyped
def dump: (untyped obj) -> untyped
def load: (untyped yaml) -> untyped
def self.as_indifferent_hash: (untyped obj) -> untyped
end
end
end
module ActiveRecord
# ActiveRecord::Suppressor prevents the receiver from being saved during
# a given block.
#
# For example, here's a pattern of creating notifications when new comments
# are posted. (The notification may in turn trigger an email, a push
# notification, or just appear in the UI somewhere):
#
# class Comment < ActiveRecord::Base
# belongs_to :commentable, polymorphic: true
# after_create -> { Notification.create! comment: self,
# recipients: commentable.recipients }
# end
#
# That's what you want the bulk of the time. New comment creates a new
# Notification. But there may well be off cases, like copying a commentable
# and its comments, where you don't want that. So you'd have a concern
# something like this:
#
# module Copyable
# def copy_to(destination)
# Notification.suppress do
# # Copy logic that creates new comments that we do not want
# # triggering notifications.
# end
# end
# end
module Suppressor
extend ActiveSupport::Concern
module ClassMethods
def suppress: () { () -> untyped } -> untyped
end
def save: () -> untyped
def save!: () -> untyped
end
class SuppressorRegistry
# :nodoc:
extend ActiveSupport::PerThreadRegistry
attr_reader suppressed: untyped
def initialize: () -> untyped
end
end
module ActiveRecord
class TableMetadata
def initialize: (untyped klass, untyped arel_table, ?untyped? association, ?untyped types) -> untyped
def resolve_column_aliases: (untyped hash) -> untyped
def arel_attribute: (untyped column_name) -> untyped
def `type`: (untyped column_name) -> untyped
def has_column?: (untyped column_name) -> untyped
def associated_with?: (untyped association_name) -> untyped
def associated_table: (untyped table_name) -> untyped
def associated_predicate_builder: (untyped table_name) -> untyped
def polymorphic_association?: () -> untyped
def aggregated_with?: (untyped aggregation_name) -> untyped
def reflect_on_aggregation: (untyped aggregation_name) -> untyped
def predicate_builder: () -> untyped
attr_reader klass: untyped
attr_reader types: untyped
attr_reader arel_table: untyped
attr_reader association: untyped
end
end
module ActiveRecord
module Tasks
class DatabaseAlreadyExists < StandardError
end
class DatabaseNotSupported < StandardError
end
# ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
# logic behind common tasks used to manage database and migrations.
#
# The tasks defined here are used with Rails commands provided by Active Record.
#
# In order to use DatabaseTasks, a few config values need to be set. All the needed
# config values are set by Rails already, so it's necessary to do it only if you
# want to change the defaults or when you want to use Active Record outside of Rails
# (in such case after configuring the database tasks, you can also use the rake tasks
# defined in Active Record).
#
# The possible config values are:
#
# * +env+: current environment (like Rails.env).
# * +database_configuration+: configuration of your databases (as in +config/database.yml+).
# * +db_dir+: your +db+ directory.
# * +fixtures_path+: a path to fixtures directory.
# * +migrations_paths+: a list of paths to directories with migrations.
# * +seed_loader+: an object which will load seeds, it needs to respond to the +load_seed+ method.
# * +root+: a path to the root of the application.
#
# Example usage of DatabaseTasks outside Rails could look as such:
#
# include ActiveRecord::Tasks
# DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml')
# DatabaseTasks.db_dir = 'db'
# # other settings...
#
# DatabaseTasks.create_current('production')
module DatabaseTasks
attr_writer current_config: untyped
attr_writer db_dir: untyped
attr_writer migrations_paths: untyped
attr_writer fixtures_path: untyped
attr_writer root: untyped
attr_writer env: untyped
attr_writer seed_loader: untyped
attr_accessor database_configuration: untyped
LOCAL_HOSTS: ::Array[untyped]
def check_protected_environments!: () -> untyped
def register_task: (untyped pattern, untyped task) -> untyped
def db_dir: () -> untyped
def migrations_paths: () -> untyped
def fixtures_path: () -> untyped
def root: () -> untyped
def env: () -> untyped
def spec: () -> untyped
def seed_loader: () -> untyped
def current_config: (?::Hash[untyped, untyped] options) -> untyped
def create: (*untyped arguments) -> untyped
def create_all: () -> untyped
def setup_initial_database_yaml: () -> (::Hash[untyped, untyped] | untyped)
def for_each: (untyped databases) { (untyped) -> untyped } -> (::Hash[untyped, untyped] | nil | untyped)
def raise_for_multi_db: (?untyped environment, command: untyped command) -> untyped
def create_current: (?untyped environment, ?untyped? spec_name) -> untyped
def drop: (*untyped arguments) -> untyped
def drop_all: () -> untyped
def drop_current: (?untyped environment) -> untyped
def truncate_tables: (untyped configuration) -> untyped
def truncate_all: (?untyped environment) -> untyped
def migrate: () -> untyped
def migrate_status: () -> untyped
def check_target_version: () -> untyped
def target_version: () -> untyped
def charset_current: (?untyped environment, ?untyped specification_name) -> untyped
def charset: (*untyped arguments) -> untyped
def collation_current: (?untyped environment, ?untyped specification_name) -> untyped
def collation: (*untyped arguments) -> untyped
def purge: (untyped configuration) -> untyped
def purge_all: () -> untyped
def purge_current: (?untyped environment) -> untyped
def structure_dump: (*untyped arguments) -> untyped
def structure_load: (*untyped arguments) -> untyped
def load_schema: (untyped configuration, ?untyped format, ?untyped? file, ?untyped environment, ?::String spec_name) -> untyped
def schema_up_to_date?: (untyped configuration, ?untyped format, ?untyped? file, ?untyped environment, ?::String spec_name) -> (::TrueClass | ::FalseClass | untyped)
def reconstruct_from_schema: (untyped configuration, ?untyped format, ?untyped? file, ?untyped environment, ?::String spec_name) -> untyped
def dump_schema: (untyped configuration, ?untyped format, ?::String spec_name) -> untyped
def schema_file: (?untyped format) -> untyped
def schema_file_type: (?untyped format) -> untyped
def dump_filename: (untyped namespace, ?untyped format) -> untyped
def cache_dump_filename: (untyped namespace) -> untyped
def load_schema_current: (?untyped format, ?untyped? file, ?untyped environment) -> untyped
def check_schema_file: (untyped filename) -> untyped
def load_seed: () -> untyped
# Dumps the schema cache in YAML format for the connection into the file
#
# ==== Examples:
# ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
def dump_schema_cache: (untyped conn, untyped filename) -> untyped
def verbose?: () -> untyped
def class_for_adapter: (untyped adapter) -> untyped
def each_current_configuration: (untyped environment, ?untyped? spec_name) { (untyped, untyped, untyped) -> untyped } -> untyped
def each_local_configuration: () { (untyped) -> untyped } -> untyped
def local_database?: (untyped configuration) -> untyped
def schema_sha1: (untyped file) -> untyped
end
end
end
module ActiveRecord
module Tasks
class MySQLDatabaseTasks
# :nodoc:
# :nodoc:
ER_DB_CREATE_EXISTS: ::Integer
def initialize: (untyped configuration) -> untyped
def create: () -> untyped
def drop: () -> untyped
def purge: () -> untyped
def charset: () -> untyped
def collation: () -> untyped
def structure_dump: (untyped filename, untyped extra_flags) -> untyped
def structure_load: (untyped filename, untyped extra_flags) -> untyped
attr_reader configuration: untyped
def configuration_without_database: () -> untyped
def creation_options: () -> untyped
def prepare_command_options: () -> untyped
def run_cmd: (untyped cmd, untyped args, untyped action) -> untyped
def run_cmd_error: (untyped cmd, untyped args, untyped action) -> untyped
end
end
end
module ActiveRecord
module Tasks
class PostgreSQLDatabaseTasks
# :nodoc:
# :nodoc:
DEFAULT_ENCODING: untyped
ON_ERROR_STOP_1: ::String
SQL_COMMENT_BEGIN: ::String
def initialize: (untyped configuration) -> untyped
def create: (?bool master_established) -> untyped
def drop: () -> untyped
def charset: () -> untyped
def collation: () -> untyped
def purge: () -> untyped
def structure_dump: (untyped filename, untyped extra_flags) -> untyped
def structure_load: (untyped filename, untyped extra_flags) -> untyped
attr_reader configuration: untyped
def encoding: () -> untyped
def establish_master_connection: () -> untyped
def set_psql_env: () -> untyped
def run_cmd: (untyped cmd, untyped args, untyped action) -> untyped
def run_cmd_error: (untyped cmd, untyped args, untyped action) -> untyped
def remove_sql_header_comments: (untyped filename) -> untyped
end
end
end
module ActiveRecord
module Tasks
class SQLiteDatabaseTasks
def initialize: (untyped configuration, ?untyped root) -> untyped
def create: () -> untyped
def drop: () -> untyped
def purge: () -> untyped
def charset: () -> untyped
def structure_dump: (untyped filename, untyped extra_flags) -> untyped
def structure_load: (untyped filename, untyped extra_flags) -> untyped
attr_reader configuration: untyped
attr_reader root: untyped
def run_cmd: (untyped cmd, untyped args, untyped `out`) -> untyped
def run_cmd_error: (untyped cmd, untyped args) -> untyped
end
end
end
module ActiveRecord
module TestDatabases
def self.create_and_load_schema: (untyped i, env_name: untyped env_name) -> untyped
end
end
module ActiveRecord
module TestFixtures
extend ActiveSupport::Concern
def before_setup: () -> untyped
def after_teardown: () -> untyped
module ClassMethods
# Sets the model class for a fixture when the class name cannot be inferred from the fixture name.
#
# Examples:
#
# set_fixture_class some_fixture: SomeModel,
# 'namespaced/fixture' => Another::Model
#
# The keys must be the fixture names, that coincide with the short paths to the fixture files.
def set_fixture_class: (?::Hash[untyped, untyped] class_names) -> untyped
def fixtures: (*untyped fixture_set_names) -> untyped
def setup_fixture_accessors: (?untyped? fixture_set_names) -> untyped
def uses_transaction: (*untyped methods) -> untyped
def uses_transaction?: (untyped method) -> untyped
end
def run_in_transaction?: () -> untyped
def setup_fixtures: (?untyped config) -> untyped
def teardown_fixtures: () -> untyped
def enlist_fixture_connections: () -> untyped
# Shares the writing connection pool with connections on
# other handlers.
#
# In an application with a primary and replica the test fixtures
# need to share a connection pool so that the reading connection
# can see data in the open transaction on the writing connection.
def setup_shared_connection_pool: () -> (nil | untyped)
def load_fixtures: (untyped config) -> untyped
def instantiate_fixtures: () -> untyped
def load_instances?: () -> untyped
end
end
module ActiveRecord
# = Active Record \Timestamp
#
# Active Record automatically timestamps create and update operations if the
# table has fields named created_at/created_on or
# updated_at/updated_on.
#
# Timestamping can be turned off by setting:
#
# config.active_record.record_timestamps = false
#
# Timestamps are in UTC by default but you can use the local timezone by setting:
#
# config.active_record.default_timezone = :local
#
# == Time Zone aware attributes
#
# Active Record keeps all the datetime and time columns
# timezone aware. By default, these values are stored in the database as UTC
# and converted back to the current Time.zone when pulled from the database.
#
# This feature can be turned off completely by setting:
#
# config.active_record.time_zone_aware_attributes = false
#
# You can also specify that only datetime columns should be time-zone
# aware (while time should not) by setting:
#
# ActiveRecord::Base.time_zone_aware_types = [:datetime]
#
# You can also add database specific timezone aware types. For example, for PostgreSQL:
#
# ActiveRecord::Base.time_zone_aware_types += [:tsrange, :tstzrange]
#
# Finally, you can indicate specific attributes of a model for which time zone
# conversion should not applied, for instance by setting:
#
# class Topic < ActiveRecord::Base
# self.skip_time_zone_conversion_for_attributes = [:written_on]
# end
module Timestamp
extend ActiveSupport::Concern
def initialize_dup: (untyped other) -> untyped
module ClassMethods
# :nodoc:
def touch_attributes_with_time: (*untyped names, ?time: untyped? time) -> untyped
def timestamp_attributes_for_create_in_model: () -> untyped
def timestamp_attributes_for_update_in_model: () -> untyped
def all_timestamp_attributes_in_model: () -> untyped
def current_time_from_proper_timezone: () -> untyped
def timestamp_attributes_for_create: () -> ::Array["created_at" | "created_on"]
def timestamp_attributes_for_update: () -> ::Array["updated_at" | "updated_on"]
def reload_schema_from_cache: () -> untyped
end
def _create_record: () -> untyped
def _update_record: () -> untyped
def create_or_update: (?touch: bool touch) -> untyped
def should_record_timestamps?: () -> untyped
def timestamp_attributes_for_create_in_model: () -> untyped
def timestamp_attributes_for_update_in_model: () -> untyped
def all_timestamp_attributes_in_model: () -> untyped
def current_time_from_proper_timezone: () -> untyped
def max_updated_column_timestamp: () -> untyped
# Clear attributes and changed_attributes
def clear_timestamp_attributes: () -> untyped
end
end
module ActiveRecord
module TouchLater
# = Active Record Touch Later
# :nodoc:
extend ActiveSupport::Concern
def touch_later: (*untyped names) -> untyped
def touch: (*untyped names, ?time: untyped? time) -> untyped
def surreptitiously_touch: (untyped attrs) -> untyped
def touch_deferred_attributes: () -> untyped
def has_defer_touch_attrs?: () -> untyped
def belongs_to_touch_method: () -> :touch_later
end
end
module ActiveRecord
# See ActiveRecord::Transactions::ClassMethods for documentation.
module Transactions
extend ActiveSupport::Concern
# nodoc:
ACTIONS: ::Array[untyped]
# = Active Record Transactions
#
# \Transactions are protective blocks where SQL statements are only permanent
# if they can all succeed as one atomic action. The classic example is a
# transfer between two accounts where you can only have a deposit if the
# withdrawal succeeded and vice versa. \Transactions enforce the integrity of
# the database and guard the data against program errors or database
# break-downs. So basically you should use transaction blocks whenever you
# have a number of statements that must be executed together or not at all.
#
# For example:
#
# ActiveRecord::Base.transaction do
# david.withdrawal(100)
# mary.deposit(100)
# end
#
# This example will only take money from David and give it to Mary if neither
# +withdrawal+ nor +deposit+ raise an exception. Exceptions will force a
# ROLLBACK that returns the database to the state before the transaction
# began. Be aware, though, that the objects will _not_ have their instance
# data returned to their pre-transactional state.
#
# == Different Active Record classes in a single transaction
#
# Though the #transaction class method is called on some Active Record class,
# the objects within the transaction block need not all be instances of
# that class. This is because transactions are per-database connection, not
# per-model.
#
# In this example a +balance+ record is transactionally saved even
# though #transaction is called on the +Account+ class:
#
# Account.transaction do
# balance.save!
# account.save!
# end
#
# The #transaction method is also available as a model instance method.
# For example, you can also do this:
#
# balance.transaction do
# balance.save!
# account.save!
# end
#
# == Transactions are not distributed across database connections
#
# A transaction acts on a single database connection. If you have
# multiple class-specific databases, the transaction will not protect
# interaction among them. One workaround is to begin a transaction
# on each class whose models you alter:
#
# Student.transaction do
# Course.transaction do
# course.enroll(student)
# student.units += course.units
# end
# end
#
# This is a poor solution, but fully distributed transactions are beyond
# the scope of Active Record.
#
# == +save+ and +destroy+ are automatically wrapped in a transaction
#
# Both {#save}[rdoc-ref:Persistence#save] and
# {#destroy}[rdoc-ref:Persistence#destroy] come wrapped in a transaction that ensures
# that whatever you do in validations or callbacks will happen under its
# protected cover. So you can use validations to check for values that
# the transaction depends on or you can raise exceptions in the callbacks
# to rollback, including after_* callbacks.
#
# As a consequence changes to the database are not seen outside your connection
# until the operation is complete. For example, if you try to update the index
# of a search engine in +after_save+ the indexer won't see the updated record.
# The #after_commit callback is the only one that is triggered once the update
# is committed. See below.
#
# == Exception handling and rolling back
#
# Also have in mind that exceptions thrown within a transaction block will
# be propagated (after triggering the ROLLBACK), so you should be ready to
# catch those in your application code.
#
# One exception is the ActiveRecord::Rollback exception, which will trigger
# a ROLLBACK when raised, but not be re-raised by the transaction block.
#
# *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions
# inside a transaction block. ActiveRecord::StatementInvalid exceptions indicate that an
# error occurred at the database level, for example when a unique constraint
# is violated. On some database systems, such as PostgreSQL, database errors
# inside a transaction cause the entire transaction to become unusable
# until it's restarted from the beginning. Here is an example which
# demonstrates the problem:
#
# # Suppose that we have a Number model with a unique column called 'i'.
# Number.transaction do
# Number.create(i: 0)
# begin
# # This will raise a unique constraint error...
# Number.create(i: 0)
# rescue ActiveRecord::StatementInvalid
# # ...which we ignore.
# end
#
# # On PostgreSQL, the transaction is now unusable. The following
# # statement will cause a PostgreSQL error, even though the unique
# # constraint is no longer violated:
# Number.create(i: 1)
# # => "PG::Error: ERROR: current transaction is aborted, commands
# # ignored until end of transaction block"
# end
#
# One should restart the entire transaction if an
# ActiveRecord::StatementInvalid occurred.
#
# == Nested transactions
#
# #transaction calls can be nested. By default, this makes all database
# statements in the nested transaction block become part of the parent
# transaction. For example, the following behavior may be surprising:
#
# User.transaction do
# User.create(username: 'Kotori')
# User.transaction do
# User.create(username: 'Nemu')
# raise ActiveRecord::Rollback
# end
# end
#
# creates both "Kotori" and "Nemu". Reason is the ActiveRecord::Rollback
# exception in the nested block does not issue a ROLLBACK. Since these exceptions
# are captured in transaction blocks, the parent block does not see it and the
# real transaction is committed.
#
# In order to get a ROLLBACK for the nested transaction you may ask for a real
# sub-transaction by passing requires_new: true. If anything goes wrong,
# the database rolls back to the beginning of the sub-transaction without rolling
# back the parent transaction. If we add it to the previous example:
#
# User.transaction do
# User.create(username: 'Kotori')
# User.transaction(requires_new: true) do
# User.create(username: 'Nemu')
# raise ActiveRecord::Rollback
# end
# end
#
# only "Kotori" is created. This works on MySQL and PostgreSQL. SQLite3 version >= '3.6.8' also supports it.
#
# Most databases don't support true nested transactions. At the time of
# writing, the only database that we're aware of that supports true nested
# transactions, is MS-SQL. Because of this, Active Record emulates nested
# transactions by using savepoints on MySQL and PostgreSQL. See
# https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
# for more information about savepoints.
#
# === \Callbacks
#
# There are two types of callbacks associated with committing and rolling back transactions:
# #after_commit and #after_rollback.
#
# #after_commit callbacks are called on every record saved or destroyed within a
# transaction immediately after the transaction is committed. #after_rollback callbacks
# are called on every record saved or destroyed within a transaction immediately after the
# transaction or savepoint is rolled back.
#
# These callbacks are useful for interacting with other systems since you will be guaranteed
# that the callback is only executed when the database is in a permanent state. For example,
# #after_commit is a good spot to put in a hook to clearing a cache since clearing it from
# within a transaction could trigger the cache to be regenerated before the database is updated.
#
# === Caveats
#
# If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested
# transactions blocks that are emulated with savepoints. That is, do not execute statements
# like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
# releases all savepoints upon executing a DDL operation. When +transaction+
# is finished and tries to release the savepoint it created earlier, a
# database error will occur because the savepoint has already been
# automatically released. The following example demonstrates the problem:
#
# Model.connection.transaction do # BEGIN
# Model.connection.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
# Model.connection.create_table(...) # active_record_1 now automatically released
# end # RELEASE SAVEPOINT active_record_1
# # ^^^^ BOOM! database error!
# end
#
# Note that "TRUNCATE" is also a MySQL DDL statement!
module ClassMethods
# See the ConnectionAdapters::DatabaseStatements#transaction API docs.
def transaction: (**untyped options) { () -> untyped } -> untyped
def before_commit: (*untyped args) { () -> untyped } -> untyped
# This callback is called after a record has been created, updated, or destroyed.
#
# You can specify that the callback should only be fired by a certain action with
# the +:on+ option:
#
# after_commit :do_foo, on: :create
# after_commit :do_bar, on: :update
# after_commit :do_baz, on: :destroy
#
# after_commit :do_foo_bar, on: [:create, :update]
# after_commit :do_bar_baz, on: [:update, :destroy]
#
def after_commit: (*untyped args) { () -> untyped } -> untyped
# Shortcut for after_commit :hook, on: [ :create, :update ].
def after_save_commit: (*untyped args) { () -> untyped } -> untyped
# Shortcut for after_commit :hook, on: :create.
def after_create_commit: (*untyped args) { () -> untyped } -> untyped
# Shortcut for after_commit :hook, on: :update.
def after_update_commit: (*untyped args) { () -> untyped } -> untyped
# Shortcut for after_commit :hook, on: :destroy.
def after_destroy_commit: (*untyped args) { () -> untyped } -> untyped
# This callback is called after a create, update, or destroy are rolled back.
#
# Please check the documentation of #after_commit for options.
def after_rollback: (*untyped args) { () -> untyped } -> untyped
def before_commit_without_transaction_enrollment: (*untyped args) { () -> untyped } -> untyped
def after_commit_without_transaction_enrollment: (*untyped args) { () -> untyped } -> untyped
def after_rollback_without_transaction_enrollment: (*untyped args) { () -> untyped } -> untyped
def set_options_for_callbacks!: (untyped args, ?::Hash[untyped, untyped] enforced_options) -> untyped
def assert_valid_transaction_action: (untyped actions) -> untyped
end
# See ActiveRecord::Transactions::ClassMethods for detailed documentation.
def transaction: (?::Hash[untyped, untyped] options) { () -> untyped } -> untyped
def destroy: () -> untyped
def save: () -> untyped
def save!: () -> untyped
def touch: () -> untyped
def before_committed!: () -> untyped
def committed!: (?should_run_callbacks: bool should_run_callbacks) -> untyped
def rolledback!: (?should_run_callbacks: bool should_run_callbacks, ?force_restore_state: bool force_restore_state) -> untyped
# Executes +method+ within a transaction and captures its return value as a
# status flag. If the status is true the transaction is committed, otherwise
# a ROLLBACK is issued. In any case the status flag is returned.
#
# This method is available within the context of an ActiveRecord::Base
# instance.
def with_transaction_returning_status: () { () -> untyped } -> untyped
def trigger_transactional_callbacks?: () -> untyped
attr_reader _committed_already_called: untyped
attr_reader _trigger_update_callback: untyped
attr_reader _trigger_destroy_callback: untyped
# Save the new record state and id of a record so it can be restored later if a transaction fails.
def remember_transaction_record_state: () -> untyped
# Clear the new record state and id of a record.
def clear_transaction_record_state: () -> (nil | untyped)
# Force to clear the transaction record state.
def force_clear_transaction_record_state: () -> untyped
# Restore the new record state and id of a record that was previously saved by a call to save_record_state.
def restore_transaction_record_state: (?bool force_restore_state) -> untyped
# Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
def transaction_include_any_action?: (untyped actions) -> untyped
# Add the record to the current transaction so that the #after_rollback and #after_commit
# callbacks can be called.
def add_to_transaction: () -> untyped
def has_transactional_callbacks?: () -> untyped
# Updates the attributes on this particular Active Record object so that
# if it's associated with a transaction, then the state of the Active Record
# object will be updated to reflect the current state of the transaction.
#
# The @transaction_state variable stores the states of the associated
# transaction. This relies on the fact that a transaction can only be in
# one rollback or commit (otherwise a list of states would be required).
# Each Active Record object inside of a transaction carries that transaction's
# TransactionState.
#
# This method checks to see if the ActiveRecord object's state reflects
# the TransactionState, and rolls back or commits the Active Record object
# as appropriate.
def sync_with_transaction_state: () -> untyped
end
end
module ActiveRecord
module Translation
include ActiveModel::Translation
def lookup_ancestors: () -> untyped
def i18n_scope: () -> :activerecord
end
end
module ActiveRecord
# :stopdoc:
module Type
class AdapterSpecificRegistry < ActiveModel::Type::Registry
def add_modifier: (untyped options, untyped klass, **untyped args) -> untyped
def registration_klass: () -> untyped
def find_registration: (untyped symbol, *untyped args, **untyped kwargs) -> untyped
end
class Registration
def initialize: (untyped name, untyped block, ?override: untyped? override, ?adapter: untyped? adapter) -> untyped
def call: (untyped _registry, *untyped args, ?adapter: untyped? adapter, **untyped kwargs) -> untyped
def matches?: (untyped type_name, *untyped args, **untyped kwargs) -> untyped
def <=>: (untyped other) -> untyped
attr_reader name: untyped
attr_reader block: untyped
attr_reader adapter: untyped
attr_reader override: untyped
def priority: () -> untyped
def priority_except_adapter: () -> untyped
def matches_adapter?: (?adapter: untyped? adapter) -> untyped
def conflicts_with?: (untyped other) -> untyped
def same_priority_except_adapter?: (untyped other) -> untyped
def has_adapter_conflict?: (untyped other) -> untyped
end
class DecorationRegistration < Registration
def initialize: (untyped options, untyped klass, ?adapter: untyped? adapter) -> untyped
def call: (untyped registry, *untyped args, **untyped kwargs) -> untyped
def matches?: (*untyped args, **untyped kwargs) -> untyped
def priority: () -> untyped
attr_reader options: untyped
attr_reader klass: untyped
def matches_options?: (**untyped kwargs) -> untyped
end
end
class TypeConflictError < StandardError
end
end
module ActiveRecord
module TypeCaster
class Connection
# :nodoc:
def initialize: (untyped klass, untyped table_name) -> untyped
def type_cast_for_database: (untyped attr_name, untyped value) -> untyped
def type_for_attribute: (untyped attr_name) -> untyped
attr_reader table_name: untyped
end
end
end
module ActiveRecord
module TypeCaster
class Map
# :nodoc:
def initialize: (untyped types) -> untyped
def type_cast_for_database: (untyped attr_name, untyped value) -> untyped
attr_reader types: untyped
end
end
end
module ActiveRecord
module TypeCaster
end
end
module ActiveRecord
module Type
class Date < ActiveModel::Type::Date
include Internal::Timezone
end
end
end
module ActiveRecord
module Type
class DateTime < ActiveModel::Type::DateTime
include Internal::Timezone
end
end
end
module ActiveRecord
module Type
class DecimalWithoutScale < ActiveModel::Type::BigInteger
# :nodoc:
def `type`: () -> :decimal
def type_cast_for_schema: (untyped value) -> untyped
end
end
end
module ActiveRecord
module Type
class HashLookupTypeMap < TypeMap
# :nodoc:
def alias_type: (untyped `type`, untyped alias_type) -> untyped
def key?: (untyped key) -> untyped
def keys: () -> untyped
def perform_fetch: (untyped `type`, *untyped args) { () -> untyped } -> untyped
end
end
end
module ActiveRecord
module Type
module Internal
module Timezone
def is_utc?: () -> untyped
def default_timezone: () -> untyped
end
end
end
end
module ActiveRecord
module Type
class Json < ActiveModel::Type::Value
include ActiveModel::Type::Helpers::Mutable
def `type`: () -> :json
def deserialize: (untyped value) -> untyped
def serialize: (untyped value) -> untyped
def changed_in_place?: (untyped raw_old_value, untyped new_value) -> untyped
def accessor: () -> untyped
end
end
end
module ActiveRecord
module Type
attr_accessor registry: untyped
# Add a new type to the registry, allowing it to be referenced as a
# symbol by {ActiveRecord::Base.attribute}[rdoc-ref:Attributes::ClassMethods#attribute].
# If your type is only meant to be used with a specific database adapter, you can
# do so by passing adapter: :postgresql. If your type has the same
# name as a native type for the current adapter, an exception will be
# raised unless you specify an +:override+ option. override: true will
# cause your type to be used instead of the native type. override:
# false will cause the native type to be used over yours if one exists.
def self.register: (untyped type_name, ?untyped? klass, **untyped options) { () -> untyped } -> untyped
def self.lookup: (*untyped args, ?adapter: untyped adapter, **untyped kwargs) -> untyped
def self.default_value: () -> untyped
def self.current_adapter_name: () -> untyped
BigInteger: untyped
Binary: untyped
Boolean: untyped
Decimal: untyped
Float: untyped
Integer: untyped
String: untyped
Value: untyped
end
end
module ActiveRecord
module Type
# Note: It inherits unnamed class, but omitted
class Serialized
include ActiveModel::Type::Helpers::Mutable
attr_reader subtype: untyped
attr_reader coder: untyped
def initialize: (untyped subtype, untyped coder) -> untyped
def deserialize: (untyped value) -> untyped
def serialize: (untyped value) -> (nil | untyped)
def inspect: () -> untyped
def changed_in_place?: (untyped raw_old_value, untyped value) -> (::FalseClass | untyped)
def accessor: () -> untyped
def assert_valid_value: (untyped value) -> untyped
def force_equality?: (untyped value) -> untyped
def default_value?: (untyped value) -> untyped
def encoded: (untyped value) -> untyped
end
end
end
module ActiveRecord
module Type
class Text < ActiveModel::Type::String
# :nodoc:
def `type`: () -> :text
end
end
end
module ActiveRecord
module Type
class Time < ActiveModel::Type::Time
include Internal::Timezone
# Note: It inherits unnamed class, but omitted
class Value
end
def serialize: (untyped value) -> untyped
end
end
end
module ActiveRecord
module Type
class TypeMap
# :nodoc:
def initialize: () -> untyped
def lookup: (untyped lookup_key, *untyped args) -> untyped
def fetch: (untyped lookup_key, *untyped args) { () -> untyped } -> untyped
def register_type: (untyped key, ?untyped? value) { () -> untyped } -> untyped
def alias_type: (untyped key, untyped target_key) -> untyped
def clear: () -> untyped
def perform_fetch: (untyped lookup_key, *untyped args) { (untyped, untyped) -> untyped } -> untyped
end
end
end
module ActiveRecord
module Type
class UnsignedInteger < ActiveModel::Type::Integer
def max_value: () -> untyped
def min_value: () -> 0
end
end
end
module ActiveRecord
module Validations
extend ::ActiveModel::Validations::ClassMethods
class AbsenceValidator < ActiveModel::Validations::AbsenceValidator
# :nodoc:
def validate_each: (untyped record, untyped attribute, untyped association_or_value) -> untyped
end
module ClassMethods
# Validates that the specified attributes are not present (as defined by
# Object#present?). If the attribute is an association, the associated object
# is considered absent if it was marked for destruction.
#
# See ActiveModel::Validations::HelperMethods.validates_absence_of for more information.
def validates_absence_of: (*untyped attr_names) -> untyped
end
end
end
module ActiveRecord
module Validations
class AssociatedValidator < ActiveModel::EachValidator
# nodoc:
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
def valid_object?: (untyped record) -> untyped
end
module ClassMethods
# Validates whether the associated object or objects are all valid.
# Works with any kind of association.
#
# class Book < ActiveRecord::Base
# has_many :pages
# belongs_to :library
#
# validates_associated :pages, :library
# end
#
# WARNING: This validation must not be used on both ends of an association.
# Doing so will lead to a circular dependency and cause infinite recursion.
#
# NOTE: This validation will not fail if the association hasn't been
# assigned. If you want to ensure that the association is both present and
# guaranteed to be valid, you also need to use
# {validates_presence_of}[rdoc-ref:Validations::ClassMethods#validates_presence_of].
#
# Configuration options:
#
# * :message - A custom error message (default is: "is invalid").
# * :on - Specifies the contexts where this validation is active.
# Runs in all validation contexts by default +nil+. You can pass a symbol
# or an array of symbols. (e.g. on: :create or
# on: :custom_validation_context or
# on: [:create, :custom_validation_context])
# * :if - Specifies a method, proc or string to call to determine
# if the validation should occur (e.g. if: :allow_validation,
# or if: Proc.new { |user| user.signup_step > 2 }). The method,
# proc or string should return or evaluate to a +true+ or +false+ value.
# * :unless - Specifies a method, proc or string to call to
# determine if the validation should not occur (e.g. unless: :skip_validation,
# or unless: Proc.new { |user| user.signup_step <= 2 }). The
# method, proc or string should return or evaluate to a +true+ or +false+
# value.
def validates_associated: (*untyped attr_names) -> untyped
end
end
end
module ActiveRecord
module Validations
class LengthValidator < ActiveModel::Validations::LengthValidator
# :nodoc:
def validate_each: (untyped record, untyped attribute, untyped association_or_value) -> untyped
end
module ClassMethods
# Validates that the specified attributes match the length restrictions supplied.
# If the attribute is an association, records that are marked for destruction are not counted.
#
# See ActiveModel::Validations::HelperMethods.validates_length_of for more information.
def validates_length_of: (*untyped attr_names) -> untyped
end
end
end
module ActiveRecord
module Validations
class PresenceValidator < ActiveModel::Validations::PresenceValidator
# :nodoc:
def validate_each: (untyped record, untyped attribute, untyped association_or_value) -> untyped
end
module ClassMethods
# Validates that the specified attributes are not blank (as defined by
# Object#blank?), and, if the attribute is an association, that the
# associated object is not marked for destruction. Happens by default
# on save.
#
# class Person < ActiveRecord::Base
# has_one :face
# validates_presence_of :face
# end
#
# The face attribute must be in the object and it cannot be blank or marked
# for destruction.
#
# If you want to validate the presence of a boolean field (where the real values
# are true and false), you will want to use
# validates_inclusion_of :field_name, in: [true, false].
#
# This is due to the way Object#blank? handles boolean values:
# false.blank? # => true.
#
# This validator defers to the Active Model validation for presence, adding the
# check to see that an associated object is not marked for destruction. This
# prevents the parent object from validating successfully and saving, which then
# deletes the associated object, thus putting the parent object into an invalid
# state.
#
# NOTE: This validation will not fail while using it with an association
# if the latter was assigned but not valid. If you want to ensure that
# it is both present and valid, you also need to use
# {validates_associated}[rdoc-ref:Validations::ClassMethods#validates_associated].
#
# Configuration options:
# * :message - A custom error message (default is: "can't be blank").
# * :on - Specifies the contexts where this validation is active.
# Runs in all validation contexts by default +nil+. You can pass a symbol
# or an array of symbols. (e.g. on: :create or
# on: :custom_validation_context or
# on: [:create, :custom_validation_context])
# * :if - Specifies a method, proc or string to call to determine if
# the validation should occur (e.g. if: :allow_validation, or
# if: Proc.new { |user| user.signup_step > 2 }). The method, proc
# or string should return or evaluate to a +true+ or +false+ value.
# * :unless - Specifies a method, proc or string to call to determine
# if the validation should not occur (e.g. unless: :skip_validation,
# or unless: Proc.new { |user| user.signup_step <= 2 }). The method,
# proc or string should return or evaluate to a +true+ or +false+ value.
# * :strict - Specifies whether validation should be strict.
# See ActiveModel::Validations#validates! for more information.
def validates_presence_of: (*untyped attr_names) -> untyped
end
end
end
module ActiveRecord
# = Active Record \RecordInvalid
#
# Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
# {ActiveRecord::Base#create!}[rdoc-ref:Persistence::ClassMethods#create!] when the record is invalid.
# Use the #record method to retrieve the record which did not validate.
#
# begin
# complex_operation_that_internally_calls_save!
# rescue ActiveRecord::RecordInvalid => invalid
# puts invalid.record.errors
# end
class RecordInvalid < ActiveRecordError
attr_reader record: untyped
def initialize: (?untyped? record) -> untyped
end
# = Active Record \Validations
#
# Active Record includes the majority of its validations from ActiveModel::Validations
# all of which accept the :on argument to define the context where the
# validations are active. Active Record will always supply either the context of
# :create or :update dependent on whether the model is a
# {new_record?}[rdoc-ref:Persistence#new_record?].
module Validations
extend ActiveSupport::Concern
include ActiveModel::Validations
# The validation process on save can be skipped by passing validate: false.
# The validation context can be changed by passing context: context.
# The regular {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] method is replaced
# with this when the validations module is mixed in, which it is by default.
def save: (**untyped options) -> untyped
# Attempts to save the record just like {ActiveRecord::Base#save}[rdoc-ref:Base#save] but
# will raise an ActiveRecord::RecordInvalid exception instead of returning +false+ if the record is not valid.
def save!: (**untyped options) -> untyped
# Runs all the validations within the specified context. Returns +true+ if
# no errors are found, +false+ otherwise.
#
# Aliased as #validate.
#
# If the argument is +false+ (default is +nil+), the context is set to :create if
# {new_record?}[rdoc-ref:Persistence#new_record?] is +true+, and to :update if it is not.
#
# \Validations with no :on option will run no matter the context. \Validations with
# some :on option will only run in the specified context.
def valid?: (?untyped? context) -> untyped
def default_validation_context: () -> untyped
def raise_validation_error: () -> untyped
def perform_validations: (?::Hash[untyped, untyped] options) -> untyped
end
end
module ActiveRecord
module Validations
class UniquenessValidator < ActiveModel::EachValidator
# :nodoc:
def initialize: (untyped options) -> untyped
def validate_each: (untyped record, untyped attribute, untyped value) -> untyped
# The check for an existing value should be run from a class that
# isn't abstract. This means working down from the current class
# (self), to the first non-abstract class. Since classes don't know
# their subclasses, we have to build the hierarchy between self and
# the record's class.
def find_finder_class_for: (untyped record) -> untyped
def build_relation: (untyped klass, untyped attribute, untyped value) -> untyped
def scope_relation: (untyped record, untyped relation) -> untyped
def map_enum_attribute: (untyped klass, untyped attribute, untyped value) -> untyped
end
module ClassMethods
# Validates whether the value of the specified attributes are unique
# across the system. Useful for making sure that only one user
# can be named "davidhh".
#
# class Person < ActiveRecord::Base
# validates_uniqueness_of :user_name
# end
#
# It can also validate whether the value of the specified attributes are
# unique based on a :scope parameter:
#
# class Person < ActiveRecord::Base
# validates_uniqueness_of :user_name, scope: :account_id
# end
#
# Or even multiple scope parameters. For example, making sure that a
# teacher can only be on the schedule once per semester for a particular
# class.
#
# class TeacherSchedule < ActiveRecord::Base
# validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
# end
#
# It is also possible to limit the uniqueness constraint to a set of
# records matching certain conditions. In this example archived articles
# are not being taken into consideration when validating uniqueness
# of the title attribute:
#
# class Article < ActiveRecord::Base
# validates_uniqueness_of :title, conditions: -> { where.not(status: 'archived') }
# end
#
# When the record is created, a check is performed to make sure that no
# record exists in the database with the given value for the specified
# attribute (that maps to a column). When the record is updated,
# the same check is made but disregarding the record itself.
#
# Configuration options:
#
# * :message - Specifies a custom error message (default is:
# "has already been taken").
# * :scope - One or more columns by which to limit the scope of
# the uniqueness constraint.
# * :conditions - Specify the conditions to be included as a
# WHERE SQL fragment to limit the uniqueness constraint lookup
# (e.g. conditions: -> { where(status: 'active') }).
# * :case_sensitive - Looks for an exact match. Ignored by
# non-text columns (+true+ by default).
# * :allow_nil - If set to +true+, skips this validation if the
# attribute is +nil+ (default is +false+).
# * :allow_blank - If set to +true+, skips this validation if the
# attribute is blank (default is +false+).
# * :if - Specifies a method, proc or string to call to determine
# if the validation should occur (e.g. if: :allow_validation,
# or if: Proc.new { |user| user.signup_step > 2 }). The method,
# proc or string should return or evaluate to a +true+ or +false+ value.
# * :unless - Specifies a method, proc or string to call to
# determine if the validation should not occur (e.g. unless: :skip_validation,
# or unless: Proc.new { |user| user.signup_step <= 2 }). The
# method, proc or string should return or evaluate to a +true+ or +false+
# value.
#
# === Concurrency and integrity
#
# Using this validation method in conjunction with
# {ActiveRecord::Base#save}[rdoc-ref:Persistence#save]
# does not guarantee the absence of duplicate record insertions, because
# uniqueness checks on the application level are inherently prone to race
# conditions. For example, suppose that two users try to post a Comment at
# the same time, and a Comment's title must be unique. At the database-level,
# the actions performed by these users could be interleaved in the following manner:
#
# User 1 | User 2
# ------------------------------------+--------------------------------------
# # User 1 checks whether there's |
# # already a comment with the title |
# # 'My Post'. This is not the case. |
# SELECT * FROM comments |
# WHERE title = 'My Post' |
# |
# | # User 2 does the same thing and also
# | # infers that their title is unique.
# | SELECT * FROM comments
# | WHERE title = 'My Post'
# |
# # User 1 inserts their comment. |
# INSERT INTO comments |
# (title, content) VALUES |
# ('My Post', 'hi!') |
# |
# | # User 2 does the same thing.
# | INSERT INTO comments
# | (title, content) VALUES
# | ('My Post', 'hello!')
# |
# | # ^^^^^^
# | # Boom! We now have a duplicate
# | # title!
#
# The best way to work around this problem is to add a unique index to the database table using
# {connection.add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index].
# In the rare case that a race condition occurs, the database will guarantee
# the field's uniqueness.
#
# When the database catches such a duplicate insertion,
# {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] will raise an ActiveRecord::StatementInvalid
# exception. You can either choose to let this error propagate (which
# will result in the default Rails exception page being shown), or you
# can catch it and restart the transaction (e.g. by telling the user
# that the title already exists, and asking them to re-enter the title).
# This technique is also known as
# {optimistic concurrency control}[https://en.wikipedia.org/wiki/Optimistic_concurrency_control].
#
# The bundled ActiveRecord::ConnectionAdapters distinguish unique index
# constraint errors from other types of database errors by throwing an
# ActiveRecord::RecordNotUnique exception. For other adapters you will
# have to parse the (database-specific) exception message to detect such
# a case.
#
# The following bundled adapters throw the ActiveRecord::RecordNotUnique exception:
#
# * ActiveRecord::ConnectionAdapters::Mysql2Adapter.
# * ActiveRecord::ConnectionAdapters::SQLite3Adapter.
# * ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.
def validates_uniqueness_of: (*untyped attr_names) -> untyped
end
end
end
module ActiveRecord
# Returns the version of the currently loaded ActiveRecord as a Gem::Version
def self.version: () -> untyped
end
module Arel
# :nodoc: all
module AliasPredication
def as: (untyped other) -> untyped
end
end
module Arel
# :nodoc: all
module Attributes
# Note: It inherits unnamed class, but omitted
class Attribute
include Arel::Expressions
include Arel::Predications
include Arel::AliasPredication
include Arel::OrderPredications
include Arel::Math
# #
# Create a node for lowering this attribute
def lower: () -> untyped
def type_cast_for_database: (untyped value) -> untyped
def able_to_type_cast?: () -> untyped
end
class String < Attribute
end
class Time < Attribute
end
class Boolean < Attribute
end
class Decimal < Attribute
end
class Float < Attribute
end
class Integer < Attribute
end
class Undefined < Attribute
end
end
Attribute: untyped
end
module Arel
# :nodoc: all
module Attributes
# #
# Factory method to wrap a raw database +column+ to an Arel Attribute.
def self.for: (untyped column) -> untyped
end
end
module Arel
# :nodoc: all
module Collectors
class Bind
def initialize: () -> untyped
def <<: (untyped str) -> untyped
def add_bind: (untyped bind) -> untyped
def value: () -> untyped
end
end
end
module Arel
# :nodoc: all
module Collectors
class Composite
def initialize: (untyped left, untyped right) -> untyped
def <<: (untyped str) -> untyped
def add_bind: (untyped bind) { () -> untyped } -> untyped
def value: () -> ::Array[untyped]
attr_reader left: untyped
attr_reader right: untyped
end
end
end
module Arel
# :nodoc: all
module Collectors
class PlainString
def initialize: () -> untyped
def value: () -> untyped
def <<: (untyped str) -> untyped
end
end
end
module Arel
# :nodoc: all
module Collectors
class SQLString < PlainString
def initialize: () -> untyped
def add_bind: (untyped bind) { (untyped) -> untyped } -> untyped
end
end
end
module Arel
# :nodoc: all
module Collectors
class SubstituteBinds
def initialize: (untyped quoter, untyped delegate_collector) -> untyped
def <<: (untyped str) -> untyped
def add_bind: (untyped bind) -> untyped
def value: () -> untyped
attr_reader quoter: untyped
attr_reader delegate: untyped
end
end
end
module Arel
# :nodoc: all
# #
# FIXME hopefully we can remove this
module Crud
def compile_update: (untyped values, untyped pk) -> untyped
def compile_insert: (untyped values) -> untyped
def create_insert: () -> InsertManager
def compile_delete: () -> untyped
end
end
module Arel
# :nodoc: all
class DeleteManager < Arel::TreeManager
include TreeManager::StatementMethods
def initialize: () -> untyped
def from: (untyped relation) -> untyped
end
end
module Arel
# :nodoc: all
class ArelError < StandardError
end
class EmptyJoinError < ArelError
end
end
module Arel
# :nodoc: all
module Expressions
def count: (?bool distinct) -> Nodes::Count
def sum: () -> Nodes::Sum
def maximum: () -> Nodes::Max
def minimum: () -> Nodes::Min
def average: () -> Nodes::Avg
def extract: (untyped field) -> Nodes::Extract
end
end
module Arel
# :nodoc: all
# #
# Methods for creating various nodes
module FactoryMethods
def create_true: () -> Arel::Nodes::True
def create_false: () -> Arel::Nodes::False
def create_table_alias: (untyped relation, untyped name) -> Nodes::TableAlias
def create_join: (untyped to, ?untyped? constraint, ?untyped klass) -> untyped
def create_string_join: (untyped to) -> untyped
def create_and: (untyped clauses) -> Nodes::And
def create_on: (untyped expr) -> Nodes::On
def grouping: (untyped expr) -> Nodes::Grouping
# #
# Create a LOWER() function
def lower: (untyped column) -> Nodes::NamedFunction
def coalesce: (*untyped exprs) -> Nodes::NamedFunction
end
end
module Arel
# :nodoc: all
class InsertManager < Arel::TreeManager
def initialize: () -> untyped
def into: (untyped table) -> untyped
def columns: () -> untyped
def values=: (untyped val) -> untyped
def select: (untyped select) -> untyped
def insert: (untyped fields) -> (nil | untyped)
def create_values: (untyped values) -> Nodes::ValuesList
def create_values_list: (untyped rows) -> Nodes::ValuesList
end
end
module Arel
# :nodoc: all
module Math
def *: (untyped other) -> Arel::Nodes::Multiplication
def +: (untyped other) -> Arel::Nodes::Grouping
def -: (untyped other) -> Arel::Nodes::Grouping
def /: (untyped other) -> Arel::Nodes::Division
def &: (untyped other) -> Arel::Nodes::Grouping
def |: (untyped other) -> Arel::Nodes::Grouping
def ^: (untyped other) -> Arel::Nodes::Grouping
def <<: (untyped other) -> Arel::Nodes::Grouping
def >>: (untyped other) -> Arel::Nodes::Grouping
def ~: () -> Arel::Nodes::BitwiseNot
end
end
module Arel
# :nodoc: all
module Nodes
class And < Arel::Nodes::NodeExpression
attr_reader children: untyped
def initialize: (untyped children) -> untyped
def left: () -> untyped
def right: () -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Ascending < Ordering
def reverse: () -> Descending
def direction: () -> :asc
def ascending?: () -> ::TrueClass
def descending?: () -> ::FalseClass
end
end
end
module Arel
# :nodoc: all
module Nodes
class Binary < Arel::Nodes::NodeExpression
attr_accessor left: untyped
attr_accessor right: untyped
def initialize: (untyped left, untyped right) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class BindParam < Node
attr_reader value: untyped
def initialize: (untyped value) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
def nil?: () -> untyped
def infinite?: () -> untyped
def unboundable?: () -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Case < Arel::Nodes::NodeExpression
attr_accessor case: untyped
attr_accessor conditions: untyped
attr_accessor default: untyped
def initialize: (?untyped? expression, ?untyped? default) -> untyped
def when: (untyped condition, ?untyped? expression) -> untyped
def then: (untyped expression) -> untyped
def else: (untyped expression) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
class When < Binary
end
class Else < Unary
end
end
end
module Arel
# :nodoc: all
module Nodes
class Casted < Arel::Nodes::NodeExpression
# :nodoc:
attr_reader val: untyped
# :nodoc:
attr_reader attribute: untyped
def initialize: (untyped val, untyped attribute) -> untyped
def nil?: () -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
class Quoted < Arel::Nodes::Unary
def nil?: () -> untyped
def infinite?: () -> untyped
end
def self.build_quoted: (untyped other, ?untyped? attribute) -> untyped
end
end
module Arel
# :nodoc: all
module Nodes
class Comment < Arel::Nodes::Node
attr_reader values: untyped
def initialize: (untyped values) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Count < Arel::Nodes::Function
def initialize: (untyped expr, ?bool distinct, ?untyped? aliaz) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class DeleteStatement < Arel::Nodes::Node
attr_accessor left: untyped
attr_accessor right: untyped
attr_accessor orders: untyped
attr_accessor limit: untyped
attr_accessor offset: untyped
attr_accessor key: untyped
def initialize: (?untyped? relation, ?untyped wheres) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Descending < Ordering
def reverse: () -> Ascending
def direction: () -> :desc
def ascending?: () -> ::FalseClass
def descending?: () -> ::TrueClass
end
end
end
module Arel
# :nodoc: all
module Nodes
class Equality < Arel::Nodes::Binary
def operator: () -> Symbol
end
end
end
module Arel
# :nodoc: all
module Nodes
class Extract < Arel::Nodes::Unary
attr_accessor field: untyped
def initialize: (untyped expr, untyped field) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class False < Arel::Nodes::NodeExpression
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class FullOuterJoin < Arel::Nodes::Join
end
end
end
module Arel
# :nodoc: all
module Nodes
class Function < Arel::Nodes::NodeExpression
include Arel::WindowPredications
attr_accessor expressions: untyped
attr_accessor alias: untyped
attr_accessor distinct: untyped
def initialize: (untyped expr, ?untyped? aliaz) -> untyped
def as: (untyped aliaz) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Grouping < Unary
end
end
end
module Arel
# :nodoc: all
module Nodes
class InfixOperation < Binary
include Arel::Expressions
include Arel::Predications
include Arel::OrderPredications
include Arel::AliasPredication
include Arel::Math
attr_reader operator: untyped
def initialize: (untyped operator, untyped left, untyped right) -> untyped
end
class Multiplication < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class Division < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class Addition < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class Subtraction < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class Concat < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class BitwiseAnd < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class BitwiseOr < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class BitwiseXor < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class BitwiseShiftLeft < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
class BitwiseShiftRight < InfixOperation
def initialize: (untyped left, untyped right) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class InnerJoin < Arel::Nodes::Join
end
end
end
module Arel
# :nodoc: all
module Nodes
class In < Equality
end
end
end
module Arel
# :nodoc: all
module Nodes
class InsertStatement < Arel::Nodes::Node
attr_accessor relation: untyped
attr_accessor columns: untyped
attr_accessor values: untyped
attr_accessor select: untyped
def initialize: () -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class JoinSource < Arel::Nodes::Binary
def initialize: (untyped single_source, ?untyped joinop) -> untyped
def empty?: () -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Matches < Binary
attr_reader escape: untyped
attr_accessor case_sensitive: untyped
def initialize: (untyped left, untyped right, ?untyped? escape, ?bool case_sensitive) -> untyped
end
class DoesNotMatch < Matches
end
end
end
module Arel
# :nodoc: all
module Nodes
class NamedFunction < Arel::Nodes::Function
attr_accessor name: untyped
def initialize: (untyped name, untyped expr, ?untyped? aliaz) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class NodeExpression < Arel::Nodes::Node
include Arel::Expressions
include Arel::Predications
include Arel::AliasPredication
include Arel::OrderPredications
include Arel::Math
end
end
end
module Arel
# :nodoc: all
module Nodes
# #
# Abstract base class for all AST nodes
class Node
include Arel::FactoryMethods
include Enumerable[untyped, untyped]
# #
# Factory method to create a Nodes::Not node that has the recipient of
# the caller as a child.
def not: () -> Nodes::Not
# #
# Factory method to create a Nodes::Grouping node that has an Nodes::Or
# node as a child.
def or: (untyped right) -> Nodes::Grouping
# #
# Factory method to create an Nodes::And node.
def and: (untyped right) -> Nodes::And
# FIXME: this method should go away. I don't like people calling
# to_sql on non-head nodes. This forces us to walk the AST until we
# can find a node that has a "relation" member.
#
# Maybe we should just use `Table.engine`? :'(
def to_sql: (?untyped engine) -> untyped
# Iterate through AST, nodes will be yielded depth-first
def each: () { () -> untyped } -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class OuterJoin < Arel::Nodes::Join
end
end
end
module Arel
# :nodoc: all
module Nodes
class Over < Binary
include Arel::AliasPredication
def initialize: (untyped left, ?untyped? right) -> untyped
def operator: () -> "OVER"
end
end
end
module Arel
# :nodoc: all
module Nodes
class Regexp < Binary
attr_accessor case_sensitive: untyped
def initialize: (untyped left, untyped right, ?bool case_sensitive) -> untyped
end
class NotRegexp < Regexp
end
end
end
module Arel
# :nodoc: all
module Nodes
class RightOuterJoin < Arel::Nodes::Join
end
end
end
module Arel
# :nodoc: all
module Nodes
class SelectCore < Arel::Nodes::Node
attr_accessor projections: untyped
attr_accessor wheres: untyped
attr_accessor groups: untyped
attr_accessor windows: untyped
attr_accessor comment: untyped
attr_accessor havings: untyped
attr_accessor source: untyped
attr_accessor set_quantifier: untyped
attr_accessor optimizer_hints: untyped
def initialize: () -> untyped
def from: () -> untyped
def from=: (untyped value) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class SelectStatement < Arel::Nodes::NodeExpression
attr_reader cores: untyped
attr_accessor limit: untyped
attr_accessor orders: untyped
attr_accessor lock: untyped
attr_accessor offset: untyped
attr_accessor with: untyped
def initialize: (?::Array[untyped] cores) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class SqlLiteral < String
include Arel::Expressions
include Arel::Predications
include Arel::AliasPredication
include Arel::OrderPredications
def encode_with: (untyped coder) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class StringJoin < Arel::Nodes::Join
def initialize: (untyped left, ?untyped? right) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class TableAlias < Arel::Nodes::Binary
def []: (untyped name) -> ::Arel::Attributes::Attribute
def table_name: () -> untyped
def type_cast_for_database: (*untyped args) -> untyped
def able_to_type_cast?: () -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Distinct < Arel::Nodes::NodeExpression
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class True < Arel::Nodes::NodeExpression
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class UnaryOperation < Unary
attr_reader operator: untyped
def initialize: (untyped operator, untyped operand) -> untyped
end
class BitwiseNot < UnaryOperation
def initialize: (untyped operand) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class Unary < Arel::Nodes::NodeExpression
attr_accessor expr: untyped
def initialize: (untyped expr) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class UnqualifiedColumn < Arel::Nodes::Unary
def relation: () -> untyped
def column: () -> untyped
def name: () -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class UpdateStatement < Arel::Nodes::Node
attr_accessor relation: untyped
attr_accessor wheres: untyped
attr_accessor values: untyped
attr_accessor orders: untyped
attr_accessor limit: untyped
attr_accessor offset: untyped
attr_accessor key: untyped
def initialize: () -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class ValuesList < Unary
end
end
end
module Arel
# :nodoc: all
module Nodes
class Window < Arel::Nodes::Node
attr_accessor orders: untyped
attr_accessor framing: untyped
attr_accessor partitions: untyped
def initialize: () -> untyped
def order: (*untyped expr) -> untyped
def partition: (*untyped expr) -> untyped
def frame: (untyped expr) -> untyped
def rows: (?untyped? expr) -> untyped
def range: (?untyped? expr) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
class NamedWindow < Window
attr_accessor name: untyped
def initialize: (untyped name) -> untyped
def initialize_copy: (untyped other) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
class Rows < Unary
def initialize: (?untyped? expr) -> untyped
end
class Range[Elem] < Unary
def initialize: (?untyped? expr) -> untyped
end
class CurrentRow < Node
def hash: () -> untyped
def eql?: (untyped other) -> untyped
end
class Preceding < Unary
def initialize: (?untyped? expr) -> untyped
end
class Following < Unary
def initialize: (?untyped? expr) -> untyped
end
end
end
module Arel
# :nodoc: all
module Nodes
class With < Arel::Nodes::Unary
end
class WithRecursive < With
end
end
end
module Arel
# :nodoc: all
module OrderPredications
def asc: () -> Nodes::Ascending
def desc: () -> Nodes::Descending
end
end
module Arel
# :nodoc: all
module Predications
def not_eq: (untyped other) -> Nodes::NotEqual
def not_eq_any: (untyped others) -> untyped
def not_eq_all: (untyped others) -> untyped
def eq: (untyped other) -> Nodes::Equality
def is_not_distinct_from: (untyped other) -> Nodes::IsNotDistinctFrom
def is_distinct_from: (untyped other) -> Nodes::IsDistinctFrom
def eq_any: (untyped others) -> untyped
def eq_all: (untyped others) -> untyped
def between: (untyped other) -> untyped
def `in`: (untyped other) -> untyped
def in_any: (untyped others) -> untyped
def in_all: (untyped others) -> untyped
def not_between: (untyped other) -> untyped
def not_in: (untyped other) -> untyped
def not_in_any: (untyped others) -> untyped
def not_in_all: (untyped others) -> untyped
def matches: (untyped other, ?untyped? escape, ?bool case_sensitive) -> Nodes::Matches
def matches_regexp: (untyped other, ?bool case_sensitive) -> Nodes::Regexp
def matches_any: (untyped others, ?untyped? escape, ?bool case_sensitive) -> untyped
def matches_all: (untyped others, ?untyped? escape, ?bool case_sensitive) -> untyped
def does_not_match: (untyped other, ?untyped? escape, ?bool case_sensitive) -> Nodes::DoesNotMatch
def does_not_match_regexp: (untyped other, ?bool case_sensitive) -> Nodes::NotRegexp
def does_not_match_any: (untyped others, ?untyped? escape) -> untyped
def does_not_match_all: (untyped others, ?untyped? escape) -> untyped
def gteq: (untyped right) -> Nodes::GreaterThanOrEqual
def gteq_any: (untyped others) -> untyped
def gteq_all: (untyped others) -> untyped
def gt: (untyped right) -> Nodes::GreaterThan
def gt_any: (untyped others) -> untyped
def gt_all: (untyped others) -> untyped
def lt: (untyped right) -> Nodes::LessThan
def lt_any: (untyped others) -> untyped
def lt_all: (untyped others) -> untyped
def lteq: (untyped right) -> Nodes::LessThanOrEqual
def lteq_any: (untyped others) -> untyped
def lteq_all: (untyped others) -> untyped
def when: (untyped right) -> untyped
def concat: (untyped other) -> Nodes::Concat
def grouping_any: (untyped method_id, untyped others, *untyped extras) -> Nodes::Grouping
def grouping_all: (untyped method_id, untyped others, *untyped extras) -> Nodes::Grouping
def quoted_node: (untyped other) -> untyped
def quoted_array: (untyped others) -> untyped
def infinity?: (untyped value) -> untyped
def unboundable?: (untyped value) -> untyped
def open_ended?: (untyped value) -> untyped
end
end
module Arel
VERSION: ::String
# Wrap a known-safe SQL string for passing to query methods, e.g.
#
# Post.order(Arel.sql("length(title)")).last
#
# Great caution should be taken to avoid SQL injection vulnerabilities.
# This method should not be used with unsafe values such as request
# parameters or model attributes.
def self.sql: (untyped raw_sql) -> Arel::Nodes::SqlLiteral
def self.star: () -> untyped
def self.arel_node?: (untyped value) -> untyped
def self.fetch_attribute: (untyped value) { (untyped) -> untyped } -> untyped
Node: untyped
end
module Arel
# :nodoc: all
class SelectManager < Arel::TreeManager
include Arel::Crud
STRING_OR_SYMBOL_CLASS: ::Array[untyped]
def initialize: (?untyped? table) -> untyped
def initialize_copy: (untyped other) -> untyped
def limit: () -> untyped
def constraints: () -> untyped
def offset: () -> untyped
def skip: (untyped amount) -> untyped
# #
# Produces an Arel::Nodes::Exists node
def exists: () -> Arel::Nodes::Exists
def as: (untyped other) -> untyped
def lock: (?untyped locking) -> untyped
def locked: () -> untyped
def on: (*untyped exprs) -> untyped
def group: (*untyped columns) -> untyped
def from: (untyped table) -> untyped
def froms: () -> untyped
def join: (untyped relation, ?untyped klass) -> untyped
def outer_join: (untyped relation) -> untyped
def having: (untyped expr) -> untyped
def window: (untyped name) -> untyped
def project: (*untyped projections) -> untyped
def projections: () -> untyped
def projections=: (untyped projections) -> untyped
def optimizer_hints: (*untyped hints) -> untyped
def distinct: (?bool value) -> untyped
def distinct_on: (untyped value) -> untyped
def order: (*untyped expr) -> untyped
def orders: () -> untyped
def where_sql: (?untyped engine) -> (nil | Nodes::SqlLiteral)
def union: (untyped operation, ?untyped? other) -> untyped
def intersect: (untyped other) -> Nodes::Intersect
def except: (untyped other) -> Nodes::Except
def lateral: (?untyped? table_name) -> Nodes::Lateral
def with: (*untyped subqueries) -> untyped
def take: (untyped limit) -> untyped
def join_sources: () -> untyped
def source: () -> untyped
def comment: (*untyped values) -> untyped
def collapse: (untyped exprs) -> untyped
end
end
module Arel
# :nodoc: all
class Table
include Arel::Crud
include Arel::FactoryMethods
attr_accessor engine: untyped
attr_accessor name: untyped
attr_accessor table_alias: untyped
def initialize: (untyped name, ?type_caster: untyped? type_caster, ?as: untyped? as) -> untyped
def `alias`: (?::String name) -> Nodes::TableAlias
def from: () -> SelectManager
def join: (untyped relation, ?untyped klass) -> untyped
def outer_join: (untyped relation) -> untyped
def group: (*untyped columns) -> untyped
def order: (*untyped expr) -> untyped
def where: (untyped condition) -> untyped
def project: (*untyped things) -> untyped
def take: (untyped amount) -> untyped
def skip: (untyped amount) -> untyped
def having: (untyped expr) -> untyped
def []: (untyped name) -> untyped
def hash: () -> untyped
def eql?: (untyped other) -> untyped
def type_cast_for_database: (untyped attribute_name, untyped value) -> untyped
def able_to_type_cast?: () -> untyped
attr_reader type_caster: untyped
end
end
module Arel
# :nodoc: all
class TreeManager
include Arel::FactoryMethods
module StatementMethods
def take: (untyped limit) -> untyped
def offset: (untyped offset) -> untyped
def order: (*untyped expr) -> untyped
def key=: (untyped key) -> untyped
def key: () -> untyped
def wheres=: (untyped exprs) -> untyped
def where: (untyped expr) -> untyped
end
attr_reader ast: untyped
def initialize: () -> untyped
def to_dot: () -> untyped
def to_sql: (?untyped engine) -> untyped
def initialize_copy: (untyped other) -> untyped
def where: (untyped expr) -> untyped
end
end
module Arel
# :nodoc: all
class UpdateManager < Arel::TreeManager
include TreeManager::StatementMethods
def initialize: () -> untyped
# #
# UPDATE +table+
def table: (untyped table) -> untyped
def set: (untyped values) -> untyped
end
end
module Arel
# :nodoc: all
module Visitors
class DepthFirst < Arel::Visitors::Visitor
def initialize: (?untyped? block) -> untyped
def visit: (untyped o, ?untyped? _) -> untyped
def unary: (untyped o) -> untyped
def function: (untyped o) -> untyped
def visit_Arel_Nodes_NamedFunction: (untyped o) -> untyped
def visit_Arel_Nodes_Count: (untyped o) -> untyped
def visit_Arel_Nodes_Case: (untyped o) -> untyped
def nary: (untyped o) -> untyped
def binary: (untyped o) -> untyped
def visit_Arel_Nodes_StringJoin: (untyped o) -> untyped
def visit_Arel_Attribute: (untyped o) -> untyped
def visit_Arel_Table: (untyped o) -> untyped
def terminal: (untyped o) -> nil
def visit_Arel_Nodes_InsertStatement: (untyped o) -> untyped
def visit_Arel_Nodes_SelectCore: (untyped o) -> untyped
def visit_Arel_Nodes_SelectStatement: (untyped o) -> untyped
def visit_Arel_Nodes_UpdateStatement: (untyped o) -> untyped
def visit_Arel_Nodes_Comment: (untyped o) -> untyped
def visit_Array: (untyped o) -> untyped
def visit_Hash: (untyped o) -> untyped
DISPATCH: untyped
def get_dispatch_cache: () -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class Dot < Arel::Visitors::Visitor
class Node
# :nodoc:
attr_accessor name: untyped
# :nodoc:
attr_accessor id: untyped
# :nodoc:
attr_accessor fields: untyped
def initialize: (untyped name, untyped id, ?untyped fields) -> untyped
end
# Note: It inherits unnamed class, but omitted
class Edge
end
def initialize: () -> untyped
def accept: (untyped object, untyped collector) -> untyped
def visit_Arel_Nodes_Ordering: (untyped o) -> untyped
def visit_Arel_Nodes_TableAlias: (untyped o) -> untyped
def visit_Arel_Nodes_Count: (untyped o) -> untyped
def visit_Arel_Nodes_ValuesList: (untyped o) -> untyped
def visit_Arel_Nodes_StringJoin: (untyped o) -> untyped
def visit_Arel_Nodes_InnerJoin: (untyped o) -> untyped
def visit_Arel_Nodes_DeleteStatement: (untyped o) -> untyped
def unary: (untyped o) -> untyped
def window: (untyped o) -> untyped
def named_window: (untyped o) -> untyped
def function: (untyped o) -> untyped
def extract: (untyped o) -> untyped
def visit_Arel_Nodes_NamedFunction: (untyped o) -> untyped
def visit_Arel_Nodes_InsertStatement: (untyped o) -> untyped
def visit_Arel_Nodes_SelectCore: (untyped o) -> untyped
def visit_Arel_Nodes_SelectStatement: (untyped o) -> untyped
def visit_Arel_Nodes_UpdateStatement: (untyped o) -> untyped
def visit_Arel_Table: (untyped o) -> untyped
def visit_Arel_Nodes_Casted: (untyped o) -> untyped
def visit_Arel_Attribute: (untyped o) -> untyped
def nary: (untyped o) -> untyped
def binary: (untyped o) -> untyped
def visit_String: (untyped o) -> untyped
def visit_Arel_Nodes_BindParam: (untyped o) -> nil
def visit_Hash: (untyped o) -> untyped
def visit_Array: (untyped o) -> untyped
def visit_Arel_Nodes_Comment: (untyped o) -> untyped
def visit_edge: (untyped o, untyped method) -> untyped
def visit: (untyped o) -> (nil | untyped)
def edge: (untyped name) { () -> untyped } -> untyped
def with_node: (untyped node) { () -> untyped } -> untyped
def quote: (untyped string) -> untyped
def to_dot: () -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class IBM_DB < Arel::Visitors::ToSql
def visit_Arel_Nodes_SelectCore: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_OptimizerHints: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Limit: (untyped o, untyped collector) -> untyped
def is_distinct_from: (untyped o, untyped collector) -> untyped
def collect_optimizer_hints: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class Informix < Arel::Visitors::ToSql
def visit_Arel_Nodes_SelectStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectCore: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_OptimizerHints: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Offset: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Limit: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class MSSQL < Arel::Visitors::ToSql
class RowNumber < ::Struct[untyped]
attr_accessor children(): untyped
end
def initialize: () -> untyped
def visit_Arel_Nodes_IsNotDistinctFrom: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsDistinctFrom: (untyped o, untyped collector) -> untyped
def visit_Arel_Visitors_MSSQL_RowNumber: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectCore: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_OptimizerHints: (untyped o, untyped collector) -> untyped
def get_offset_limit_clause: (untyped o) -> untyped
def visit_Arel_Nodes_DeleteStatement: (untyped o, untyped collector) -> untyped
def collect_optimizer_hints: (untyped o, untyped collector) -> untyped
def determine_order_by: (untyped orders, untyped x) -> untyped
def row_num_literal: (untyped order_by) -> RowNumber
def select_count?: (untyped x) -> untyped
# FIXME raise exception of there is no pk?
def find_left_table_pk: (untyped o) -> untyped
def find_primary_key: (untyped o) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class MySQL < Arel::Visitors::ToSql
def visit_Arel_Nodes_Bin: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_UnqualifiedColumn: (untyped o, untyped collector) -> untyped
# #
# :'(
# http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214
def visit_Arel_Nodes_SelectStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectCore: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Concat: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsNotDistinctFrom: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsDistinctFrom: (untyped o, untyped collector) -> untyped
# In the simple case, MySQL allows us to place JOINs directly into the UPDATE
# query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
# these, we must use a subquery.
def prepare_update_statement: (untyped o) -> untyped
# MySQL is too stupid to create a temporary table for use subquery, so we have
# to give it some prompting in the form of a subsubquery.
def build_subselect: (untyped key, untyped o) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class Oracle12 < Arel::Visitors::ToSql
def visit_Arel_Nodes_SelectStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectOptions: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Limit: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Offset: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Except: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_UpdateStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_BindParam: (untyped o, untyped collector) -> untyped
def is_distinct_from: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class Oracle < Arel::Visitors::ToSql
def visit_Arel_Nodes_SelectStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Limit: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Offset: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Except: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_UpdateStatement: (untyped o, untyped collector) -> untyped
# #
# Hacks for the order clauses specific to Oracle
def order_hacks: (untyped o) -> untyped
# Split string by commas but count opening and closing brackets
# and ignore commas inside brackets.
def split_order_string: (untyped string) -> untyped
def visit_Arel_Nodes_BindParam: (untyped o, untyped collector) -> untyped
def is_distinct_from: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class PostgreSQL < Arel::Visitors::ToSql
def visit_Arel_Nodes_Matches: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_DoesNotMatch: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Regexp: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_NotRegexp: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_DistinctOn: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_BindParam: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_GroupingElement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Cube: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_RollUp: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_GroupingSet: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Lateral: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsNotDistinctFrom: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsDistinctFrom: (untyped o, untyped collector) -> untyped
# Used by Lateral visitor to enclose select queries in parentheses
def grouping_parentheses: (untyped o, untyped collector) -> untyped
# Utilized by GroupingSet, Cube & RollUp visitors to
# handle grouping aggregation semantics
def grouping_array_or_grouping_element: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
end
end
module Arel
# :nodoc: all
module Visitors
class SQLite < Arel::Visitors::ToSql
# Locks are not supported in SQLite
def visit_Arel_Nodes_Lock: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_True: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_False: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsNotDistinctFrom: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsDistinctFrom: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class UnsupportedVisitError < StandardError
def initialize: (untyped object) -> untyped
end
class ToSql < Arel::Visitors::Visitor
def initialize: (untyped connection) -> untyped
def compile: (untyped node, ?untyped collector) -> untyped
def visit_Arel_Nodes_DeleteStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_UpdateStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_InsertStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Exists: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Casted: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Quoted: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_True: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_False: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_ValuesList: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectStatement: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectOptions: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_SelectCore: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_OptimizerHints: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Comment: (untyped o, untyped collector) -> untyped
def collect_nodes_for: (untyped nodes, untyped collector, untyped spacer, ?::String connector) -> untyped
def visit_Arel_Nodes_Bin: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Distinct: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_DistinctOn: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_With: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_WithRecursive: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Union: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_UnionAll: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Intersect: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Except: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_NamedWindow: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Window: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Rows: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Range: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Preceding: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Following: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_CurrentRow: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Over: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Offset: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Limit: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Lock: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Grouping: (untyped o, untyped collector) -> untyped
def visit_Arel_SelectManager: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Ascending: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Descending: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Group: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_NamedFunction: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Extract: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Count: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Sum: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Max: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Min: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Avg: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_TableAlias: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Between: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_GreaterThanOrEqual: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_GreaterThan: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_LessThanOrEqual: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_LessThan: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Matches: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_DoesNotMatch: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_JoinSource: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Regexp: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_NotRegexp: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_StringJoin: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_FullOuterJoin: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_OuterJoin: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_RightOuterJoin: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_InnerJoin: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_On: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Not: (untyped o, untyped collector) -> untyped
def visit_Arel_Table: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_In: (untyped o, untyped collector) -> untyped
def collect_in_clause: (untyped left, untyped right, untyped collector) -> untyped
def visit_Arel_Nodes_NotIn: (untyped o, untyped collector) -> untyped
def collect_not_in_clause: (untyped left, untyped right, untyped collector) -> untyped
def visit_Arel_Nodes_And: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Or: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Assignment: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Equality: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsNotDistinctFrom: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_IsDistinctFrom: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_NotEqual: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_As: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Case: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_When: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_Else: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_UnqualifiedColumn: (untyped o, untyped collector) -> untyped
def visit_Arel_Attributes_Attribute: (untyped o, untyped collector) -> untyped
def literal: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_BindParam: (untyped o, untyped collector) -> untyped
def quoted: (untyped o, untyped a) -> untyped
def unsupported: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_InfixOperation: (untyped o, untyped collector) -> untyped
def visit_Arel_Nodes_UnaryOperation: (untyped o, untyped collector) -> untyped
def visit_Array: (untyped o, untyped collector) -> untyped
def quote: (untyped value) -> untyped
def quote_table_name: (untyped name) -> untyped
def quote_column_name: (untyped name) -> untyped
def sanitize_as_sql_comment: (untyped value) -> untyped
def collect_optimizer_hints: (untyped o, untyped collector) -> untyped
def maybe_visit: (untyped thing, untyped collector) -> untyped
def inject_join: (untyped list, untyped collector, untyped join_str) -> untyped
def unboundable?: (untyped value) -> untyped
def has_join_sources?: (untyped o) -> untyped
def has_limit_or_offset_or_orders?: (untyped o) -> untyped
# The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
# on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
# an UPDATE statement, so in the MySQL visitor we redefine this to do that.
def prepare_update_statement: (untyped o) -> untyped
# FIXME: we should probably have a 2-pass visitor for this
def build_subselect: (untyped key, untyped o) -> untyped
def infix_value: (untyped o, untyped collector, untyped value) -> untyped
def infix_value_with_paren: (untyped o, untyped collector, untyped value, ?bool suppress_parens) -> untyped
def aggregate: (untyped name, untyped o, untyped collector) -> untyped
def is_distinct_from: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class Visitor
def initialize: () -> untyped
def accept: (untyped object, ?untyped? collector) -> untyped
attr_reader dispatch: untyped
def self.dispatch_cache: () -> untyped
def get_dispatch_cache: () -> untyped
def visit: (untyped object, ?untyped? collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module Visitors
class WhereSql < Arel::Visitors::ToSql
def initialize: (untyped inner_visitor, *untyped args) { () -> untyped } -> untyped
def visit_Arel_Nodes_SelectCore: (untyped o, untyped collector) -> untyped
end
end
end
module Arel
# :nodoc: all
module WindowPredications
def over: (?untyped? expr) -> Nodes::Over
end
end
module ActiveRecord
module Generators
class ApplicationRecordGenerator < ::Rails::Generators::Base
# FIXME: Change this file to a symlink once RubyGems 2.5.0 is required.
def create_application_record: () -> untyped
def application_record_file_name: () -> untyped
end
end
end
module ActiveRecord
module Generators
class MigrationGenerator < Base
def create_migration_file: () -> untyped
attr_reader migration_action: untyped
attr_reader join_tables: untyped
# Sets the default migration template that is being used for the generation of the migration.
# Depending on command line arguments, the migration template and the table name instance
# variables are set up.
def set_local_assigns!: () -> untyped
def set_index_names: () -> untyped
def index_name_for: (untyped attribute) -> untyped
def attributes_with_index: () -> untyped
# A migration file name can only contain underscores (_), lowercase characters,
# and numbers 0-9. Any other file name will raise an IllegalMigrationNameError.
def validate_file_name!: () -> untyped
def normalize_table_name: (untyped _table_name) -> untyped
end
end
end
module ActiveRecord
module Generators
# :nodoc:
module Migration
extend ActiveSupport::Concern
include Rails::Generators::Migration
extend ::Rails::Generators::Migration::ClassMethods
module ClassMethods
# Implement the required interface for Rails::Generators::Migration.
def next_migration_number: (untyped dirname) -> untyped
end
def primary_key_type: () -> untyped
def db_migrate_path: () -> untyped
def default_migrate_path: () -> untyped
def configured_migrate_path: () -> (nil | untyped)
end
end
end
module ActiveRecord
module Generators
class ModelGenerator < Base
# creates the migration file for the model.
def create_migration_file: () -> (nil | untyped)
def create_model_file: () -> untyped
def create_module_file: () -> (nil | untyped)
def attributes_with_index: () -> untyped
# Used by the migration template to determine the parent name of the model
def parent_class_name: () -> untyped
end
end
end
module ActiveRecord
module Generators
class Base < Rails::Generators::NamedBase
# :nodoc:
# :nodoc:
include ActiveRecord::Generators::Migration
extend ::ActiveRecord::Generators::Migration::ClassMethods
# Set the current directory as base for the inherited generators.
def self.base_root: () -> untyped
end
end
end