File: //usr/local/rvm/gems/ruby-2.7.4/doc/activerecord-6.1.4.1/ri/ActiveRecord/Base/cdesc-Base.ri
U:RDoc::NormalClass[iI" Base:ETI"ActiveRecord::Base;TI"Object;To:RDoc::Markup::Document:@parts[o;;[cS:RDoc::Markup::Heading:
leveli: textI"Active Record;To:RDoc::Markup::BlankLine o:RDoc::Markup::Paragraph;[
I"_Active Record objects don't specify their attributes directly, but rather infer them from ;TI"_the table definition with which they're linked. Adding, removing, and changing attributes ;TI"_and their type is done directly in the database. Any change is instantly reflected in the ;TI"\Active Record objects. The mapping that binds a given Active Record class to a certain ;TI"qdatabase table will happen automatically in most common cases, but can be overwritten for the uncommon ones.;T@o;
;[I"{See the mapping rules in table_name and the full example in link:files/activerecord/README_rdoc.html for more insight.;T@S; ;
i;I"
Creation;T@o;
;[I"[Active Records accept constructor parameters either in a hash or as a block. The hash ;TI"]method is especially useful when you're receiving the data from somewhere else, like an ;TI"&HTTP request. It works like this:;T@o:RDoc::Markup::Verbatim;[I"?user = User.new(name: "David", occupation: "Code Artist")
;TI"user.name # => "David"
;T:@format0o;
;[I"+You can also use block initialization:;T@o;;[ I"user = User.new do |u|
;TI" u.name = "David"
;TI"$ u.occupation = "Code Artist"
;TI" end
;T;0o;
;[I"_And of course you can just create a bare object and specify the attributes after the fact:;T@o;;[I"user = User.new
;TI"user.name = "David"
;TI"%user.occupation = "Code Artist"
;T;0S; ;
i;I"Conditions;T@o;
;[ I"uConditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement. ;TI"uThe array form is to be used when the condition input is tainted and requires sanitization. The string form can ;TI"rbe used for statements that don't involve tainted data. The hash form works much like the array form, except ;TI"3only equality and range is possible. Examples:;T@o;;[I"%class User < ActiveRecord::Base
;TI"; def self.authenticate_unsafely(user_name, password)
;TI"P where("user_name = '#{user_name}' AND password = '#{password}'").first
;TI" end
;TI"
;TI"9 def self.authenticate_safely(user_name, password)
;TI"L where("user_name = ? AND password = ?", user_name, password).first
;TI" end
;TI"
;TI"@ def self.authenticate_safely_simply(user_name, password)
;TI"? where(user_name: user_name, password: password).first
;TI" end
;TI" end
;T;0o;
;[I"^The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query ;TI"_and is thus susceptible to SQL-injection attacks if the <tt>user_name</tt> and +password+ ;TI"Yparameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and ;TI"b<tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+ ;TI"]before inserting them in the query, which will ensure that an attacker can't escape the ;TI")query and fake the login (or worse).;T@o;
;[ I"aWhen using multiple parameters in the conditions, it can easily become hard to read exactly ;TI"^what the fourth or fifth question mark is supposed to represent. In those cases, you can ;TI"^resort to named bind variables instead. That's done by replacing the question marks with ;TI"Ksymbols and supplying a hash with values for the matching symbol keys:;T@o;;[ I"Company.where(
;TI"_ "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
;TI"V { id: 3, name: "37signals", division: "First", accounting_date: '2005-01-01' }
;TI"
).first
;T;0o;
;[I"nSimilarly, a simple hash without a statement will generate conditions based on equality with the SQL AND ;TI"operator. For instance:;T@o;;[I"4Student.where(first_name: "Harvey", status: 1)
;TI"%Student.where(params[:student])
;T;0o;
;[I"EA range may be used in the hash to use the SQL BETWEEN operator:;T@o;;[I"!Student.where(grade: 9..12)
;T;0o;
;[I"AAn array may be used in the hash to use the SQL IN operator:;T@o;;[I"%Student.where(grade: [9,11,12])
;T;0o;
;[I"]When joining tables, nested hashes or keys written in the form 'table_name.column_name' ;TI"Scan be used to qualify the table name of a particular condition. For instance:;T@o;;[I"DStudent.joins(:schools).where(schools: { category: 'public' })
;TI"DStudent.joins(:schools).where('schools.category' => 'public' )
;T;0S; ;
i;I""Overwriting default accessors;T@o;
;[ I"`All column values are automatically available through basic accessors on the Active Record ;TI"aobject, but sometimes you want to specialize this behavior. This can be done by overwriting ;TI"Nthe default accessors (using the same name as the attribute) and calling ;TI"'+super+ to actually change things.;T@o;;[I"%class Song < ActiveRecord::Base
;TI"C # Uses an integer of seconds to hold the length of the song
;TI"
;TI" def length=(minutes)
;TI"" super(minutes.to_i * 60)
;TI" end
;TI"
;TI" def length
;TI" super / 60
;TI" end
;TI" end
;T;0S; ;
i;I"Attribute query methods;T@o;
;[I"uIn addition to the basic accessors, query methods are also automatically available on the Active Record object. ;TI"LQuery methods allow you to test whether an attribute value is present. ;TI"kAdditionally, when dealing with numeric values, a query method will return false if the value is zero.;T@o;
;[I"wFor example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call ;TI".to determine whether the user has a name:;T@o;;[
I"$user = User.new(name: "David")
;TI"user.name? # => true
;TI"
;TI"$anonymous = User.new(name: "")
;TI" anonymous.name? # => false
;T;0S; ;
i;I":Accessing attributes before they have been typecasted;T@o;
;[ I"gSometimes you want to be able to read the raw attribute data without having the column-determined ;TI"htypecast run its course first. That can be done by using the <tt><attribute>_before_type_cast</tt> ;TI"naccessors that all attributes have. For example, if your Account model has a <tt>balance</tt> attribute, ;TI"dyou can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.;T@o;
;[I"dThis is especially useful in validation situations where the user might supply a string for an ;TI"ginteger field and you want to display the original string back in an error message. Accessing the ;TI"Rattribute normally would typecast the string to 0, which isn't what you want.;T@S; ;
i;I"$Dynamic attribute-based finders;T@o;
;[
I"fDynamic attribute-based finders are a mildly deprecated way of getting (and/or creating) objects ;TI"_by simple queries without turning to SQL. They work by appending the name of an attribute ;TI"Bto <tt>find_by_</tt> like <tt>Person.find_by_user_name</tt>. ;TI"SInstead of writing <tt>Person.find_by(user_name: user_name)</tt>, you can use ;TI"2<tt>Person.find_by_user_name(user_name)</tt>.;T@o;
;[I"mIt's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an ;TI"KActiveRecord::RecordNotFound error if they do not return any records, ;TI"-like <tt>Person.find_by_last_name!</tt>.;T@o;
;[I"iIt's also possible to use multiple attributes in the same <tt>find_by_</tt> by separating them with ;TI"
"_and_".;T@o;;[I">Person.find_by(user_name: user_name, password: password)
;TI"VPerson.find_by_user_name_and_password(user_name, password) # with dynamic finder
;T;0o;
;[I"[It's even possible to call these dynamic finder methods on relations and named scopes.;T@o;;[I"4Payment.order("created_on").find_by_amount(50)
;T;0S; ;
i;I"JSaving arrays, hashes, and other non-mappable objects in text columns;T@o;
;[
I"[Active Record can serialize any object in text columns using YAML. To do so, you must ;TI"2specify this with a call to the class method ;TI"T{serialize}[rdoc-ref:AttributeMethods::Serialization::ClassMethods#serialize]. ;TI"bThis makes it possible to store arrays, hashes, and other non-mappable objects without doing ;TI"any additional work.;T@o;;[I"%class User < ActiveRecord::Base
;TI" serialize :preferences
;TI" end
;TI"
;TI"Vuser = User.create(preferences: { "background" => "black", "display" => large })
;TI"YUser.find(user.id).preferences # => { "background" => "black", "display" => large }
;T;0o;
;[I"\You can also specify a class option as the second parameter that'll raise an exception ;TI"Yif a serialized object is retrieved as a descendant of a class not in the hierarchy.;T@o;;[I"%class User < ActiveRecord::Base
;TI"$ serialize :preferences, Hash
;TI" end
;TI"
;TI":user = User.create(preferences: %w( one two three ))
;TI"JUser.find(user.id).preferences # raises SerializationTypeMismatch
;T;0o;
;[I"YWhen you specify a class option, the default value for that attribute will be a new ;TI"instance of that class.;T@o;;[I"%class User < ActiveRecord::Base
;TI"* serialize :preferences, OpenStruct
;TI" end
;TI"
;TI"user = User.new
;TI"*user.preferences.theme_color = "red"
;T;0S; ;
i;I"Single table inheritance;T@o;
;[I"LActive Record allows inheritance by storing the name of the class in a ;TI"Ocolumn that is named "type" by default. See ActiveRecord::Inheritance for ;TI"more details.;T@S; ;
i;I"9Connection to multiple databases in different models;T@o;
;[I"-Connections are usually created through ;TI"o{ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] and retrieved ;TI"dby ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this ;TI"`connection. But you can also set a class-specific connection. For example, if Course is an ;TI"tActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt> ;TI"Kand Course and all of its subclasses will use this connection instead.;T@o;
;[ I"\This feature is implemented by keeping a connection pool in ActiveRecord::Base that is ;TI"Da hash indexed by the class. If a connection is requested, the ;TI"f{ActiveRecord::Base.retrieve_connection}[rdoc-ref:ConnectionHandling#retrieve_connection] method ;TI"Wwill go up the class-hierarchy until a connection is found in the connection pool.;T@S; ;
i;I"Exceptions;T@o:RDoc::Markup::List:
@type:BULLET:@items[o:RDoc::Markup::ListItem:@label0;[o;
;[I"hActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.;To;;0;[o;
;[I":AdapterNotSpecified - The configuration hash used in ;TI"a{ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] ;TI"-didn't include an <tt>:adapter</tt> key.;To;;0;[o;
;[ I"9AdapterNotFound - The <tt>:adapter</tt> key used in ;TI"a{ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] ;TI"&specified a non-existent adapter ;TI",(or a bad spelling of an existing one).;To;;0;[o;
;[I"YAssociationTypeMismatch - The object assigned to the association wasn't of the type ;TI"-specified in the association definition.;To;;0;[o;
;[ I"\AttributeAssignmentError - An error occurred while doing a mass assignment through the ;TI"X{ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method. ;TI"cYou can inspect the +attribute+ property of the exception object to determine which attribute ;TI"triggered the error.;To;;0;[o;
;[I"DConnectionNotEstablished - No connection has been established. ;TI"uUse {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] before querying.;To;;0;[o;
;[
I"lMultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the ;TI"X{ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method. ;TI"BThe +errors+ property of this exception contains an array of ;TI"AttributeAssignmentError ;TI"Yobjects that should be inspected to determine which attributes triggered the errors.;To;;0;[o;
;[I"ZRecordInvalid - raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and ;TI"N{ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!] ;TI" when the record is invalid.;To;;0;[o;
;[ I"pRecordNotFound - No record responded to the {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] method. ;TI"hEither the row with the given ID doesn't exist or the row didn't meet the additional restrictions. ;TI"mSome {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] calls do not raise this exception to signal ;TI"Knothing was found, please check its documentation for further details.;To;;0;[o;
;[I"mSerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.;To;;0;[o;
;[I"rStatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.;T@o;
;[I"s*Note*: The attributes listed are class-level attributes (accessible from both the class and instance level). ;TI"sSo it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all ;TI"+instances in the current object space.;T:
@fileI"lib/active_record/base.rb;T:0@omit_headings_from_table_of_contents_below0;0;0[ [ [$[I" Core;To;;[ ;@\;0I"lib/active_record/base.rb;T[I"Persistence;To;;[ ;@\;0@d[I"ReadonlyAttributes;To;;[ ;@\;0@d[I"ModelSchema;To;;[ ;@\;0@d[I"Inheritance;To;;[ ;@\;0@d[I"Scoping;To;;[ ;@\;0@d[I"Sanitization;To;;[ ;@\;0@d[I"AttributeAssignment;To;;[ ;@\;0@d[I"ActiveModel::Conversion;To;;[ ;@\;0@d[I"Integration;To;;[ ;@\;0@d[I"Validations;To;;[ ;@\;0@d[I"CounterCache;To;;[ ;@\;0@d[I"Attributes;To;;[ ;@\;0@d[I"Locking::Optimistic;To;;[ ;@\;0@d[I"Locking::Pessimistic;To;;[ ;@\;0@d[I"AttributeMethods;To;;[ ;@\;0@d[I"Callbacks;To;;[ ;@\;0@d[I"Timestamp;To;;[ ;@\;0@d[I"Associations;To;;[ ;@\;0@d[I" ActiveModel::SecurePassword;To;;[ ;@\;0@d[I"AutosaveAssociation;To;;[ ;@\;0@d[I"NestedAttributes;To;;[ ;@\;0@d[I"Transactions;To;;[ ;@\;0@d[I"TouchLater;To;;[ ;@\;0@d[I"NoTouching;To;;[ ;@\;0@d[I"Reflection;To;;[ ;@\;0@d[I"Serialization;To;;[ ;@\;0@d[I"
Store;To;;[ ;@\;0@d[I"SecureToken;To;;[ ;@\;0@d[I"
SignedId;To;;[ ;@\;0@d[I"Suppressor;To;;[ ;@\;0@d[[I"
class;T[[:public[ [:protected[ [:private[ [I"
instance;T[[;[ [;[ [;[ [[I"ActiveModel::Naming;To;;[ ;@\;0@d[I"!ActiveSupport::Benchmarkable;To;;[ ;@\;0@d[I"&ActiveSupport::DescendantsTracker;To;;[ ;@\;0@d[I"ConnectionHandling;To;;[ ;@\;0@d[I"QueryCache::ClassMethods;To;;[ ;@\;0@d[I"
Querying;To;;[ ;@\;0@d[I"Translation;To;;[ ;@\;0@d[I"DynamicMatchers;To;;[ ;@\;0@d[I"DelegatedType;To;;[ ;@\;0@d[I"Explain;To;;[ ;@\;0@d[I" Enum;To;;[ ;@\;0@d[I"Delegation::DelegateCache;To;;[ ;@\;0@d[I"Aggregations::ClassMethods;To;;[ ;@\;0@d[U:RDoc::Context::Section[i 0o;;[ ;0;0[@\I"ActiveRecord;TcRDoc::NormalModule