Module: ActiveRecord::Core
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
::ActiveSupport::Concern
|
|
Defined in: | activerecord/lib/active_record/core.rb |
Class Method Summary
::ActiveSupport::Concern
- Extended
class_methods | Define class methods from given block. |
included | Evaluate given block in context of base class, so that you can write class macros here. |
prepended | Evaluate given block in context of base class, so that you can write class macros here. |
Instance Attribute Summary
-
#frozen? ⇒ Boolean
readonly
Returns
true
if the attributes hash has been frozen. -
#readonly? ⇒ Boolean
readonly
Returns
true
if the record is read only. -
#strict_loading? ⇒ Boolean
readonly
Returns
true
if the record is in strict_loading mode.
Instance Method Summary
-
#<=>(other_object)
Allows sort on objects.
-
#==(comparison_object)
(also: #eql?)
Returns true if
comparison_object
is the same exact object, orcomparison_object
is of the same type andself
has an ID and it is equal tocomparison_object.id
. -
#clone
Identical to Ruby’s clone method.
- #connection_handler
-
#dup
Duped objects have no id assigned and are treated as new records.
-
#encode_with(coder)
Populate
coder
with attributes about this record that should be serialized. -
#eql?(comparison_object)
Alias for #==.
-
#freeze
Clone and freeze the attributes hash such that associations are still accessible, even on destroyed records, but cloned models will not be frozen.
-
#hash
Delegates to id in order to allow two records of the same type and id to work with something like:
-
#init_with(coder, &block)
Initialize an empty model object from
coder
. -
#initialize(attributes = nil) {|_self| ... }
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).
-
#inspect
Returns the contents of the record as a nicely formatted string.
- #inspection_filter
-
#pretty_print(pp)
Takes a PP and prettily prints this record to it, allowing you to get a nice result from
pp record
when pp is required. -
#readonly!
Marks this record as read only.
-
#slice(*methods)
Returns a hash of the given methods with their names as keys and returned values as values.
-
#strict_loading!
Sets the record to strict_loading mode.
-
#values_at(*methods)
Returns an array of the values returned by the given methods.
DSL Calls
included
[ GitHub ]13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
# File 'activerecord/lib/active_record/core.rb', line 13
included do ## # :singleton-method: # # Accepts a logger conforming to the interface of Log4r which is then # passed on to any new database connections made and which can be # retrieved on both a class and instance level by calling logger. mattr_accessor :logger, instance_writer: false ## # :singleton-method: # # Specifies if the methods calling database queries should be logged below # their relevant queries. Defaults to false. mattr_accessor :verbose_query_logs, instance_writer: false, default: false ## # :singleton-method: # # Specifies the names of the queues used by background jobs. mattr_accessor :queues, instance_accessor: false, default: {} ## # :singleton-method: # # Specifies the job used to destroy associations in the background class_attribute :destroy_association_async_job, instance_writer: false, instance_predicate: false, default: false ## # 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: # # #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development", # @name="primary", @config={adapter: "sqlite3", database: "db/development.sqlite3"}>, # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production", # @name="primary", @config={adapter: "sqlite3", database: "db/production.sqlite3"}> # ]> def self.configurations=(config) @@configurations = ActiveRecord::DatabaseConfigurations.new(config) end self.configurations = {} # Returns fully resolved ActiveRecord::DatabaseConfigurations object def self.configurations @@configurations end ## # :singleton-method: # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling # dates and times from the database. This is set to :utc by default. mattr_accessor :default_timezone, instance_writer: false, default: :utc ## # :singleton-method: # Specifies the format to use when dumping the database schema with Rails' # Rakefile. If :sql, the schema is dumped as (potentially database- # specific) SQL statements. If :ruby, the schema is dumped as an # ActiveRecord::Schema file which can be loaded into any database that # supports migrations. Use :ruby if you want to have different database # adapters for, e.g., your development and test environments. mattr_accessor :schema_format, instance_writer: false, default: :ruby ## # :singleton-method: # Specifies if an error should be raised if the query has an order being # ignored when doing batch queries. Useful in applications where the # scope being ignored is error-worthy, rather than a warning. mattr_accessor :error_on_ignored_order, instance_writer: false, default: false ## # :singleton-method: # Specify whether or not to use timestamps for migration versions mattr_accessor :, instance_writer: false, default: true ## # :singleton-method: # Specify whether schema dump should happen at the end of the # db:migrate rails command. This is true by default, which is useful for the # development environment. This should ideally be false in the production # environment where dumping schema is rarely needed. mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true ## # :singleton-method: # Specifies which database schemas to dump when calling db:schema:dump. # If the value is :schema_search_path (the default), any schemas listed in # schema_search_path are dumped. Use :all to dump all schemas regardless # of schema_search_path, or a string of comma separated schemas for a # custom list. mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path ## # :singleton-method: # Specify a threshold for the size of query result sets. If the number of # records in the set exceeds the threshold, a warning is logged. This can # be used to identify queries which load thousands of records and # potentially cause memory bloat. mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false ## # :singleton-method: # Show a warning when Rails couldn't parse your database.yml # for multiple databases. mattr_accessor :suppress_multiple_database_warning, instance_writer: false, default: false mattr_accessor :maintain_test_schema, instance_accessor: false class_attribute :belongs_to_required_by_default, instance_accessor: false ## # :singleton-method: # Set the application to log or raise when an association violates strict loading. # Defaults to :raise. mattr_accessor :action_on_strict_loading_violation, instance_accessor: false, default: :raise class_attribute :strict_loading_by_default, instance_accessor: false, default: false mattr_accessor :writing_role, instance_accessor: false, default: :writing mattr_accessor :reading_role, instance_accessor: false, default: :reading mattr_accessor :has_many_inversing, instance_accessor: false, default: false class_attribute :default_connection_handler, instance_writer: false class_attribute :default_role, instance_writer: false class_attribute :default_shard, instance_writer: false mattr_accessor :legacy_connection_handling, instance_writer: false, default: true # Application configurable boolean that instructs the YAML Coder to use # an unsafe load if set to true. mattr_accessor :use_yaml_unsafe_load, instance_writer: false, default: false # Application configurable array that provides additional permitted classes # to Psych safe_load in the YAML Coder mattr_accessor :yaml_column_permitted_classes, instance_writer: false, default: [Symbol] ## # :singleton-method: # Application configurable boolean that denotes whether or not to raise # an exception when the PostgreSQLAdapter is provided with an integer that is # wider than signed 64bit representation mattr_accessor :raise_int_wider_than_64bit, instance_writer: false, default: true self.filter_attributes = [] def self.connection_handler Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler end def self.connection_handler=(handler) Thread.current.thread_variable_set(:ar_connection_handler, handler) end def self.connection_handlers unless legacy_connection_handling raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers." end @@connection_handlers ||= {} end def self.connection_handlers=(handlers) unless legacy_connection_handling raise NotImplementedError, "The new connection handling does not setting support multiple connection handlers." end @@connection_handlers = handlers end # 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 self.current_role if ActiveRecord::Base.legacy_connection_handling connection_handlers.key(connection_handler) || default_role else connected_to_stack.reverse_each do |hash| return hash[:role] if hash[:role] && hash[:klasses].include?(Base) return hash[:role] if hash[:role] && hash[:klasses].include?(connection_classes) end default_role end end # Returns the symbol representing the current connected shard. # # ActiveRecord::Base.connected_to(role: :reading) do # ActiveRecord::Base.current_shard #=> :default # end # # ActiveRecord::Base.connected_to(role: :writing, shard: :one) do # ActiveRecord::Base.current_shard #=> :one # end def self.current_shard connected_to_stack.reverse_each do |hash| return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base) return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_classes) end default_shard end # Returns the symbol representing the current setting for # preventing writes. # # ActiveRecord::Base.connected_to(role: :reading) do # ActiveRecord::Base.current_preventing_writes #=> true # end # # ActiveRecord::Base.connected_to(role: :writing) do # ActiveRecord::Base.current_preventing_writes #=> false # end def self.current_preventing_writes if legacy_connection_handling connection_handler.prevent_writes else connected_to_stack.reverse_each do |hash| return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base) return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_classes) end false end end def self.connected_to_stack # :nodoc: if connected_to_stack = Thread.current.thread_variable_get(:ar_connected_to_stack) connected_to_stack else connected_to_stack = Concurrent::Array.new Thread.current.thread_variable_set(:ar_connected_to_stack, connected_to_stack) connected_to_stack end end def self.connection_class=(b) # :nodoc: @connection_class = b end def self.connection_class # :nodoc @connection_class ||= false end def self.connection_class? # :nodoc: self.connection_class end def self.connection_classes # :nodoc: klass = self until klass == Base break if klass.connection_class? klass = klass.superclass end klass end def self.allow_unsafe_raw_sql # :nodoc: ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 7.0") end def self.allow_unsafe_raw_sql=(value) # :nodoc: ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 7.0") end self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new self.default_role = writing_role self.default_shard = :default def self.strict_loading_violation!(owner:, reflection:) # :nodoc: case action_on_strict_loading_violation when :raise = "`#{owner}` is marked for strict_loading. The `#{reflection.klass}` association named `:#{reflection.name}` cannot be lazily loaded." raise ActiveRecord::StrictLoadingViolationError.new( ) when :log name = "strict_loading_violation.active_record" ActiveSupport::Notifications.instrument(name, owner: owner, reflection: reflection) end end end
Instance Attribute Details
#frozen? ⇒ Boolean
(readonly)
Returns true
if the attributes hash has been frozen.
# File 'activerecord/lib/active_record/core.rb', line 664
def frozen? @attributes.frozen? end
#readonly? ⇒ Boolean
(readonly)
Returns true
if the record is read only.
# File 'activerecord/lib/active_record/core.rb', line 686
def readonly? @readonly end
#strict_loading? ⇒ Boolean
(readonly)
Returns true
if the record is in strict_loading mode.
# File 'activerecord/lib/active_record/core.rb', line 691
def strict_loading? @strict_loading end
Instance Method Details
#<=>(other_object)
Allows sort on objects
# File 'activerecord/lib/active_record/core.rb', line 669
def <=>(other_object) if other_object.is_a?(self.class) to_key <=> other_object.to_key else super end end
#==(comparison_object) Also known as: #eql?
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.
# File 'activerecord/lib/active_record/core.rb', line 637
def ==(comparison_object) super || comparison_object.instance_of?(self.class) && !id.nil? && comparison_object.id == id end
#clone
Identical to Ruby’s clone method. This is a “shallow” copy. Be warned that your attributes are not copied. That means that modifying attributes of the clone will modify the original, since they will both point to the same attributes hash. If you need a copy of your attributes hash, please use the #dup method.
user = User.first
new_user = user.clone
user.name # => "Bob"
new_user.name = "Joe"
user.name # => "Joe"
user.object_id == new_user.object_id # => false
user.name.object_id == new_user.name.object_id # => true
user.name.object_id == user.dup.name.object_id # => false
# File 'activerecord/lib/active_record/core.rb', line 570
rdoc_method :method: clone
#connection_handler
[ GitHub ]# File 'activerecord/lib/active_record/core.rb', line 711
def connection_handler self.class.connection_handler end
#dup
Duped objects have no id assigned and are treated as new records. Note that this is a “shallow” copy as it copies the object’s attributes only, not its associations. The extent of a “deep” copy is application specific and is therefore left to the application to implement according to its need. The dup method does not preserve the timestamps (created|updated)_(at|on).
# File 'activerecord/lib/active_record/core.rb', line 587
rdoc_method :method: dup
#encode_with(coder)
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, ... }}
# File 'activerecord/lib/active_record/core.rb', line 622
def encode_with(coder) self.class.yaml_encoder.encode(@attributes, coder) coder["new_record"] = new_record? coder["active_record_yaml_version"] = 2 end
#eql?(comparison_object)
Alias for #==.
# File 'activerecord/lib/active_record/core.rb', line 643
alias :eql? :==
#freeze
Clone and freeze the attributes hash such that associations are still accessible, even on destroyed records, but cloned models will not be frozen.
# File 'activerecord/lib/active_record/core.rb', line 658
def freeze @attributes = @attributes.clone.freeze self end
#hash
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) ]
# File 'activerecord/lib/active_record/core.rb', line 647
def hash if id self.class.hash ^ id.hash else super end end
#init_with(coder, &block)
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'
# File 'activerecord/lib/active_record/core.rb', line 545
def init_with(coder, &block) coder = LegacyYamlAdapter.convert(self.class, coder) attributes = self.class.yaml_encoder.decode(coder) init_with_attributes(attributes, coder["new_record"], &block) end
#initialize(attributes = nil) {|_self| ... }
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')
# File 'activerecord/lib/active_record/core.rb', line 518
def initialize(attributes = nil) @new_record = true @attributes = self.class._default_attributes.deep_dup init_internals initialize_internals_callback assign_attributes(attributes) if attributes yield self if block_given? _run_initialize_callbacks end
#inspect
Returns the contents of the record as a nicely formatted string.
# File 'activerecord/lib/active_record/core.rb', line 716
def inspect # We check defined?(@attributes) not to issue warnings if the object is # allocated but not initialized. inspection = if defined?(@attributes) && @attributes self.class.attribute_names.collect do |name| if _has_attribute?(name) "#{name}: #{attribute_for_inspect(name)}" end end.compact.join(", ") else "not initialized" end "#<#{self.class} #{inspection}>" end
#inspection_filter
[ GitHub ]# File 'activerecord/lib/active_record/core.rb', line 807
def inspection_filter self.class.inspection_filter end
#pretty_print(pp)
Takes a PP and prettily prints this record to it, allowing you to get a nice result from pp record
when pp is required.
# File 'activerecord/lib/active_record/core.rb', line 734
def pretty_print(pp) return super if custom_inspect_method_defined? pp.object_address_group(self) do if defined?(@attributes) && @attributes attr_names = self.class.attribute_names.select { |name| _has_attribute?(name) } pp.seplist(attr_names, proc { pp.text "," }) do |attr_name| pp.breakable " " pp.group(1) do pp.text attr_name pp.text ":" pp.breakable value = _read_attribute(attr_name) value = inspection_filter.filter_param(attr_name, value) unless value.nil? pp.pp value end end else pp.breakable " " pp.text "not initialized" end end end
#readonly!
Marks this record as read only.
# File 'activerecord/lib/active_record/core.rb', line 707
def readonly! @readonly = true end
#slice(*methods)
Returns a hash of the given methods with their names as keys and returned values as values.
# File 'activerecord/lib/active_record/core.rb', line 758
def slice(*methods) methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access end
#strict_loading!
Sets the record to strict_loading mode. This will raise an error if the record tries to lazily load an association.
user = User.first
user.strict_loading!
user.comments.to_a
#=> ActiveRecord::StrictLoadingViolationError
# File 'activerecord/lib/active_record/core.rb', line 702
def strict_loading! @strict_loading = true end
#values_at(*methods)
Returns an array of the values returned by the given methods.
# File 'activerecord/lib/active_record/core.rb', line 763
def values_at(*methods) methods.flatten.map! { |method| public_send(method) } end