diff options
Diffstat (limited to 'activerecord/lib')
71 files changed, 757 insertions, 663 deletions
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb index a2aea63bdd..be88c7c9e8 100644 --- a/activerecord/lib/active_record/aggregations.rb +++ b/activerecord/lib/active_record/aggregations.rb @@ -1,6 +1,6 @@ module ActiveRecord - # = Active Record Aggregations - module Aggregations # :nodoc: + # See ActiveRecord::Aggregations::ClassMethods for documentation + module Aggregations extend ActiveSupport::Concern def initialize_dup(*) # :nodoc: @@ -24,7 +24,7 @@ module ActiveRecord super end - # Active Record implements aggregation through a macro-like class method called +composed_of+ + # 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 @@ -120,12 +120,12 @@ module ActiveRecord # # 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 + # <tt>Money#exchange_to</tt> 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. + # 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 @@ -134,17 +134,17 @@ module ActiveRecord # # By default value objects are initialized by calling the <tt>new</tt> constructor of the value # class passing each of the mapped attributes, in the order specified by the <tt>:mapping</tt> - # option, as arguments. If the value class doesn't support this convention then +composed_of+ allows + # 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). + # 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 + # New values can be assigned to the value object using either another +NetAddr::CIDR+ object, a string # or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to meet # these requirements: # @@ -173,7 +173,7 @@ module ActiveRecord # # == Finding records by a value object # - # Once a +composed_of+ relationship is specified for a model, records can be loaded from the database + # 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 +balance_amount+ equal to 20 and +balance_currency+ equal to "USD": # @@ -186,7 +186,7 @@ module ActiveRecord # Options are: # * <tt>:class_name</tt> - Specifies the class name of the association. Use it only if that name # can't be inferred from the part id. So <tt>composed_of :address</tt> will by default be linked - # to the Address class, but if the real class name is CompanyAddress, you'll have to specify it + # to the Address class, but if the real class name is +CompanyAddress+, you'll have to specify it # with this option. # * <tt>:mapping</tt> - 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 diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index cf3e63b4a3..70f29debbc 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -149,7 +149,10 @@ module ActiveRecord class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc: end - class EagerLoadPolymorphicError < ActiveRecordError #:nodoc: + # This error is raised when trying to eager load a poloymorphic association using a JOIN. + # Eager loading polymorphic associations is only possible with + # {ActiveRecord::Relation#preload}[rdoc-ref:QueryMethods#preload]. + class EagerLoadPolymorphicError < ActiveRecordError def initialize(reflection = nil) if reflection super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}") @@ -298,7 +301,7 @@ module ActiveRecord # === A word of warning # # Don't create associations that have the same name as instance methods of - # <tt>ActiveRecord::Base</tt>. Since the association adds a method with that name to + # ActiveRecord::Base. Since the association adds a method with that name to # its model, it will override the inherited method and break things. # For instance, +attributes+ and +connection+ would be bad choices for association names. # @@ -360,7 +363,7 @@ module ActiveRecord # end # # If your model class is <tt>Project</tt>, the module is - # named <tt>Project::GeneratedAssociationMethods</tt>. The GeneratedAssociationMethods module is + # named <tt>Project::GeneratedAssociationMethods</tt>. The +GeneratedAssociationMethods+ module is # included in the model class immediately after the (anonymous) generated attributes methods # module, meaning an association will override the methods for an attribute with the same name. # @@ -368,12 +371,12 @@ module ActiveRecord # # 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 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. + # Use #has_one in the base, and #belongs_to in the associated model. # # class Employee < ActiveRecord::Base # has_one :office @@ -384,7 +387,7 @@ module ActiveRecord # # === One-to-many # - # Use +has_many+ in the base, and +belongs_to+ in the associated model. + # Use #has_many in the base, and #belongs_to in the associated model. # # class Manager < ActiveRecord::Base # has_many :employees @@ -397,7 +400,7 @@ module ActiveRecord # # There are two ways to build a many-to-many relationship. # - # The first way uses a +has_many+ association with the <tt>:through</tt> option and a join model, so + # The first way uses a #has_many association with the <tt>:through</tt> option and a join model, so # there are two stages of associations. # # class Assignment < ActiveRecord::Base @@ -413,7 +416,7 @@ module ActiveRecord # has_many :programmers, through: :assignments # end # - # For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table + # 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 @@ -425,13 +428,13 @@ module ActiveRecord # # 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 <tt>has_many :through</tt>. Use +has_and_belongs_to_many+ when working with legacy schemas or when + # use #has_many <tt>:through</tt>. 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? + # == 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. + # key, which goes on the table for the class declaring the #belongs_to relationship. # # class User < ActiveRecord::Base # # I reference an account. @@ -464,35 +467,35 @@ module ActiveRecord # there is some special behavior you should be aware of, mostly involving the saving of # associated objects. # - # You can set the <tt>:autosave</tt> option on a <tt>has_one</tt>, <tt>belongs_to</tt>, - # <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it + # You can set the <tt>:autosave</tt> 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 <tt>:autosave</tt> option is available at # AutosaveAssociation. # # === One-to-one associations # - # * Assigning an object to a +has_one+ association automatically saves that object and + # * 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 (<tt>new_record? == true</tt>). # * If either of these saves fail (due to one of the objects being invalid), an - # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is + # 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 <tt>build_association</tt> method (documented below). The object being + # * If you wish to assign an object to a #has_one association without saving it, + # use the <tt>#build_association</tt> 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 + # * 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 + # * 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 <tt>push</tt> or similar) # fails, then <tt>push</tt> returns +false+. # * If saving fails while replacing the collection (via <tt>association=</tt>), an - # <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is + # 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 # <tt>collection.build</tt> method (documented below). @@ -501,14 +504,14 @@ module ActiveRecord # # == Customizing the query # - # \Associations are built from <tt>Relation</tt>s, and you can use the <tt>Relation</tt> syntax + # \Associations are built from <tt>Relation</tt>s, 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 <tt>-> { ... }</tt> block you can use all of the usual <tt>Relation</tt> methods. + # Inside the <tt>-> { ... }</tt> block you can use all of the usual Relation methods. # # === Accessing the owner object # @@ -596,8 +599,8 @@ module ActiveRecord # # * <tt>record.association(:items).owner</tt> - Returns the object the association is part of. # * <tt>record.association(:items).reflection</tt> - Returns the reflection object that describes the association. - # * <tt>record.association(:items).target</tt> - 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+. + # * <tt>record.association(:items).target</tt> - 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 <tt>record</tt> as # above. In this case, you can access <tt>proxy_association</tt>. For example, @@ -609,7 +612,7 @@ module ActiveRecord # # Has Many associations can be configured with the <tt>:through</tt> 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, + # #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 @@ -626,7 +629,7 @@ module ActiveRecord # @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: + # You can also go through a #has_many association on the join model: # # class Firm < ActiveRecord::Base # has_many :clients @@ -646,7 +649,7 @@ module ActiveRecord # @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: + # Similarly you can go through a #has_one association on the join model: # # class Group < ActiveRecord::Base # has_many :users @@ -666,7 +669,7 @@ module ActiveRecord # @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 + # 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: # @@ -675,9 +678,9 @@ module ActiveRecord # # == Setting Inverses # - # If you are using a +belongs_to+ on the join model, it is a good idea to set the - # <tt>:inverse_of</tt> option on the +belongs_to+, which will mean that the following example - # works correctly (where <tt>tags</tt> is a +has_many+ <tt>:through</tt> association): + # If you are using a #belongs_to on the join model, it is a good idea to set the + # <tt>:inverse_of</tt> option on the #belongs_to, which will mean that the following example + # works correctly (where <tt>tags</tt> is a #has_many <tt>:through</tt> association): # # @post = Post.first # @tag = @post.tags.build name: "ruby" @@ -693,8 +696,8 @@ module ActiveRecord # # If you do not set the <tt>:inverse_of</tt> record, the association will # do its best to match itself up with the correct inverse. Automatic - # inverse detection only works on <tt>has_many</tt>, <tt>has_one</tt>, and - # <tt>belongs_to</tt> associations. + # inverse detection only works on #has_many, #has_one, and + # #belongs_to associations. # # Extra options on the associations, as defined in the # <tt>AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS</tt> constant, will @@ -757,7 +760,7 @@ module ActiveRecord # == 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 + # can be associated with. Rather, they specify an interface that a #has_many association # must adhere to. # # class Asset < ActiveRecord::Base @@ -841,7 +844,7 @@ module ActiveRecord # # Post.includes(:author).each do |post| # - # This references the name of the +belongs_to+ association that also used the <tt>:author</tt> + # This references the name of the #belongs_to association that also used the <tt>:author</tt> # symbol. After loading the posts, find will collect the +author_id+ from each one and load # all the referenced authors with one query. Doing so will cut down the number of queries # from 201 to 102. @@ -852,7 +855,7 @@ module ActiveRecord # # 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). + # named (except if some of the associations are polymorphic #belongs_to - see below). # # To include a deep hierarchy of associations, use a hash: # @@ -924,7 +927,7 @@ module ActiveRecord # 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 <tt>ActiveRecord::EagerLoadPolymorphicError</tt>. + # 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. # @@ -966,7 +969,7 @@ module ActiveRecord # 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 <tt>joins</tt> method, those table + # 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 ...") @@ -1059,7 +1062,7 @@ module ActiveRecord # # * does not work with <tt>:through</tt> associations. # * does not work with <tt>:polymorphic</tt> associations. - # * for +belongs_to+ associations +has_many+ inverse associations are ignored. + # * for #belongs_to associations #has_many inverse associations are ignored. # # For more information, see the documentation for the +:inverse_of+ option. # @@ -1067,7 +1070,7 @@ module ActiveRecord # # === Dependent associations # - # +has_many+, +has_one+ and +belongs_to+ associations support the <tt>:dependent</tt> option. + # #has_many, #has_one and #belongs_to associations support the <tt>:dependent</tt> option. # This allows you to specify that associated records should be deleted when the owner is # deleted. # @@ -1088,22 +1091,22 @@ module ActiveRecord # callbacks declared either before or after the <tt>:dependent</tt> option # can affect what it does. # - # Note that <tt>:dependent</tt> option is ignored for +has_one+ <tt>:through</tt> associations. + # Note that <tt>:dependent</tt> option is ignored for #has_one <tt>:through</tt> associations. # # === Delete or destroy? # - # +has_many+ and +has_and_belongs_to_many+ associations have the methods <tt>destroy</tt>, + # #has_many and #has_and_belongs_to_many associations have the methods <tt>destroy</tt>, # <tt>delete</tt>, <tt>destroy_all</tt> and <tt>delete_all</tt>. # - # For +has_and_belongs_to_many+, <tt>delete</tt> and <tt>destroy</tt> are the same: they + # For #has_and_belongs_to_many, <tt>delete</tt> and <tt>destroy</tt> are the same: they # cause the records in the join table to be removed. # - # For +has_many+, <tt>destroy</tt> and <tt>destroy_all</tt> will always call the <tt>destroy</tt> method of the + # For #has_many, <tt>destroy</tt> and <tt>destroy_all</tt> will always call the <tt>destroy</tt> method of the # record(s) being removed so that callbacks are run. However <tt>delete</tt> and <tt>delete_all</tt> will either # do the deletion according to the strategy specified by the <tt>:dependent</tt> option, or # if no <tt>:dependent</tt> 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+ <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete + # #has_many <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete # the join records, without running their callbacks). # # There is also a <tt>clear</tt> method which is the same as <tt>delete_all</tt>, except that @@ -1111,13 +1114,13 @@ module ActiveRecord # # === What gets deleted? # - # There is a potential pitfall here: +has_and_belongs_to_many+ and +has_many+ <tt>:through</tt> + # There is a potential pitfall here: #has_and_belongs_to_many and #has_many <tt>:through</tt> # 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 # <i>link</i> 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+ + # associated objects themselves. So with #has_and_belongs_to_many and #has_many # <tt>:through</tt>, 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 <tt>post.tags.delete(Tag.find_by(name: 'food'))</tt> @@ -1128,20 +1131,20 @@ module ActiveRecord # 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 + # #belongs_to. In other situations you are expected to perform operations directly on # either the associated records or the <tt>:through</tt> association. # - # With a regular +has_many+ there is no distinction between the "associated records" + # 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+ <tt>:through</tt>, if you want to delete the + # With #has_and_belongs_to_many and #has_many <tt>:through</tt>, if you want to delete the # associated records themselves, you can always do something along the lines of # <tt>person.tasks.each(&:destroy)</tt>. # - # == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt> + # == Type safety with ActiveRecord::AssociationTypeMismatch # # If you attempt to assign an object to an association that doesn't match the inferred - # or specified <tt>:class_name</tt>, you'll get an <tt>ActiveRecord::AssociationTypeMismatch</tt>. + # or specified <tt>:class_name</tt>, you'll get an ActiveRecord::AssociationTypeMismatch. # # == Options # @@ -1195,10 +1198,10 @@ module ActiveRecord # [collection.size] # Returns the number of associated objects. # [collection.find(...)] - # Finds an associated object according to the same rules as <tt>ActiveRecord::Base.find</tt>. + # 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 <tt>ActiveRecord::Base.exists?</tt>. + # 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 @@ -1209,7 +1212,7 @@ module ActiveRecord # 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 <tt>collection.create</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt> + # Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid # if the record is invalid. # # === Example @@ -1261,11 +1264,11 @@ module ActiveRecord # [:class_name] # Specify the class name of the association. Use it only if that name can't be inferred # from the association name. So <tt>has_many :products</tt> will by default be linked - # to the Product class, but if the real class name is SpecialProduct, you'll have to + # 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+ + # 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 <tt>:foreign_key</tt>. # [:foreign_type] # Specify the column used to store the associated object's type, if this is a polymorphic @@ -1289,20 +1292,20 @@ module ActiveRecord # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects. # # If using with the <tt>:through</tt> option, the association on the join model must be - # a +belongs_to+, and the records which get deleted are the join records, rather than + # a #belongs_to, and the records which get deleted are the join records, rather than # the associated records. # [:counter_cache] # This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option, - # when you customized the name of your <tt>:counter_cache</tt> on the <tt>belongs_to</tt> association. + # when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association. # [:as] - # Specifies a polymorphic interface (See <tt>belongs_to</tt>). + # 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 <tt>:through</tt> associations. Options for <tt>:class_name</tt>, # <tt>:primary_key</tt> and <tt>:foreign_key</tt> 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 + # If the association on the join model is a #belongs_to, the collection can be modified # and the records on the <tt>:through</tt> model will be automatically created and removed # as appropriate. Otherwise, the collection is read-only, so you should manipulate the # <tt>:through</tt> association directly. @@ -1313,13 +1316,13 @@ module ActiveRecord # the appropriate join model records when they are saved. (See the 'Association Join Models' # section above.) # [:source] - # Specifies the source association name used by <tt>has_many :through</tt> queries. + # Specifies the source association name used by #has_many <tt>:through</tt> queries. # Only use it if the name cannot be inferred from the association. # <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or # <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given. # [:source_type] - # Specifies type of the source association used by <tt>has_many :through</tt> queries where the source - # association is a polymorphic +belongs_to+. + # Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source + # association is a polymorphic #belongs_to. # [:validate] # If +false+, don't validate the associated objects when saving the parent object. true by default. # [:autosave] @@ -1329,10 +1332,11 @@ module ActiveRecord # +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 <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. + # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets + # <tt>:autosave</tt> to <tt>true</tt>. # [:inverse_of] - # Specifies the name of the <tt>belongs_to</tt> association on the associated object - # that is the inverse of this <tt>has_many</tt> association. Does not work in combination + # Specifies the name of the #belongs_to association on the associated object + # that is the inverse of this #has_many association. Does not work in combination # with <tt>:through</tt> or <tt>:as</tt> options. # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail. # [:extend] @@ -1356,8 +1360,8 @@ module ActiveRecord # 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+. + # 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: # @@ -1379,7 +1383,7 @@ module ActiveRecord # 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 <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt> + # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid # if the record is invalid. # # === Example @@ -1424,7 +1428,7 @@ module ActiveRecord # Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> 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 + # 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 <tt>:foreign_key</tt>. # [:foreign_type] # Specify the column used to store the associated object's type, if this is a polymorphic @@ -1435,20 +1439,20 @@ module ActiveRecord # [: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 <tt>belongs_to</tt>). + # Specifies a polymorphic interface (See #belongs_to). # [:through] # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>, # <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the - # source reflection. You can only use a <tt>:through</tt> query through a <tt>has_one</tt> - # or <tt>belongs_to</tt> association on the join model. + # source reflection. You can only use a <tt>:through</tt> query through a #has_one + # or #belongs_to association on the join model. # [:source] - # Specifies the source association name used by <tt>has_one :through</tt> queries. + # Specifies the source association name used by #has_one <tt>:through</tt> queries. # Only use it if the name cannot be inferred from the association. # <tt>has_one :favorite, through: :favorites</tt> will look for a # <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given. # [:source_type] - # Specifies type of the source association used by <tt>has_one :through</tt> queries where the source - # association is a polymorphic +belongs_to+. + # Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source + # association is a polymorphic #belongs_to. # [:validate] # If +false+, don't validate the associated object when saving the parent object. +false+ by default. # [:autosave] @@ -1456,10 +1460,11 @@ module ActiveRecord # 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 <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. + # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets + # <tt>:autosave</tt> to <tt>true</tt>. # [:inverse_of] - # Specifies the name of the <tt>belongs_to</tt> association on the associated object - # that is the inverse of this <tt>has_one</tt> association. Does not work in combination + # Specifies the name of the #belongs_to association on the associated object + # that is the inverse of this #has_one association. Does not work in combination # with <tt>:through</tt> or <tt>:as</tt> options. # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail. # [:required] @@ -1485,8 +1490,8 @@ module ActiveRecord # 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+. + # 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: @@ -1506,7 +1511,7 @@ module ActiveRecord # 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 <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt> + # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid # if the record is invalid. # # === Example @@ -1553,12 +1558,12 @@ module ActiveRecord # [:dependent] # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. - # This option should not be specified when <tt>belongs_to</tt> is used in conjunction with - # a <tt>has_many</tt> relationship on another class because of the potential to leave + # 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 +increment_counter+ - # and +decrement_counter+. The counter cache is incremented when an object of this + # 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 <tt>#{table_name}_count</tt> (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 @@ -1580,14 +1585,15 @@ module ActiveRecord # If false, never save or destroy the associated object. # By default, only save the associated object if it's a new record. # - # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. + # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for + # sets <tt>:autosave</tt> to <tt>true</tt>. # [: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. # [:inverse_of] - # Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated - # object that is the inverse of this <tt>belongs_to</tt> association. Does not work in + # Specifies the name of the #has_one or #has_many association on the associated + # object that is the inverse of this #belongs_to association. Does not work in # combination with the <tt>:polymorphic</tt> options. # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail. # [:optional] @@ -1677,10 +1683,10 @@ module ActiveRecord # [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 <tt>ActiveRecord::Base.find</tt>. + # 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 <tt>ActiveRecord::Base.exists?</tt>. + # 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. @@ -1744,16 +1750,16 @@ module ActiveRecord # [:join_table] # Specify the name of the join table if the default based on lexical order isn't what you want. # <b>WARNING:</b> 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. + # 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 + # a #has_and_belongs_to_many association to Project will use "person_id" as the # default <tt>:foreign_key</tt>. # [: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, + # So if a Person class makes a #has_and_belongs_to_many association to Project, # the association will use "project_id" as the default <tt>:association_foreign_key</tt>. # [:readonly] # If true, all the associated objects are readonly through the association. @@ -1765,7 +1771,8 @@ module ActiveRecord # If false, never save or destroy the associated objects. # By default, only save associated objects that are new records. # - # Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>. + # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets + # <tt>:autosave</tt> to <tt>true</tt>. # # Option examples: # has_and_belongs_to_many :projects diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index ba1b1814d1..d0534056d9 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -9,7 +9,7 @@ # - CollectionAssociation # - HasManyAssociation -module ActiveRecord::Associations::Builder +module ActiveRecord::Associations::Builder # :nodoc: class Association #:nodoc: class << self attr_accessor :extensions diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index 6e4a53f7fb..dae468ba54 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -1,4 +1,4 @@ -module ActiveRecord::Associations::Builder +module ActiveRecord::Associations::Builder # :nodoc: class BelongsTo < SingularAssociation #:nodoc: def self.macro :belongs_to diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb index 2ff67f904d..56a8dc4e18 100644 --- a/activerecord/lib/active_record/associations/builder/collection_association.rb +++ b/activerecord/lib/active_record/associations/builder/collection_association.rb @@ -2,7 +2,7 @@ require 'active_record/associations' -module ActiveRecord::Associations::Builder +module ActiveRecord::Associations::Builder # :nodoc: class CollectionAssociation < Association #:nodoc: CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove] diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb index b18d99d54e..a5c9f1666e 100644 --- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb @@ -1,9 +1,9 @@ -module ActiveRecord::Associations::Builder +module ActiveRecord::Associations::Builder # :nodoc: class HasAndBelongsToMany # :nodoc: - class JoinTableResolver + class JoinTableResolver # :nodoc: KnownTable = Struct.new :join_table - class KnownClass + class KnownClass # :nodoc: def initialize(lhs_class, rhs_class_name) @lhs_class = lhs_class @rhs_class_name = rhs_class_name diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb index 1c1b47bd56..f71b10120f 100644 --- a/activerecord/lib/active_record/associations/builder/has_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_many.rb @@ -1,4 +1,4 @@ -module ActiveRecord::Associations::Builder +module ActiveRecord::Associations::Builder # :nodoc: class HasMany < CollectionAssociation #:nodoc: def self.macro :has_many diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb index a272d3c781..9d64ae877b 100644 --- a/activerecord/lib/active_record/associations/builder/has_one.rb +++ b/activerecord/lib/active_record/associations/builder/has_one.rb @@ -1,4 +1,4 @@ -module ActiveRecord::Associations::Builder +module ActiveRecord::Associations::Builder # :nodoc: class HasOne < SingularAssociation #:nodoc: def self.macro :has_one diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb index 42542f188e..58a9c8ff24 100644 --- a/activerecord/lib/active_record/associations/builder/singular_association.rb +++ b/activerecord/lib/active_record/associations/builder/singular_association.rb @@ -1,6 +1,6 @@ # This class is inherited by the has_one and belongs_to association classes -module ActiveRecord::Associations::Builder +module ActiveRecord::Associations::Builder # :nodoc: class SingularAssociation < Association #:nodoc: def self.valid_options(options) super + [:dependent, :primary_key, :inverse_of, :required] diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb index 9994b72158..fe693cfbb6 100644 --- a/activerecord/lib/active_record/associations/collection_proxy.rb +++ b/activerecord/lib/active_record/associations/collection_proxy.rb @@ -112,7 +112,7 @@ module ActiveRecord end # Finds an object in the collection responding to the +id+. Uses the same - # rules as <tt>ActiveRecord::Base.find</tt>. Returns <tt>ActiveRecord::RecordNotFound</tt> + # rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound # error if the object cannot be found. # # class Person < ActiveRecord::Base @@ -171,27 +171,27 @@ module ActiveRecord @association.first(*args) end - # Same as +first+ except returns only the second record. + # Same as #first except returns only the second record. def second(*args) @association.second(*args) end - # Same as +first+ except returns only the third record. + # Same as #first except returns only the third record. def third(*args) @association.third(*args) end - # Same as +first+ except returns only the fourth record. + # Same as #first except returns only the fourth record. def fourth(*args) @association.fourth(*args) end - # Same as +first+ except returns only the fifth record. + # Same as #first except returns only the fifth record. def fifth(*args) @association.fifth(*args) end - # Same as +first+ except returns only the forty second record. + # Same as #first except returns only the forty second record. # Also known as accessing "the reddit". def forty_two(*args) @association.forty_two(*args) @@ -315,7 +315,7 @@ module ActiveRecord @association.create(attributes, &block) end - # Like +create+, except that if the record is invalid, raises an exception. + # Like #create, except that if the record is invalid, raises an exception. # # class Person # has_many :pets @@ -332,8 +332,8 @@ module ActiveRecord end # Add 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+ + # to the association's primary key. Since #<< flattens its argument list and + # inserts each record, +push+ and #concat behave identically. Returns +self+ # so method calls may be chained. # # class Person < ActiveRecord::Base @@ -389,7 +389,7 @@ module ActiveRecord # 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 + # For <tt>has_many :through</tt> associations, the default deletion strategy is # +:delete_all+. # # For +has_many+ associations, the default deletion strategy is +:nullify+. @@ -424,7 +424,7 @@ module ActiveRecord # # #<Pet id: 3, name: "Choo-Choo", person_id: nil> # # ] # - # Both +has_many+ and +has_many :through+ dependencies default to the + # Both +has_many+ and <tt>has_many :through</tt> 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. # @@ -500,7 +500,7 @@ module ActiveRecord # then it will follow the default strategy. Returns an array with the # deleted records. # - # For +has_many :through+ associations, the default deletion strategy is + # For <tt>has_many :through</tt> associations, the default deletion strategy is # +:delete_all+. # # For +has_many+ associations, the default deletion strategy is +:nullify+. diff --git a/activerecord/lib/active_record/associations/foreign_association.rb b/activerecord/lib/active_record/associations/foreign_association.rb index fe48ecec29..3ceec0ee46 100644 --- a/activerecord/lib/active_record/associations/foreign_association.rb +++ b/activerecord/lib/active_record/associations/foreign_association.rb @@ -1,5 +1,5 @@ module ActiveRecord::Associations - module ForeignAssociation + module ForeignAssociation # :nodoc: def foreign_key_present? if reflection.klass.primary_key owner.attribute_present?(reflection.active_record_primary_key) diff --git a/activerecord/lib/active_record/attribute/user_provided_default.rb b/activerecord/lib/active_record/attribute/user_provided_default.rb index fb8ad9163e..6dbd92ce28 100644 --- a/activerecord/lib/active_record/attribute/user_provided_default.rb +++ b/activerecord/lib/active_record/attribute/user_provided_default.rb @@ -2,7 +2,7 @@ require 'active_record/attribute' module ActiveRecord class Attribute # :nodoc: - class UserProvidedDefault < FromUser + class UserProvidedDefault < FromUser # :nodoc: def initialize(name, value, type, database_default) super(name, value, type, database_default) end diff --git a/activerecord/lib/active_record/attribute_assignment.rb b/activerecord/lib/active_record/attribute_assignment.rb index 45fdcaa1cd..a6d81c82b4 100644 --- a/activerecord/lib/active_record/attribute_assignment.rb +++ b/activerecord/lib/active_record/attribute_assignment.rb @@ -5,7 +5,7 @@ module ActiveRecord extend ActiveSupport::Concern include ActiveModel::AttributeAssignment - # Alias for `assign_attributes`. See +ActiveModel::AttributeAssignment+. + # Alias for ActiveModel::AttributeAssignment#assign_attributes. See ActiveModel::AttributeAssignment. def attributes=(attributes) assign_attributes(attributes) end diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index ca6ba18fe0..cbdd4950a6 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -96,7 +96,7 @@ module ActiveRecord end end - # Raises an <tt>ActiveRecord::DangerousAttributeError</tt> exception when an + # Raises an ActiveRecord::DangerousAttributeError exception when an # \Active \Record method is defined in the model, otherwise +false+. # # class Person < ActiveRecord::Base @@ -346,7 +346,7 @@ module ActiveRecord # # Note: +:id+ is always present. # - # Alias for the <tt>read_attribute</tt> method. + # Alias for the #read_attribute method. # # class Person < ActiveRecord::Base # belongs_to :organization @@ -364,7 +364,7 @@ module ActiveRecord end # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. - # (Alias for the protected <tt>write_attribute</tt> method). + # (Alias for the protected #write_attribute method). # # class Person < ActiveRecord::Base # end diff --git a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb index 56c1898551..1db6776688 100644 --- a/activerecord/lib/active_record/attribute_methods/before_type_cast.rb +++ b/activerecord/lib/active_record/attribute_methods/before_type_cast.rb @@ -2,7 +2,7 @@ module ActiveRecord module AttributeMethods # = Active Record Attribute Methods Before Type Cast # - # <tt>ActiveRecord::AttributeMethods::BeforeTypeCast</tt> provides a way to + # ActiveRecord::AttributeMethods::BeforeTypeCast provides a way to # read the value of the attributes before typecasting and deserialization. # # class Task < ActiveRecord::Base diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index c28374e4ab..0d5cb8b37c 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -5,7 +5,7 @@ module ActiveRecord module PrimaryKey extend ActiveSupport::Concern - # Returns this record's primary key value wrapped in an Array if one is + # Returns this record's primary key value wrapped in an array if one is # available. def to_key sync_with_transaction_state @@ -108,7 +108,7 @@ module ActiveRecord # self.primary_key = 'sysid' # end # - # You can also define the +primary_key+ method yourself: + # You can also define the #primary_key method yourself: # # class Project < ActiveRecord::Base # def self.primary_key diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index 60eecab0d0..65978aea2a 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -9,7 +9,7 @@ module ActiveRecord # 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 <tt>SerializationTypeMismatch</tt> will be raised. + # Otherwise SerializationTypeMismatch will be raised. # # Empty objects as <tt>{}</tt>, in the case of +Hash+, or <tt>[]</tt>, in the case of # +Array+, will always be persisted as null. @@ -17,7 +17,7 @@ module ActiveRecord # 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 + # objects transparently. There is no need to use #serialize in this # case. # # For more complex cases, such as conversion to or from your application diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb index a573f76a8e..5d0405c3be 100644 --- a/activerecord/lib/active_record/attributes.rb +++ b/activerecord/lib/active_record/attributes.rb @@ -15,7 +15,7 @@ module ActiveRecord # 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::QueryMethods#where. This will let you use + # {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. # @@ -87,7 +87,7 @@ module ActiveRecord # 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. + # \Attributes do not need to be backed by a database column. # # class MyModel < ActiveRecord::Base # attribute :my_string, :string @@ -119,7 +119,7 @@ module ActiveRecord # # class MoneyType < ActiveRecord::Type::Integer # def cast(value) - # if value.include?('$') + # if !value.kind_of(Numeric) && value.include?('$') # price_in_dollars = value.gsub(/\$/, '').to_f # super(price_in_dollars * 100) # else @@ -144,9 +144,9 @@ module ActiveRecord # to be referenced by a symbol, see ActiveRecord::Type.register. You can # also pass a type object directly, in place of a symbol. # - # ==== Querying + # ==== \Querying # - # When ActiveRecord::QueryMethods#where is called, it will + # 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: # diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index d0de42d27c..d35bc3e794 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -1,10 +1,10 @@ module ActiveRecord # = Active Record Autosave Association # - # +AutosaveAssociation+ is a module that takes care of automatically saving + # 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 <tt>marked_for_destruction?</tt>). + # (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 @@ -125,7 +125,6 @@ module ActiveRecord # Now it _is_ removed from the database: # # Comment.find_by(id: id).nil? # => true - module AutosaveAssociation extend ActiveSupport::Concern @@ -143,7 +142,7 @@ module ActiveRecord Associations::Builder::Association.extensions << AssociationBuilderExtension end - module ClassMethods + module ClassMethods # :nodoc: private def define_non_cyclic_method(name, &block) @@ -353,7 +352,7 @@ module ActiveRecord # <tt>:autosave</tt> is enabled on the association. # # In addition, it destroys all children that were marked for destruction - # with mark_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. @@ -396,7 +395,7 @@ module ActiveRecord # on the association. # # In addition, it will destroy the association if it was marked for - # destruction with mark_for_destruction. + # 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. diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 4b66d8cd36..9782e58299 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -170,7 +170,7 @@ module ActiveRecord #:nodoc: # <tt>Person.find_by_user_name(user_name)</tt>. # # It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an - # <tt>ActiveRecord::RecordNotFound</tt> error if they do not return any records, + # ActiveRecord::RecordNotFound error if they do not return any records, # like <tt>Person.find_by_last_name!</tt>. # # It's also possible to use multiple attributes in the same find by separating them with "_and_". @@ -185,7 +185,8 @@ module ActiveRecord #:nodoc: # == 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+. + # 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. # @@ -225,39 +226,47 @@ module ActiveRecord #:nodoc: # # == Connection to multiple databases in different models # - # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved + # 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 <tt>Course.establish_connection</tt> # 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 retrieve_connection method + # 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 <tt>establish_connection</tt> didn't include an - # <tt>:adapter</tt> key. - # * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a - # non-existent adapter + # * AdapterNotSpecified - The configuration hash used in + # {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] + # didn't include an <tt>:adapter</tt> key. + # * AdapterNotFound - The <tt>:adapter</tt> 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 - # <tt>attributes=</tt> method. + # {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 <tt>establish_connection</tt> - # before querying. + # * 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 - # <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of + # {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 <tt>save!</tt> and <tt>create!</tt> when the record is invalid. - # * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist - # or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal + # * 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. diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index ccdbebbc77..bfedc4af3f 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -1,11 +1,11 @@ module ActiveRecord - # = Active Record Callbacks + # = Active Record \Callbacks # - # Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic + # \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 +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 <tt>Base#save</tt> call for a new record: + # 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: # # * (-) <tt>save</tt> # * (-) <tt>valid</tt> @@ -20,7 +20,7 @@ module ActiveRecord # * (7) <tt>after_commit</tt> # # Also, an <tt>after_rollback</tt> callback can be configured to be triggered whenever a rollback is issued. - # Check out <tt>ActiveRecord::Transactions</tt> for more details about <tt>after_commit</tt> and + # Check out ActiveRecord::Transactions for more details about <tt>after_commit</tt> and # <tt>after_rollback</tt>. # # Additionally, an <tt>after_touch</tt> callback is triggered whenever an @@ -31,7 +31,7 @@ module ActiveRecord # 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 <tt>Base#save</tt> for an existing record is similar, + # Active Record life cycle. The sequence for calling {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] for an existing record is similar, # except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback. # # Examples: @@ -193,8 +193,9 @@ module ActiveRecord # == <tt>before_validation*</tt> returning statements # # If the +before_validation+ callback throws +:abort+, the process will be - # aborted and <tt>Base#save</tt> will return +false+. If Base#save! is called it will raise a - # <tt>ActiveRecord::RecordInvalid</tt> exception. Nothing will be appended to the errors object. + # 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 a ActiveRecord::RecordInvalid exception. + # Nothing will be appended to the errors object. # # == Canceling callbacks # @@ -223,7 +224,8 @@ module ActiveRecord # end # # In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available - # because the +destroy+ callback gets executed first. You can use the +prepend+ option on the +before_destroy+ callback to avoid this. + # 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 @@ -238,21 +240,21 @@ module ActiveRecord # # This way, the +before_destroy+ gets executed before the <tt>dependent: destroy</tt> is called, and the data is still available. # - # == Transactions + # == \Transactions # - # The entire callback chain of a +save+, <tt>save!</tt>, or +destroy+ call runs - # within a transaction. That includes <tt>after_*</tt> hooks. If everything - # goes fine a COMMIT is executed once the chain has been completed. + # 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 <tt>after_*</tt> hooks. + # If everything goes fine a COMMIT is executed once the chain has been completed. # # If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You # can also trigger a ROLLBACK raising an exception in any of the callbacks, # including <tt>after_*</tt> hooks. Note, however, that in that case the client - # needs to be aware of it because an ordinary +save+ will raise such exception + # 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 <tt>_*_callbacks</tt> method on an object. ActiveModel Callbacks support + # The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. Active Model \Callbacks support # <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property # defines what part of the chain the callback runs in. # @@ -278,7 +280,7 @@ module ActiveRecord :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback ] - module ClassMethods + module ClassMethods # :nodoc: include ActiveModel::Callbacks end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index b579bc1e93..0d850c7625 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -10,8 +10,9 @@ module ActiveRecord end # Raised when a pool was unable to get ahold of all its connections - # to perform a "group" action such as +ConnectionPool#disconnect!+ - # or +ConnectionPool#clear_reloadable_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 @@ -37,17 +38,18 @@ module ActiveRecord # Connections can be obtained and used from a connection pool in several # ways: # - # 1. Simply use ActiveRecord::Base.connection as with Active Record 2.1 and + # 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!. This will be the - # default behavior for Active Record when used in conjunction with + # {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. You are responsible for + # {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). - # 3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which + # {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. # @@ -140,7 +142,7 @@ module ActiveRecord # become available. # # Raises: - # - ConnectionTimeoutError if +timeout+ is given and no element + # - ActiveRecord::ConnectionTimeoutError if +timeout+ is given and no element # becomes available within +timeout+ seconds, def poll(timeout = nil) synchronize { internal_poll(timeout) } @@ -331,7 +333,7 @@ module ActiveRecord # of the cache is to speed-up +connection+ method, it is not the authoritative # registry of which thread owns which connection, that is tracked by # +connection.owner+ attr on each +connection+ instance. - # The invariant works like this: if there is mapping of +thread => conn+, + # The invariant works like this: if there is mapping of <tt>thread => conn</tt>, # then that +thread+ does indeed own that +conn+, however an absence of a such # mapping does not mean that the +thread+ doesn't own the said connection, in # that case +conn.owner+ attr should be consulted. @@ -342,7 +344,7 @@ module ActiveRecord @connections = [] @automatic_reconnect = true - # Connection pool allows for concurrent (outside the main `synchronize` section) + # Connection pool allows for concurrent (outside the main +synchronize+ section) # establishment of new connections. This variable tracks the number of threads # currently in the process of independently establishing connections to the DB. @now_connecting = 0 @@ -406,9 +408,9 @@ module ActiveRecord # Disconnects all connections in the pool, and clears the pool. # # Raises: - # - +ExclusiveConnectionTimeoutError+ if unable to gain ownership of all + # - 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). + # <tt>spec.config[:checkout_timeout] * 2</tt> seconds). def disconnect(raise_on_acquisition_timeout = true) with_exclusively_acquired_all_connections(raise_on_acquisition_timeout) do synchronize do @@ -426,7 +428,7 @@ module ActiveRecord # # 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), the pool is forcefully + # <tt>spec.config[:checkout_timeout] * 2</tt> seconds), the pool is forcefully # disconnected without any regard for other connection owning threads. def disconnect! disconnect(false) @@ -436,9 +438,9 @@ module ActiveRecord # require reloading. # # Raises: - # - +ExclusiveConnectionTimeoutError+ if unable to gain ownership of all + # - 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). + # <tt>spec.config[:checkout_timeout] * 2</tt> seconds). def clear_reloadable_connections(raise_on_acquisition_timeout = true) num_new_conns_required = 0 @@ -474,7 +476,7 @@ module ActiveRecord # # 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), the pool forcefully + # <tt>spec.config[:checkout_timeout] * 2</tt> seconds), the pool forcefully # clears the cache and reloads connections without any regard for other # connection owning threads. def clear_reloadable_connections! @@ -494,7 +496,7 @@ module ActiveRecord # Returns: an AbstractAdapter object. # # Raises: - # - ConnectionTimeoutError: no connection can be obtained from the pool. + # - ActiveRecord::ConnectionTimeoutError no connection can be obtained from the pool. def checkout(checkout_timeout = @checkout_timeout) checkout_and_verify(acquire_connection(checkout_timeout)) end @@ -503,7 +505,7 @@ module ActiveRecord # no longer need this connection. # # +conn+: an AbstractAdapter object, which was obtained by earlier by - # calling +checkout+ on this pool. + # calling #checkout on this pool. def checkin(conn) synchronize do remove_connection_from_thread_cache conn @@ -516,7 +518,7 @@ module ActiveRecord end end - # Remove a connection from the connection pool. The connection will + # 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(conn) needs_new_connection = false @@ -547,7 +549,7 @@ module ActiveRecord bulk_make_new_connections(1) if needs_new_connection end - # Recover lost connections for the pool. A lost connection can occur if + # 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 @@ -628,10 +630,10 @@ module ActiveRecord end end rescue ExclusiveConnectionTimeoutError - # `raise_on_acquisition_timeout == false` means we are directed to ignore any + # <tt>raise_on_acquisition_timeout == false</tt> means we are directed to ignore any # timeouts and are expected to just give up: we've obtained as many connections # as possible, note that in a case like that we don't return any of the - # `newly_checked_out` connections. + # +newly_checked_out+ connections. if raise_on_acquisition_timeout release_newly_checked_out = true @@ -688,18 +690,18 @@ module ActiveRecord # queue for a connection to become available. # # Raises: - # - ConnectionTimeoutError if a connection could not be acquired + # - 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(checkout_timeout) - # NOTE: we rely on `@available.poll` and `try_to_checkout_new_connection` to - # `conn.lease` the returned connection (and to do this in a `synchronized` + # NOTE: we rely on +@available.poll+ and +try_to_checkout_new_connection+ to + # +conn.lease+ the returned connection (and to do this in a +synchronized+ # section), this is not the cleanest implementation, as ideally we would - # `synchronize { conn.lease }` in this method, but by leaving it to `@available.poll` - # and `try_to_checkout_new_connection` we can piggyback on `synchronize` sections - # of the said methods and avoid an additional `synchronize` overhead. + # <tt>synchronize { conn.lease }</tt> in this method, but by leaving it to +@available.poll+ + # and +try_to_checkout_new_connection+ we can piggyback on +synchronize+ sections + # of the said methods and avoid an additional +synchronize+ overhead. if conn = @available.poll || try_to_checkout_new_connection conn else @@ -857,6 +859,8 @@ module ActiveRecord end # Clears the cache which maps classes. + # + # See ConnectionPool#clear_reloadable_connections! for details. def clear_reloadable_connections! connection_pool_list.each(&:clear_reloadable_connections!) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb index 30b2fca2ca..6711049588 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb @@ -19,8 +19,8 @@ module ActiveRecord # Returns the maximum allowed length for an index name. This # limit is enforced by \Rails and is less than or equal to - # <tt>index_name_length</tt>. The gap between - # <tt>index_name_length</tt> is to allow internal \Rails + # #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 index_name_length diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index 107806cd93..dbacf56795 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -192,7 +192,7 @@ module ActiveRecord # * http://www.postgresql.org/docs/current/static/transaction-iso.html # * https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html # - # An <tt>ActiveRecord::TransactionIsolationError</tt> will be raised if: + # An ActiveRecord::TransactionIsolationError will be raised if: # # * The adapter does not support setting the isolation level # * You are joining an existing open transaction diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb index 2c7409b2dc..9ec0a67c8f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb @@ -43,9 +43,9 @@ module ActiveRecord # If you are having to call this function, you are likely doing something # wrong. The column does not have sufficient type information if the user # provided a custom type on the class level either explicitly (via - # `attribute`) or implicitly (via `serialize`, - # `time_zone_aware_attributes`). In almost all cases, the sql type should - # only be used to change quoting behavior, when the primitive to + # Attributes::ClassMethods#attribute) or implicitly (via + # AttributeMethods::Serialization::ClassMethods#serialize, +time_zone_aware_attributes+). + # In almost all cases, the sql type should only be used to change quoting behavior, when the primitive to # represent the type doesn't sufficiently reflect the differences # (varchar vs binary) for example. The type used to get this primitive # should have been provided before reaching the connection adapter. @@ -58,7 +58,7 @@ module ActiveRecord end end - # See docs for +type_cast_from_column+ + # See docs for #type_cast_from_column def lookup_cast_type_from_column(column) # :nodoc: lookup_cast_type(column.sql_type) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 10329de5f4..bceda5abd9 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -123,23 +123,29 @@ module ActiveRecord end def foreign_key_options - as_options(foreign_key) + as_options(foreign_key).merge(column: column_name) end def columns - result = [["#{name}_id", type, options]] + result = [[column_name, type, options]] if polymorphic result.unshift(["#{name}_type", :string, polymorphic_options]) end result end + def column_name + "#{name}_id" + end + def column_names columns.map(&:first) end def foreign_table_name - Base.pluralize_table_names ? name.to_s.pluralize : name + foreign_key_options.fetch(:to_table) do + Base.pluralize_table_names ? name.to_s.pluralize : name + end end end @@ -181,7 +187,7 @@ module ActiveRecord # 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+ + # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table] # is actually of this type: # # class SomeMigration < ActiveRecord::Migration @@ -197,7 +203,7 @@ module ActiveRecord # end # # The table definitions - # The Columns are stored as a ColumnDefinition in the +columns+ attribute. + # The Columns are stored as a ColumnDefinition in the #columns attribute. class TableDefinition include ColumnMethods @@ -315,7 +321,7 @@ module ActiveRecord # # == Short-hand examples # - # Instead of calling +column+ directly, you can also work with the short-hand definitions for the default types. + # 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. # @@ -347,7 +353,8 @@ module ActiveRecord # TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type # column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of # options, these will be used when creating the <tt>_type</tt> column. The <tt>:index</tt> option - # will also create an index, similar to calling <tt>add_index</tt>. So what can be written like this: + # 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 @@ -398,7 +405,7 @@ module ActiveRecord end # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and - # <tt>:updated_at</tt> to the table. See SchemaStatements#add_timestamps + # <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps] # # t.timestamps null: false def timestamps(*args) @@ -415,7 +422,7 @@ module ActiveRecord # t.references(:user) # t.belongs_to(:supplier, foreign_key: true) # - # See SchemaStatements#add_reference for details of the options you can use. + # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use. def references(*args, **options) args.each do |col| ReferenceDefinition.new(col, **options).add_to(self) @@ -487,7 +494,7 @@ module ActiveRecord end # Represents an SQL table in an abstract way for updating a table. - # Also see TableDefinition and SchemaStatements#create_table + # Also see TableDefinition and {connection.create_table}[rdoc-ref:SchemaStatements#create_table] # # Available transformations are: # @@ -544,7 +551,7 @@ module ActiveRecord # # t.string(:name) unless t.column_exists?(:name, :string) # - # See SchemaStatements#column_exists? + # See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?] def column_exists?(column_name, type = nil, options = {}) @base.column_exists?(name, column_name, type, options) end @@ -556,7 +563,7 @@ module ActiveRecord # t.index([:branch_id, :party_id], unique: true) # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party') # - # See SchemaStatements#add_index for details of the options you can use. + # See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use. def index(column_name, options = {}) @base.add_index(name, column_name, options) end @@ -567,7 +574,7 @@ module ActiveRecord # t.index(:branch_id) # end # - # See SchemaStatements#index_exists? + # See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?] def index_exists?(column_name, options = {}) @base.index_exists?(name, column_name, options) end @@ -576,7 +583,7 @@ module ActiveRecord # # t.rename_index(:user_id, :account_id) # - # See SchemaStatements#rename_index + # See {connection.rename_index}[rdoc-ref:SchemaStatements#rename_index] def rename_index(index_name, new_index_name) @base.rename_index(name, index_name, new_index_name) end @@ -585,7 +592,7 @@ module ActiveRecord # # t.timestamps(null: false) # - # See SchemaStatements#add_timestamps + # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps] def timestamps(options = {}) @base.add_timestamps(name, options) end @@ -606,7 +613,7 @@ module ActiveRecord # t.change_default(:authorized, 1) # t.change_default(:status, from: nil, to: "draft") # - # See SchemaStatements#change_column_default + # See {connection.change_column_default}[rdoc-ref:SchemaStatements#change_column_default] def change_default(column_name, default_or_changes) @base.change_column_default(name, column_name, default_or_changes) end @@ -616,7 +623,7 @@ module ActiveRecord # t.remove(:qualification) # t.remove(:qualification, :experience) # - # See SchemaStatements#remove_columns + # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns] def remove(*column_names) @base.remove_columns(name, *column_names) end @@ -627,7 +634,7 @@ module ActiveRecord # t.remove_index(column: [:branch_id, :party_id]) # t.remove_index(name: :by_branch_party) # - # See SchemaStatements#remove_index + # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index] def remove_index(options = {}) @base.remove_index(name, options) end @@ -636,7 +643,7 @@ module ActiveRecord # # t.remove_timestamps # - # See SchemaStatements#remove_timestamps + # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps] def remove_timestamps(options = {}) @base.remove_timestamps(name, options) end @@ -645,7 +652,7 @@ module ActiveRecord # # t.rename(:description, :name) # - # See SchemaStatements#rename_column + # See {connection.rename_column}[rdoc-ref:SchemaStatements#rename_column] def rename(column_name, new_column_name) @base.rename_column(name, column_name, new_column_name) end @@ -655,7 +662,7 @@ module ActiveRecord # t.references(:user) # t.belongs_to(:supplier, foreign_key: true) # - # See SchemaStatements#add_reference for details of the options you can use. + # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use. def references(*args) options = args.extract_options! args.each do |ref_name| @@ -669,7 +676,7 @@ module ActiveRecord # t.remove_references(:user) # t.remove_belongs_to(:supplier, polymorphic: true) # - # See SchemaStatements#remove_reference + # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference] def remove_references(*args) options = args.extract_options! args.each do |ref_name| @@ -682,7 +689,7 @@ module ActiveRecord # # t.foreign_key(:authors) # - # See SchemaStatements#add_foreign_key + # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key] def foreign_key(*args) # :nodoc: @base.add_foreign_key(name, *args) end @@ -691,7 +698,7 @@ module ActiveRecord # # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors) # - # See SchemaStatements#foreign_key_exists? + # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?] def foreign_key_exists?(*args) # :nodoc: @base.foreign_key_exists?(name, *args) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb index a2f58364a4..e252ddb4cf 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb @@ -20,7 +20,7 @@ module ActiveRecord # This can be overridden on an Adapter level basis to support other # extended datatypes (Example: Adding an array option in the - # PostgreSQLAdapter) + # PostgreSQL::ColumnDumper) def prepare_column_options(column) spec = {} spec[:name] = column.name.inspect diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index ccff853987..d3fbc18f97 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -129,7 +129,7 @@ module ActiveRecord # 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 + # There are two ways to work with #create_table. You can use the block # form or the regular form, like this: # # === Block form @@ -161,7 +161,7 @@ module ActiveRecord # The +options+ hash can include the following keys: # [<tt>:id</tt>] # Whether to automatically add a primary key column. Defaults to true. - # Join tables for +has_and_belongs_to_many+ should set it to false. + # 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. # [<tt>:primary_key</tt>] @@ -169,7 +169,8 @@ module ActiveRecord # Defaults to +id+. If <tt>:id</tt> is false this option is ignored. # # Note that Active Record models will automatically detect their - # primary key. This can be avoided by using +self.primary_key=+ on the model + # 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. # # [<tt>:options</tt>] @@ -296,7 +297,7 @@ module ActiveRecord # 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 + # 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| @@ -331,11 +332,11 @@ module ActiveRecord end # Drops the join table specified by the given arguments. - # See +create_join_table+ for details. + # 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. + # In that case, the block will be used by #create_join_table. def drop_join_table(table_1, table_2, options = {}) join_table_name = find_join_table_name(table_1, table_2, options) drop_table(join_table_name) @@ -440,7 +441,7 @@ module ActiveRecord # # 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. + # In that case, +options+ and the block will be used by #create_table. def drop_table(table_name, options = {}) execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}" end @@ -694,7 +695,7 @@ module ActiveRecord # Adds a reference. The reference column is an integer by default, # the <tt>:type</tt> option can be used to specify a different type. # Optionally adds a +_type+ column, if <tt>:polymorphic</tt> option is provided. - # <tt>add_reference</tt> and <tt>add_belongs_to</tt> are acceptable. + # #add_reference and #add_belongs_to are acceptable. # # The +options+ hash can include the following keys: # [<tt>:type</tt>] @@ -724,13 +725,17 @@ module ActiveRecord # # 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(table_name, *args) ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self)) end alias :add_belongs_to :add_reference # Removes the reference(s). Also removes a +type+ column if one exists. - # <tt>remove_reference</tt> and <tt>remove_belongs_to</tt> are acceptable. + # #remove_reference and #remove_belongs_to are acceptable. # # ====== Remove the reference # @@ -756,7 +761,7 @@ module ActiveRecord alias :remove_belongs_to :remove_reference # Returns an array of foreign keys for the given table. - # The foreign keys are represented as +ForeignKeyDefinition+ objects. + # The foreign keys are represented as ForeignKeyDefinition objects. def foreign_keys(table_name) raise NotImplementedError, "foreign_keys is not implemented" end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index ed14c781c6..9b46df721a 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -51,15 +51,15 @@ module ActiveRecord # 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. + # 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 returns an AbstractAdapter object, which + # {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 SchemaStatement are very useful. + # notably, the instance methods provided by SchemaStatements are very useful. class AbstractAdapter ADAPTER_NAME = 'Abstract'.freeze include Quoting, DatabaseStatements, SchemaStatements @@ -348,7 +348,7 @@ module ActiveRecord end # Checks whether the connection to the database is still active (i.e. not stale). - # This is done under the hood by calling <tt>active?</tt>. If the connection + # 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!(*ignored) reconnect! unless active? diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index b260133f4a..f710ec10fc 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -1,12 +1,14 @@ require 'active_record/connection_adapters/abstract_adapter' require 'active_record/connection_adapters/mysql/schema_creation' require 'active_record/connection_adapters/mysql/schema_definitions' +require 'active_record/connection_adapters/mysql/schema_dumper' require 'active_support/core_ext/string/strip' module ActiveRecord module ConnectionAdapters class AbstractMysqlAdapter < AbstractAdapter + include MySQL::ColumnDumper include Savepoints def update_table_definition(table_name, base) # :nodoc: @@ -17,49 +19,6 @@ module ActiveRecord MySQL::SchemaCreation.new(self) end - def column_spec_for_primary_key(column) - spec = {} - if column.auto_increment? - spec[:id] = ':bigint' if column.bigint? - spec[:unsigned] = 'true' if column.unsigned? - return if spec.empty? - else - spec[:id] = column.type.inspect - spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) }) - end - spec - end - - def prepare_column_options(column) - spec = super - spec[:unsigned] = 'true' if column.unsigned? - spec - end - - def migration_keys - super + [:unsigned] - end - - private - - def schema_limit(column) - super unless column.type == :boolean - end - - def schema_precision(column) - super unless /time/ === column.sql_type && column.precision == 0 - end - - def schema_collation(column) - if column.collation && table_name = column.instance_variable_get(:@table_name) - @collation_cache ||= {} - @collation_cache[table_name] ||= select_one("SHOW TABLE STATUS LIKE '#{table_name}'")["Collation"] - column.collation.inspect if column.collation != @collation_cache[table_name] - end - end - - public - class Column < ConnectionAdapters::Column # :nodoc: delegate :strict, :extra, to: :sql_type_metadata, allow_nil: true diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb index 5e31efec4a..81de7c03fb 100644 --- a/activerecord/lib/active_record/connection_adapters/column.rb +++ b/activerecord/lib/active_record/connection_adapters/column.rb @@ -16,7 +16,7 @@ module ActiveRecord # +sql_type_metadata+ is various information about the type of the column # +null+ determines if this column allows +NULL+ values. def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation = nil) - @name = name + @name = name.freeze @sql_type_metadata = sql_type_metadata @null = null @default = default diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb new file mode 100644 index 0000000000..6448b8b5e2 --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb @@ -0,0 +1,48 @@ +module ActiveRecord + module ConnectionAdapters + module MySQL + module ColumnDumper + def column_spec_for_primary_key(column) + spec = {} + if column.auto_increment? + spec[:id] = ':bigint' if column.bigint? + spec[:unsigned] = 'true' if column.unsigned? + return if spec.empty? + else + spec[:id] = column.type.inspect + spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) }) + end + spec + end + + def prepare_column_options(column) + spec = super + spec[:unsigned] = 'true' if column.unsigned? + spec + end + + def migration_keys + super + [:unsigned] + end + + private + + def schema_limit(column) + super unless column.type == :boolean + end + + def schema_precision(column) + super unless /time/ === column.sql_type && column.precision == 0 + end + + def schema_collation(column) + if column.collation && table_name = column.instance_variable_get(:@table_name) + @table_collation_cache ||= {} + @table_collation_cache[table_name] ||= select_one("SHOW TABLE STATUS LIKE '#{table_name}'")["Collation"] + column.collation.inspect if column.collation != @table_collation_cache[table_name] + end + end + end + end + end +end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb new file mode 100644 index 0000000000..a4f0742516 --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb @@ -0,0 +1,54 @@ +module ActiveRecord + module ConnectionAdapters + module PostgreSQL + module ColumnDumper + def column_spec_for_primary_key(column) + spec = {} + if column.serial? + return unless column.bigint? + spec[:id] = ':bigserial' + elsif column.type == :uuid + spec[:id] = ':uuid' + spec[:default] = column.default_function.inspect + else + spec[:id] = column.type.inspect + spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) }) + end + spec + end + + # Adds +:array+ option to the default set + def prepare_column_options(column) + spec = super + spec[:array] = 'true' if column.array? + spec + end + + # Adds +:array+ as a valid migration key + def migration_keys + super + [:array] + end + + private + + def schema_type(column) + return super unless column.serial? + + if column.bigint? + 'bigserial' + else + 'serial' + end + end + + def schema_default(column) + if column.default_function + column.default_function.inspect unless column.serial? + else + super + end + end + end + end + end +end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 25dfda9ef8..0686b35425 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -9,6 +9,7 @@ require "active_record/connection_adapters/postgresql/oid" require "active_record/connection_adapters/postgresql/quoting" require "active_record/connection_adapters/postgresql/referential_integrity" require "active_record/connection_adapters/postgresql/schema_definitions" +require "active_record/connection_adapters/postgresql/schema_dumper" require "active_record/connection_adapters/postgresql/schema_statements" require "active_record/connection_adapters/postgresql/type_metadata" require "active_record/connection_adapters/postgresql/utils" @@ -117,61 +118,14 @@ module ActiveRecord include PostgreSQL::ReferentialIntegrity include PostgreSQL::SchemaStatements include PostgreSQL::DatabaseStatements + include PostgreSQL::ColumnDumper include Savepoints def schema_creation # :nodoc: PostgreSQL::SchemaCreation.new self end - def column_spec_for_primary_key(column) - spec = {} - if column.serial? - return unless column.bigint? - spec[:id] = ':bigserial' - elsif column.type == :uuid - spec[:id] = ':uuid' - spec[:default] = column.default_function.inspect - else - spec[:id] = column.type.inspect - spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) }) - end - spec - end - - # Adds +:array+ option to the default set provided by the - # AbstractAdapter - def prepare_column_options(column) # :nodoc: - spec = super - spec[:array] = 'true' if column.array? - spec - end - - # Adds +:array+ as a valid migration key - def migration_keys - super + [:array] - end - - def schema_type(column) - return super unless column.serial? - - if column.bigint? - 'bigserial' - else - 'serial' - end - end - private :schema_type - - def schema_default(column) - if column.default_function - column.default_function.inspect unless column.serial? - else - super - end - end - private :schema_default - - # Returns +true+, since this connection adapter supports prepared statement + # Returns true, since this connection adapter supports prepared statement # caching. def supports_statement_cache? true diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb index 2fc5e410f9..aedef54928 100644 --- a/activerecord/lib/active_record/connection_handling.rb +++ b/activerecord/lib/active_record/connection_handling.rb @@ -35,14 +35,14 @@ module ActiveRecord # "postgres://myuser:mypass@localhost/somedatabase" # ) # - # In case <tt>ActiveRecord::Base.configurations</tt> is set (Rails - # automatically loads the contents of config/database.yml into it), + # 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+ + # The exceptions AdapterNotSpecified, AdapterNotFound and +ArgumentError+ # may be returned on an error. def establish_connection(spec = nil) spec ||= DEFAULT_ENV.call.to_sym diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 894d18b79e..db3e9d1d52 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -310,7 +310,7 @@ module ActiveRecord # Initialize an empty model object from +coder+. +coder+ should be # the result of previously encoding an Active Record model, using - # `encode_with` + # #encode_with. # # class Post < ActiveRecord::Base # end @@ -379,7 +379,7 @@ module ActiveRecord # 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+ + # guaranteed to match the structure of +coder+ passed to the #init_with # method. # # Example: @@ -477,7 +477,7 @@ module ActiveRecord "#<#{self.class} #{inspection}>" end - # Takes a PP and prettily prints this record to it, allowing you to get a nice result from `pp record` + # Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt> # when pp is required. def pretty_print(pp) return super if custom_inspect_method_defined? diff --git a/activerecord/lib/active_record/counter_cache.rb b/activerecord/lib/active_record/counter_cache.rb index 82596b63df..9e7d391c70 100644 --- a/activerecord/lib/active_record/counter_cache.rb +++ b/activerecord/lib/active_record/counter_cache.rb @@ -45,14 +45,14 @@ module ActiveRecord end # A generic "counter updater" implementation, intended primarily to be - # used by increment_counter and decrement_counter, but which may also + # 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. + # * +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. # @@ -86,14 +86,14 @@ module ActiveRecord # 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 + # 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. + # * +id+ - The id of the object that should be incremented or an array of ids. # # ==== Examples # @@ -105,13 +105,13 @@ module ActiveRecord # Decrement a numeric field by one, via a direct SQL update. # - # This works the same as increment_counter but reduces the column value by + # 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. + # * +id+ - The id of the object that should be decremented or an array of ids. # # ==== Examples # diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb index 10b5fcab24..8fba6fcc35 100644 --- a/activerecord/lib/active_record/enum.rb +++ b/activerecord/lib/active_record/enum.rb @@ -46,13 +46,13 @@ module ActiveRecord # Good practice is to let the first declared status be the default. # # Finally, it's also possible to explicitly map the relation between attribute and - # database integer with a +Hash+: + # database integer with a hash: # # class Conversation < ActiveRecord::Base # enum status: { active: 0, archived: 1 } # end # - # Note that when an +Array+ is used, the implicit mapping from the values to database + # Note that when an array is used, the implicit mapping from the values to database # integers is derived from the order the values appear in the array. In the example, # <tt>:active</tt> is mapped to +0+ as it's the first element, and <tt>:archived</tt> # is mapped to +1+. In general, the +i+-th element is mapped to <tt>i-1</tt> in the @@ -60,7 +60,7 @@ module ActiveRecord # # Therefore, once a value is added to the enum array, its position in the array must # be maintained, and new values should only be added to the end of the array. To - # remove unused values, the explicit +Hash+ syntax should be used. + # remove unused values, the explicit hash syntax should be used. # # In rare circumstances you might need to access the mapping directly. # The mappings are exposed through a class method with the pluralized attribute diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb index 6721fe144f..533c86a6a9 100644 --- a/activerecord/lib/active_record/errors.rb +++ b/activerecord/lib/active_record/errors.rb @@ -7,8 +7,10 @@ module ActiveRecord end # Raised when the single-table inheritance mechanism fails to locate the subclass - # (for example due to improper usage of column that +inheritance_column+ points to). - class SubclassNotFound < ActiveRecordError #:nodoc: + # (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. @@ -40,12 +42,13 @@ module ActiveRecord class AdapterNotFound < ActiveRecordError end - # Raised when connection to the database could not been established (for - # example when +connection=+ is given a nil object). + # 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 Active Record cannot find record by given id or set of ids. + # Raised when Active Record cannot find a record by given id or set of ids. class RecordNotFound < ActiveRecordError attr_reader :model, :primary_key, :id @@ -58,8 +61,9 @@ module ActiveRecord end end - # Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be - # saved because record is invalid. + # 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 can not be saved. class RecordNotSaved < ActiveRecordError attr_reader :record @@ -69,7 +73,9 @@ module ActiveRecord end end - # Raised by ActiveRecord::Base.destroy! when a call to destroy would return false. + # 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! @@ -99,7 +105,7 @@ module ActiveRecord end # Defunct wrapper class kept for compatibility. - # +StatementInvalid+ wraps the original exception now. + # StatementInvalid wraps the original exception now. class WrappedDatabaseException < StatementInvalid end @@ -112,8 +118,8 @@ module ActiveRecord end # Raised when number of bind variables in statement given to +:condition+ key - # (for example, when using +find+ method) does not match number of expected - # values supplied. + # (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: # @@ -147,7 +153,9 @@ module ActiveRecord end # Raised when association is being configured improperly or user tries to use - # offset and limit together with +has_many+ or +has_and_belongs_to_many+ + # 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 @@ -156,9 +164,10 @@ module ActiveRecord class ReadOnlyRecord < ActiveRecordError end - # ActiveRecord::Transactions::ClassMethods.transaction uses this exception - # to distinguish a deliberate rollback from other exceptional situations. - # Normally, raising an exception will cause the +transaction+ method to rollback + # {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. @@ -195,8 +204,8 @@ module ActiveRecord UnknownAttributeError = ActiveModel::UnknownAttributeError # Raised when an error occurred while doing a mass assignment to an attribute through the - # +attributes=+ method. The exception has an +attribute+ property that is the name of the - # offending attribute. + # {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, :attribute @@ -207,7 +216,8 @@ module ActiveRecord end end - # Raised when there are multiple errors while doing a mass assignment through the +attributes+ + # 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 diff --git a/activerecord/lib/active_record/explain_registry.rb b/activerecord/lib/active_record/explain_registry.rb index f5cd57e075..b652932f9c 100644 --- a/activerecord/lib/active_record/explain_registry.rb +++ b/activerecord/lib/active_record/explain_registry.rb @@ -7,7 +7,7 @@ module ActiveRecord # # returns the collected queries local to the current thread. # - # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt> + # See the documentation of ActiveSupport::PerThreadRegistry # for further details. class ExplainRegistry # :nodoc: extend ActiveSupport::PerThreadRegistry diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 59df3c78f3..17e7c828b9 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -89,7 +89,7 @@ module ActiveRecord # end # # In order to use these methods to access fixtured data within your testcases, you must specify one of the - # following in your <tt>ActiveSupport::TestCase</tt>-derived class: + # following in your ActiveSupport::TestCase-derived class: # # - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above) # self.use_instantiated_fixtures = true @@ -124,7 +124,7 @@ module ActiveRecord # # 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 <tt>ActiveRecord::FixtureSet.context_class</tt>. + # that is included in ActiveRecord::FixtureSet.context_class. # # - define a helper method in `test_helper.rb` # module FixtureFileHelpers diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index f659d0b10f..94316d5249 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -1,5 +1,5 @@ module ActiveRecord - # = Active Record Persistence + # = Active Record \Persistence module Persistence extend ActiveSupport::Concern @@ -106,7 +106,7 @@ module ActiveRecord # the existing record gets updated. # # By default, save always run validations. If any of them fail the action - # is cancelled and +save+ returns +false+. However, if you supply + # is cancelled and #save returns +false+. However, if you supply # validate: false, validations are bypassed altogether. See # ActiveRecord::Validations for more information. # @@ -132,7 +132,7 @@ module ActiveRecord # If the model is new, a record gets created in the database, otherwise # the existing record gets updated. # - # With <tt>save!</tt> validations always run. If any of them fail + # With #save! validations always run. If any of them fail # ActiveRecord::RecordInvalid gets raised. See ActiveRecord::Validations # for more information. # @@ -158,7 +158,7 @@ module ActiveRecord # 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 <tt>readonly?</tt>. + # 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 <tt>:dependent</tt> association @@ -207,7 +207,7 @@ module ActiveRecord # 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. + # If you want to change the sti column as well, use #becomes! instead. def becomes(klass) became = klass.new became.instance_variable_set("@attributes", @attributes) @@ -219,7 +219,7 @@ module ActiveRecord became end - # Wrapper around +becomes+ that also changes the instance's sti column value. + # 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. # @@ -239,14 +239,14 @@ module ActiveRecord # This is especially useful for boolean flags on existing records. Also note that # # * Validation is skipped. - # * Callbacks are invoked. + # * \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 + # This method raises an ActiveRecord::ActiveRecordError if the # attribute is marked as readonly. # - # See also +update_column+. + # See also #update_column. def update_attribute(name, value) name = name.to_s verify_readonly_attribute(name) @@ -268,7 +268,7 @@ module ActiveRecord alias update_attributes update - # Updates its receiver just like +update+ but calls <tt>save!</tt> instead + # Updates its receiver just like #update but calls #save! instead # of +save+, so an exception is raised if the record is invalid. def update!(attributes) # The following transaction covers any possible database side-effects of the @@ -295,11 +295,11 @@ module ActiveRecord # the database, but take into account that in consequence the regular update # procedures are totally bypassed. In particular: # - # * Validations are skipped. - # * Callbacks are skipped. + # * \Validations are skipped. + # * \Callbacks are skipped. # * +updated_at+/+updated_on+ are not updated. # - # This method raises an +ActiveRecord::ActiveRecordError+ when called on new + # 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(attributes) raise ActiveRecordError, "cannot update a new record" if new_record? @@ -327,7 +327,7 @@ module ActiveRecord self end - # Wrapper around +increment+ that saves the record. This method differs from + # Wrapper around #increment that saves the record. This method differs from # its non-bang version in that it passes through the attribute setter. # Saving is not subjected to validation checks. Returns +true+ if the # record could be saved. @@ -346,7 +346,7 @@ module ActiveRecord increment(attribute, -by) end - # Wrapper around +decrement+ that saves the record. This method differs from + # Wrapper around #decrement that saves the record. This method differs from # its non-bang version in that it passes through the attribute setter. # Saving is not subjected to validation checks. Returns +true+ if the # record could be saved. @@ -363,7 +363,7 @@ module ActiveRecord self end - # Wrapper around +toggle+ that saves the record. This method differs from + # Wrapper around #toggle that saves the record. This method differs from # its non-bang version in that it passes through the attribute setter. # Saving is not subjected to validation checks. Returns +true+ if the # record could be saved. @@ -386,7 +386,7 @@ module ActiveRecord # 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 <tt>ActiveRecord::RecordNotFound</tt> + # 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. # @@ -448,8 +448,8 @@ module ActiveRecord # 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+ then +touch+ will invoke +touch+ method on - # associated object. + # 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 diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 36cdeed489..392b462aa9 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -1,7 +1,7 @@ require "arel/collectors/bind" module ActiveRecord - # = Active Record Relation + # = Active Record \Relation class Relation MULTI_VALUE_METHODS = [:includes, :eager_load, :preload, :select, :group, :order, :joins, :references, @@ -108,7 +108,7 @@ module ActiveRecord # Initializes new record from relation while maintaining the current # scope. # - # Expects arguments in the same format as +Base.new+. + # Expects arguments in the same format as {ActiveRecord::Base.new}[rdoc-ref:Core.new]. # # users = User.where(name: 'DHH') # user = users.new # => #<User id: nil, name: "DHH", created_at: nil, updated_at: nil> @@ -126,28 +126,32 @@ module ActiveRecord # 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 +Base.create+. + # Expects arguments in the same format as + # {ActiveRecord::Base.create}[rdoc-ref:Persistence::ClassMethods#create]. # # ==== Examples + # # users = User.where(name: 'Oscar') - # users.create # #<User id: 3, name: "oscar", ...> + # users.create # => #<User id: 3, name: "oscar", ...> # # users.create(name: 'fxn') - # users.create # #<User id: 4, name: "fxn", ...> + # users.create # => #<User id: 4, name: "fxn", ...> # # users.create { |user| user.name = 'tenderlove' } - # # #<User id: 5, name: "tenderlove", ...> + # # => #<User id: 5, name: "tenderlove", ...> # # users.create(name: nil) # validation on name - # # #<User id: nil, name: nil, ...> + # # => #<User id: nil, name: nil, ...> def create(*args, &block) scoping { @klass.create(*args, &block) } end - # Similar to #create, but calls +create!+ on the base class. Raises - # an exception if a validation error occurs. + # 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 <tt>Base.create!</tt>. + # Expects arguments in the same format as + # {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]. def create!(*args, &block) scoping { @klass.create!(*args, &block) } end @@ -181,7 +185,7 @@ module ActiveRecord # User.create_with(last_name: 'Johansson').find_or_create_by(first_name: 'Scarlett') # # => #<User id: 2, first_name: "Scarlett", last_name: "Johansson"> # - # This method accepts a block, which is passed down to +create+. The last example + # 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 @@ -193,7 +197,7 @@ module ActiveRecord # # 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. + # #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 @@ -216,13 +220,15 @@ module ActiveRecord find_by(attributes) || create(attributes, &block) end - # Like <tt>find_or_create_by</tt>, but calls <tt>create!</tt> so an exception + # 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!(attributes, &block) find_by(attributes) || create!(attributes, &block) end - # Like <tt>find_or_create_by</tt>, but calls <tt>new</tt> instead of <tt>create</tt>. + # 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(attributes, &block) find_by(attributes) || new(attributes, &block) end @@ -304,7 +310,7 @@ module ActiveRecord # the existing records is updated or deleted, the cache key changes. # # Product.where("name like ?", "%Cosmic Encounter%").cache_key - # => "products/query-1850ab3d302391b85b8693e941286659-1-20150714212553907087000" + # # => "products/query-1850ab3d302391b85b8693e941286659-1-20150714212553907087000" # # If the collection is loaded, the method will iterate through the records # to generate the timestamp, otherwise it will trigger one SQL query like: @@ -341,8 +347,8 @@ module ActiveRecord # 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. Values passed to `update_all` will not go through - # ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL + # trigger Active Record callbacks or validations. Values passed to #update_all will not go through + # Active Record's type-casting behavior. It should receive only values that can be passed as-is to the SQL # database. # # ==== Parameters @@ -403,7 +409,7 @@ module ActiveRecord # Note: Updating a large number of records will run an # UPDATE query for each record, which may cause a performance # issue. So if it is not needed to run callbacks for each update, it is - # preferred to use <tt>update_all</tt> for updating all records using + # preferred to use #update_all for updating all records using # a single query. def update(id = :all, attributes) if id.is_a?(Array) @@ -411,6 +417,13 @@ module ActiveRecord elsif id == :all to_a.each { |record| record.update(attributes) } else + if ActiveRecord::Base === id + id = id.id + ActiveSupport::Deprecation.warn(<<-MSG.squish) + You are passing an instance of ActiveRecord::Base to `update`. + Please pass the id of the object by calling `.id` + MSG + end object = find(id) object.update(attributes) object @@ -418,9 +431,9 @@ module ActiveRecord end # Destroys the records by instantiating each - # record and calling its +destroy+ method. Each object's callbacks are - # executed (including <tt>:dependent</tt> association options). Returns the - # collection of objects that were destroyed; each will be frozen, to + # record and calling its {#destroy}[rdoc-ref:Persistence#destroy] method. + # Each object's callbacks are executed (including <tt>:dependent</tt> 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 @@ -428,7 +441,7 @@ module ActiveRecord # 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. + # #delete_all instead. # # ==== Examples # @@ -447,7 +460,7 @@ module ActiveRecord # 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 ActiveRecord#delete but allows cleanup methods and other actions to be run. + # 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. @@ -473,9 +486,10 @@ module ActiveRecord end # Deletes the records without instantiating the records - # first, and hence not calling the +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 + # 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 # <tt>:dependent</tt> rules defined on associations are not honored. Returns the # number of rows affected. # @@ -483,9 +497,9 @@ module ActiveRecord # # Both calls delete the affected posts all at once with a single DELETE statement. # If you need to destroy dependent associations or call your <tt>before_*</tt> or - # +after_destroy+ callbacks, use the +destroy_all+ method instead. + # +after_destroy+ callbacks, use the #destroy_all method instead. # - # If an invalid method is supplied, +delete_all+ raises an ActiveRecord error: + # If an invalid method is supplied, #delete_all raises an ActiveRecordError: # # Post.limit(100).delete_all # # => ActiveRecord::ActiveRecordError: delete_all doesn't support limit @@ -534,7 +548,7 @@ module ActiveRecord # You can delete multiple rows at once by passing an Array of <tt>id</tt>s. # # Note: Although it is often much faster than the alternative, - # <tt>#destroy</tt>, skipping callbacks might bypass business logic in + # #destroy, skipping callbacks might bypass business logic in # your application that ensures referential integrity or performs other # essential jobs. # @@ -624,8 +638,10 @@ module ActiveRecord includes_values & joins_values end - # +uniq+ and +uniq!+ are silently deprecated. +uniq_value+ delegates to +distinct_value+ - # to maintain backwards compatibility. Use +distinct_value+ instead. + # {#uniq}[rdoc-ref:QueryMethods#uniq] and + # {#uniq!}[rdoc-ref:QueryMethods#uniq!] are silently deprecated. + # #uniq_value delegates to #distinct_value to maintain backwards compatibility. + # Use #distinct_value instead. def uniq_value distinct_value end diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb index beb8fa511c..221bc73680 100644 --- a/activerecord/lib/active_record/relation/batches.rb +++ b/activerecord/lib/active_record/relation/batches.rb @@ -3,8 +3,8 @@ require "active_record/relation/batches/batch_enumerator" module ActiveRecord module Batches # 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. + # (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. diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index 69f39e5ba9..16d5774fec 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -14,33 +14,34 @@ module ActiveRecord # Person.distinct.count(:age) # # => counts the number of different age values # - # If +count+ is used with +group+, it returns a Hash whose keys represent the aggregated column, + # 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 +group+ for multiple columns, it returns a Hash whose + # 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+. + # 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 +select+, it will count the selected columns: + # 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 +select+ expressions are valid +count+ expressions. The specifics differ + # 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(column_name = nil) calculate(:count, column_name) end # Calculates the average value on a given column. Returns +nil+ if there's - # no row. See +calculate+ for examples with options. + # no row. See #calculate for examples with options. # # Person.average(:age) # => 35.8 def average(column_name) @@ -49,7 +50,7 @@ module ActiveRecord # 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. + # #calculate for examples with options. # # Person.minimum(:age) # => 7 def minimum(column_name) @@ -58,7 +59,7 @@ module ActiveRecord # 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. + # #calculate for examples with options. # # Person.maximum(:age) # => 93 def maximum(column_name) @@ -66,8 +67,8 @@ module ActiveRecord end # 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. + # 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(column_name = nil, &block) @@ -75,37 +76,37 @@ module ActiveRecord calculate(:sum, column_name) end - # This calculates aggregate values in the given column. Methods for count, sum, average, - # minimum, and maximum have been added as shortcuts. + # This calculates aggregate values in the given column. Methods for #count, #sum, #average, + # #minimum, and #maximum have been added as shortcuts. # - # There are two basic forms of output: + # Person.calculate(:count, :all) # The same as Person.count + # Person.average(:age) # SELECT AVG(age) FROM people... # - # * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float - # for AVG, and the given column's type for everything else. + # # Selects the minimum age for any family without any minors + # Person.group(:last_name).having("min(age) > 17").minimum(:age) # - # * 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. + # Person.sum("2 * age") # - # values = Person.group('last_name').maximum(:age) - # puts values["Drake"] - # # => 43 + # There are two basic forms of output: # - # drake = Family.find_by(last_name: 'Drake') - # values = Person.group(:family).maximum(:age) # Person belongs_to :family - # puts values[drake] - # # => 43 + # * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float + # for AVG, and the given column's type for everything else. # - # values.each do |family, max_age| - # ... - # end + # * 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. # - # Person.calculate(:count, :all) # The same as Person.count - # Person.average(:age) # SELECT AVG(age) FROM people... + # values = Person.group('last_name').maximum(:age) + # puts values["Drake"] + # # => 43 # - # # Selects the minimum age for any family without any minors - # Person.group(:last_name).having("min(age) > 17").minimum(:age) + # drake = Family.find_by(last_name: 'Drake') + # values = Person.group(:family).maximum(:age) # Person belongs_to :family + # puts values[drake] + # # => 43 # - # Person.sum("2 * age") + # values.each do |family, max_age| + # ... + # end def calculate(operation, column_name) if column_name.is_a?(Symbol) && attribute_alias?(column_name) column_name = attribute_alias(column_name) @@ -118,7 +119,7 @@ module ActiveRecord end end - # Use <tt>pluck</tt> as a shortcut to select one or more attributes without + # 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) @@ -127,7 +128,7 @@ module ActiveRecord # # Person.all.map(&:name) # - # Pluck returns an <tt>Array</tt> of attribute values type-casted to match + # 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. # @@ -151,7 +152,7 @@ module ActiveRecord # # SELECT DATEDIFF(updated_at, created_at) FROM people # # => ['0', '27761', '173'] # - # See also +ids+. + # See also #ids. # def pluck(*column_names) column_names.map! do |column_name| diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb index d75ec72b1a..27de313d05 100644 --- a/activerecord/lib/active_record/relation/delegation.rb +++ b/activerecord/lib/active_record/relation/delegation.rb @@ -3,12 +3,12 @@ require 'active_support/concern' module ActiveRecord module Delegation # :nodoc: - module DelegateCache - def relation_delegate_class(klass) # :nodoc: + module DelegateCache # :nodoc: + def relation_delegate_class(klass) @relation_delegate_cache[klass] end - def initialize_relation_delegate_cache # :nodoc: + def initialize_relation_delegate_cache @relation_delegate_cache = cache = {} [ ActiveRecord::Relation, diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 009b2bad57..435cef901b 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -17,7 +17,7 @@ module ActiveRecord # Person.where("administrator = 1").order("created_on DESC").find(1) # # NOTE: The returned records may not be in the same order as the ids you - # provide since database rows are unordered. You'd need to provide an explicit <tt>order</tt> + # provide since database rows are unordered. You'd need to provide an explicit QueryMethods#order # option if you want the results are sorted. # # ==== Find with lock @@ -34,7 +34,7 @@ module ActiveRecord # person.save! # end # - # ==== Variations of +find+ + # ==== Variations of #find # # Person.where(name: 'Spartacus', rating: 4) # # returns a chainable list (which can be empty). @@ -48,7 +48,7 @@ module ActiveRecord # Person.where(name: 'Spartacus', rating: 4).first_or_create # # returns the first item or creates it and returns it. # - # ==== Alternatives for +find+ + # ==== Alternatives for #find # # Person.where(name: 'Spartacus', rating: 4).exists?(conditions = :none) # # returns a boolean indicating if any record with the given conditions exist. @@ -80,8 +80,8 @@ module ActiveRecord nil end - # Like <tt>find_by</tt>, except that if no record is found, raises - # an <tt>ActiveRecord::RecordNotFound</tt> error. + # Like #find_by, except that if no record is found, raises + # an ActiveRecord::RecordNotFound error. def find_by!(arg, *args) where(arg, *args).take! rescue RangeError @@ -100,8 +100,8 @@ module ActiveRecord limit ? limit(limit).to_a : find_take end - # Same as +take+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record - # is found. Note that <tt>take!</tt> accepts no arguments. + # Same as #take but raises ActiveRecord::RecordNotFound if no record + # is found. Note that #take! accepts no arguments. def take! take or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]") end @@ -123,8 +123,8 @@ module ActiveRecord end end - # Same as +first+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record - # is found. Note that <tt>first!</tt> accepts no arguments. + # Same as #first but raises ActiveRecord::RecordNotFound if no record + # is found. Note that #first! accepts no arguments. def first! find_nth! 0 end @@ -156,8 +156,8 @@ module ActiveRecord end end - # Same as +last+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record - # is found. Note that <tt>last!</tt> accepts no arguments. + # Same as #last but raises ActiveRecord::RecordNotFound if no record + # is found. Note that #last! accepts no arguments. def last! last or raise RecordNotFound.new("Couldn't find #{@klass.name} with [#{arel.where_sql(@klass.arel_engine)}]") end @@ -172,7 +172,7 @@ module ActiveRecord find_nth(1, offset_index) end - # Same as +second+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # Same as #second but raises ActiveRecord::RecordNotFound if no record # is found. def second! find_nth! 1 @@ -188,7 +188,7 @@ module ActiveRecord find_nth(2, offset_index) end - # Same as +third+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # Same as #third but raises ActiveRecord::RecordNotFound if no record # is found. def third! find_nth! 2 @@ -204,7 +204,7 @@ module ActiveRecord find_nth(3, offset_index) end - # Same as +fourth+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # Same as #fourth but raises ActiveRecord::RecordNotFound if no record # is found. def fourth! find_nth! 3 @@ -220,7 +220,7 @@ module ActiveRecord find_nth(4, offset_index) end - # Same as +fifth+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # Same as #fifth but raises ActiveRecord::RecordNotFound if no record # is found. def fifth! find_nth! 4 @@ -236,14 +236,14 @@ module ActiveRecord find_nth(41, offset_index) end - # Same as +forty_two+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record + # Same as #forty_two but raises ActiveRecord::RecordNotFound if no record # is found. def forty_two! find_nth! 41 end - # 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: + # 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 @@ -256,7 +256,7 @@ module ActiveRecord # * No args - Returns +false+ if the table is empty, +true+ otherwise. # # For more information about specifying conditions as a hash or array, - # see the Conditions section in the introduction to <tt>ActiveRecord::Base</tt>. + # see the Conditions section in the introduction to ActiveRecord::Base. # # Note: You can't pass in a condition as a string (like <tt>name = # 'Jamie'</tt>), since it would be sanitized and then queried against @@ -298,7 +298,7 @@ module ActiveRecord end # This method is called whenever no records are found with either a single - # id or multiple ids and raises a +ActiveRecord::RecordNotFound+ exception. + # id or multiple ids and raises a ActiveRecord::RecordNotFound exception. # # The error message is different depending on whether a single id or # multiple ids are provided. If multiple ids are provided, then the number diff --git a/activerecord/lib/active_record/relation/from_clause.rb b/activerecord/lib/active_record/relation/from_clause.rb index a93952fa30..92340216ed 100644 --- a/activerecord/lib/active_record/relation/from_clause.rb +++ b/activerecord/lib/active_record/relation/from_clause.rb @@ -1,6 +1,6 @@ module ActiveRecord class Relation - class FromClause + class FromClause # :nodoc: attr_reader :value, :name def initialize(value, name) diff --git a/activerecord/lib/active_record/relation/query_attribute.rb b/activerecord/lib/active_record/relation/query_attribute.rb index e69319b4de..7ba964e802 100644 --- a/activerecord/lib/active_record/relation/query_attribute.rb +++ b/activerecord/lib/active_record/relation/query_attribute.rb @@ -2,7 +2,7 @@ require 'active_record/attribute' module ActiveRecord class Relation - class QueryAttribute < Attribute + class QueryAttribute < Attribute # :nodoc: def type_cast(value) value end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 7d95fe9a22..55fd0e0b52 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -20,7 +20,7 @@ module ActiveRecord # 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 #where for + # #not accepts conditions as a string, array, or hash. See QueryMethods#where for # more details on each format. # # User.where.not("name = 'Jon'") @@ -112,7 +112,7 @@ module ActiveRecord # # 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+. + # performance improvement over a simple join. # # You can also specify multiple relationships, like this: # @@ -133,7 +133,7 @@ module ActiveRecord # # User.includes(:posts).where('posts.name = ?', 'example').references(:posts) # - # Note that +includes+ works with association names while +references+ needs + # Note that #includes works with association names while #references needs # the actual table name. def includes(*args) check_if_method_has_arguments!(:includes, args) @@ -151,9 +151,9 @@ module ActiveRecord # 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" + # # 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(*args) check_if_method_has_arguments!(:eager_load, args) spawn.eager_load!(*args) @@ -164,10 +164,10 @@ module ActiveRecord self end - # Allows preloading of +args+, in the same way that +includes+ does: + # 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) + # # SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3) def preload(*args) check_if_method_has_arguments!(:preload, args) spawn.preload!(*args) @@ -180,14 +180,14 @@ module ActiveRecord # 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+. + # 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. + # # 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 + # # Query now knows the string references posts, so adds a JOIN def references(*table_names) check_if_method_has_arguments!(:references, table_names) spawn.references!(*table_names) @@ -203,12 +203,12 @@ module ActiveRecord # Works in two unique ways. # - # First: takes a block so it can be used just like Array#select. + # 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. + # 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: @@ -236,7 +236,7 @@ module ActiveRecord # # => "value" # # Accessing attributes of an object that do not have fields retrieved by a select - # except +id+ will throw <tt>ActiveModel::MissingAttributeError</tt>: + # except +id+ will throw ActiveModel::MissingAttributeError: # # Model.select(:field).first.other_field # # => ActiveModel::MissingAttributeError: missing attribute: other_field @@ -258,22 +258,23 @@ module ActiveRecord # Allows to specify a group attribute: # # User.group(:name) - # => SELECT "users".* FROM "users" GROUP BY name + # # SELECT "users".* FROM "users" GROUP BY name # # Returns an array with distinct records based on the +group+ attribute: # # User.select([:id, :name]) - # => [#<User id: 1, name: "Oscar">, #<User id: 2, name: "Oscar">, #<User id: 3, name: "Foo">] + # # => [#<User id: 1, name: "Oscar">, #<User id: 2, name: "Oscar">, #<User id: 3, name: "Foo">] # # User.group(:name) - # => [#<User id: 3, name: "Foo", ...>, #<User id: 2, name: "Oscar", ...>] + # # => [#<User id: 3, name: "Foo", ...>, #<User id: 2, name: "Oscar", ...>] # # User.group('name AS grouped_name, age') - # => [#<User id: 3, name: "Foo", age: 21, ...>, #<User id: 2, name: "Oscar", age: 21, ...>, #<User id: 5, name: "Foo", age: 23, ...>] + # # => [#<User id: 3, name: "Foo", age: 21, ...>, #<User id: 2, name: "Oscar", age: 21, ...>, #<User id: 5, name: "Foo", age: 23, ...>] # # Passing in an array of attributes to group by is also supported. + # # User.select([:id, :first_name]).group(:id, :first_name).first(3) - # => [#<User id: 1, first_name: "Bill">, #<User id: 2, first_name: "Earl">, #<User id: 3, first_name: "Beto">] + # # => [#<User id: 1, first_name: "Bill">, #<User id: 2, first_name: "Earl">, #<User id: 3, first_name: "Beto">] def group(*args) check_if_method_has_arguments!(:group, args) spawn.group!(*args) @@ -289,22 +290,22 @@ module ActiveRecord # Allows to specify an order attribute: # # User.order(:name) - # => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC + # # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC # # User.order(email: :desc) - # => SELECT "users".* FROM "users" ORDER BY "users"."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 + # # SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC # # User.order('name') - # => SELECT "users".* FROM "users" ORDER BY name + # # SELECT "users".* FROM "users" ORDER BY name # # User.order('name DESC') - # => SELECT "users".* FROM "users" ORDER BY name DESC + # # SELECT "users".* FROM "users" ORDER BY name DESC # # User.order('name DESC, email') - # => SELECT "users".* FROM "users" ORDER BY name DESC, email + # # SELECT "users".* FROM "users" ORDER BY name DESC, email def order(*args) check_if_method_has_arguments!(:order, args) spawn.order!(*args) @@ -356,15 +357,15 @@ module ActiveRecord # 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. + # 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: + # +: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 <tt>except</tt>, but unlike - # <tt>except</tt>, it persists across merges: + # This method is similar to #except, but unlike + # #except, it persists across merges: # # User.order('email').merge(User.except(:order)) # == User.order('email') @@ -409,12 +410,12 @@ module ActiveRecord # Performs a joins on +args+: # # User.joins(:posts) - # => SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id" + # # SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."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 + # # SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id def joins(*args) check_if_method_has_arguments!(:joins, args) spawn.joins!(*args) @@ -470,7 +471,7 @@ module ActiveRecord # 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 <tt>Kernel::sprintf</tt>. + # 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'; @@ -565,12 +566,17 @@ module ActiveRecord # 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 + # Post.where(trashed: true).where(trashed: false) + # # WHERE `trashed` = 1 AND `trashed` = 0 + # + # Post.where(trashed: true).rewhere(trashed: false) + # # WHERE `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. + # Post.where(active: true).where(trashed: true).rewhere(trashed: false) + # # WHERE `active` = 1 AND `trashed` = 0 + # + # This is short-hand for <tt>unscope(where: conditions.keys).where(conditions)</tt>. + # Note that unlike reorder, we're only unscoping the named conditions -- not the entire where statement. def rewhere(conditions) unscope(where: conditions.keys).where(conditions) end @@ -579,8 +585,8 @@ module ActiveRecord # 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. + # 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("id = 2")) # # SELECT `posts`.* FROM `posts` WHERE (('id = 1' OR 'id = 2')) @@ -600,12 +606,6 @@ module ActiveRecord self end - private def structurally_compatible_for_or?(other) # :nodoc: - Relation::SINGLE_VALUE_METHODS.all? { |m| send("#{m}_value") == other.send("#{m}_value") } && - (Relation::MULTI_VALUE_METHODS - [:extending]).all? { |m| send("#{m}_values") == other.send("#{m}_values") } && - (Relation::CLAUSE_METHODS - [:having, :where]).all? { |m| send("#{m}_clause") != other.send("#{m}_clause") } - end - # Allows to specify a HAVING clause. Note that you can't use HAVING # without also specifying a GROUP clause. # @@ -653,7 +653,7 @@ module ActiveRecord end # Specifies locking settings (default to +true+). For more information - # on locking, please see +ActiveRecord::Locking+. + # on locking, please see ActiveRecord::Locking. def lock(locks = true) spawn.lock!(locks) end @@ -684,7 +684,7 @@ module ActiveRecord # For example: # # @posts = current_user.visible_posts.where(name: params[:name]) - # # => the visible_posts method is expected to return a chainable Relation + # # the visible_posts method is expected to return a chainable Relation # # def visible_posts # case role @@ -729,7 +729,7 @@ module ActiveRecord # users = users.create_with(name: 'DHH') # users.new.name # => 'DHH' # - # You can pass +nil+ to +create_with+ to reset attributes: + # You can pass +nil+ to #create_with to reset attributes: # # users = users.create_with(nil) # users.new.name # => 'Oscar' @@ -751,15 +751,15 @@ module ActiveRecord # Specifies table from which the records will be fetched. For example: # # Topic.select('title').from('posts') - # # => 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 + # # 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 + # # SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a # def from(value, subquery_name = nil) spawn.from!(value, subquery_name) @@ -773,13 +773,13 @@ module ActiveRecord # Specifies whether the records should be unique or not. For example: # # User.select(:name) - # # => Might return two records with the same name + # # Might return two records with the same name # # User.select(:name).distinct - # # => Returns 1 record per distinct name + # # Returns 1 record per distinct name # # User.select(:name).distinct.distinct(false) - # # => You can also remove the uniqueness + # # You can also remove the uniqueness def distinct(value = true) spawn.distinct!(value) end @@ -1075,8 +1075,8 @@ module ActiveRecord # # Example: # - # Post.references() # => raises an error - # Post.references([]) # => does not raise an error + # 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: @@ -1091,6 +1091,12 @@ module ActiveRecord end end + def structurally_compatible_for_or?(other) + Relation::SINGLE_VALUE_METHODS.all? { |m| send("#{m}_value") == other.send("#{m}_value") } && + (Relation::MULTI_VALUE_METHODS - [:extending]).all? { |m| send("#{m}_values") == other.send("#{m}_values") } && + (Relation::CLAUSE_METHODS - [:having, :where]).all? { |m| send("#{m}_clause") != other.send("#{m}_clause") } + end + def new_where_clause Relation::WhereClause.empty end diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 70da37fa84..5c3318651a 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -10,7 +10,7 @@ module ActiveRecord clone end - # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an <tt>ActiveRecord::Relation</tt>. + # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation. # Returns an array representing the intersection of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array. # Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) ) # # Performs a single join query with both where conditions. diff --git a/activerecord/lib/active_record/relation/where_clause_factory.rb b/activerecord/lib/active_record/relation/where_clause_factory.rb index 23eaab4699..83ac074f97 100644 --- a/activerecord/lib/active_record/relation/where_clause_factory.rb +++ b/activerecord/lib/active_record/relation/where_clause_factory.rb @@ -1,6 +1,6 @@ module ActiveRecord class Relation - class WhereClauseFactory + class WhereClauseFactory # :nodoc: def initialize(klass, predicate_builder) @klass = klass @predicate_builder = predicate_builder diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb index 500c478e65..8e6cd6c82f 100644 --- a/activerecord/lib/active_record/result.rb +++ b/activerecord/lib/active_record/result.rb @@ -1,7 +1,8 @@ module ActiveRecord ### - # This class encapsulates a Result returned from calling +exec_query+ on any - # database connection adapter. For example: + # 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 # => #<ActiveRecord::Result:0xdeadbeef> diff --git a/activerecord/lib/active_record/runtime_registry.rb b/activerecord/lib/active_record/runtime_registry.rb index 9d605b826a..56e88bc661 100644 --- a/activerecord/lib/active_record/runtime_registry.rb +++ b/activerecord/lib/active_record/runtime_registry.rb @@ -7,7 +7,7 @@ module ActiveRecord # # returns the connection handler local to the current thread. # - # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt> + # See the documentation of ActiveSupport::PerThreadRegistry # for further details. class RuntimeRegistry # :nodoc: extend ActiveSupport::PerThreadRegistry diff --git a/activerecord/lib/active_record/sanitization.rb b/activerecord/lib/active_record/sanitization.rb index 7f6664ea50..1cf4b09bf3 100644 --- a/activerecord/lib/active_record/sanitization.rb +++ b/activerecord/lib/active_record/sanitization.rb @@ -3,7 +3,8 @@ module ActiveRecord extend ActiveSupport::Concern module ClassMethods - # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>. + # Used to sanitize objects before they're used in an SQL SELECT statement. + # Delegates to {connection.quote}[rdoc-ref:ConnectionAdapters::Quoting#quote]. def sanitize(object) # :nodoc: connection.quote(object) end @@ -53,8 +54,8 @@ module ActiveRecord end # Accepts a hash of SQL conditions and replaces those attributes - # that correspond to a +composed_of+ relationship with their expanded - # aggregate attribute values. + # that correspond to a {#composed_of}[rdoc-ref:Aggregations::ClassMethods#composed_of] + # relationship with their expanded aggregate attribute values. # # Given: # diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb index c1a42dc629..31dd584538 100644 --- a/activerecord/lib/active_record/schema.rb +++ b/activerecord/lib/active_record/schema.rb @@ -1,5 +1,5 @@ module ActiveRecord - # = Active Record Schema + # = 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 @@ -30,8 +30,9 @@ module ActiveRecord class Schema < Migration # 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+, - # +add_index+, etc.). + # 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): diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb index f049b658c4..e395970dc6 100644 --- a/activerecord/lib/active_record/scoping.rb +++ b/activerecord/lib/active_record/scoping.rb @@ -30,7 +30,7 @@ module ActiveRecord end end - def populate_with_current_scope_attributes + def populate_with_current_scope_attributes # :nodoc: return unless self.class.scope_attributes? self.class.scope_attributes.each do |att,value| @@ -38,7 +38,7 @@ module ActiveRecord end end - def initialize_internals_callback + def initialize_internals_callback # :nodoc: super populate_with_current_scope_attributes end @@ -59,8 +59,8 @@ module ActiveRecord # # 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+ + # 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, diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb index fac566e12b..17bc066e4d 100644 --- a/activerecord/lib/active_record/scoping/default.rb +++ b/activerecord/lib/active_record/scoping/default.rb @@ -55,7 +55,7 @@ module ActiveRecord # # Article.all # => SELECT * FROM articles WHERE published = true # - # The +default_scope+ is also applied while creating/building a record. + # The #default_scope is also applied while creating/building a record. # It is not applied while updating a record. # # Article.new.published # => true @@ -65,7 +65,7 @@ module ActiveRecord # +default_scope+ macro, and it will be called when building the # default scope.) # - # If you use multiple +default_scope+ declarations in your model then + # If you use multiple #default_scope declarations in your model then # they will be merged together: # # class Article < ActiveRecord::Base @@ -76,7 +76,7 @@ module ActiveRecord # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G' # # This is also the case with inheritance and module includes where the - # parent or module defines a +default_scope+ and the child or including + # parent or module defines a #default_scope and the child or including # class defines a second one. # # If you need to do more complex things with a default scope, you can diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb index b2f25752d3..103569c84d 100644 --- a/activerecord/lib/active_record/scoping/named.rb +++ b/activerecord/lib/active_record/scoping/named.rb @@ -9,7 +9,7 @@ module ActiveRecord extend ActiveSupport::Concern module ClassMethods - # Returns an <tt>ActiveRecord::Relation</tt> scope object. + # Returns an ActiveRecord::Relation scope object. # # posts = Post.all # posts.size # Fires "select count(*) from posts" and returns the count @@ -20,7 +20,7 @@ module ActiveRecord # fruits = fruits.limit(10) if limited? # # You can define a scope that applies to all finders using - # <tt>ActiveRecord::Base.default_scope</tt>. + # {default_scope}[rdoc-ref:Scoping::Default::ClassMethods#default_scope]. def all if current_scope current_scope.clone @@ -40,9 +40,10 @@ module ActiveRecord end # Adds a class method for retrieving and querying objects. - # The method is intended to return an <tt>ActiveRecord::Relation</tt> + # The method is intended to return an ActiveRecord::Relation # object, which is composable with other scopes. - # If it returns +nil+ or +false+, an <tt>all</tt> scope is returned instead. + # 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 # <tt>where(color: :red).select('shirts.*').includes(:washing_instructions)</tt>. @@ -52,12 +53,12 @@ module ActiveRecord # scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) } # end # - # The above calls to +scope+ define class methods <tt>Shirt.red</tt> and + # The above calls to #scope define class methods <tt>Shirt.red</tt> and # <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>, in effect, # represents the query <tt>Shirt.where(color: 'red')</tt>. # # You should always pass a callable object to the scopes defined - # with +scope+. This ensures that the scope is re-evaluated each + # 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 @@ -70,15 +71,15 @@ module ActiveRecord # end # # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by - # <tt>Shirt.red</tt> is not an Array but an <tt>ActiveRecord::Relation</tt>, + # <tt>Shirt.red</tt> is not an Array but an ActiveRecord::Relation, # which is composable with other scopes; it resembles the association object - # constructed by a +has_many+ declaration. For instance, you can invoke - # <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>, + # constructed by a {has_many}[rdoc-ref:Associations::ClassMethods#has_many] + # declaration. For instance, you can invoke <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>, # <tt>Shirt.red.where(size: 'small')</tt>. Also, just as with the # association objects, named \scopes act like an Array, implementing # Enumerable; <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>, # and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if - # <tt>Shirt.red</tt> really was an Array. + # <tt>Shirt.red</tt> really was an array. # # These named \scopes are composable. For instance, # <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are @@ -89,7 +90,8 @@ module ActiveRecord # # 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+ associations. If, + # available to {has_many}[rdoc-ref:Associations::ClassMethods#has_many] + # associations. If, # # class Person < ActiveRecord::Base # has_many :shirts @@ -98,8 +100,8 @@ module ActiveRecord # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of # Elton's red, dry clean only shirts. # - # \Named scopes can also have extensions, just as with +has_many+ - # declarations: + # \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 diff --git a/activerecord/lib/active_record/secure_token.rb b/activerecord/lib/active_record/secure_token.rb index ca11853da7..8abda2ac49 100644 --- a/activerecord/lib/active_record/secure_token.rb +++ b/activerecord/lib/active_record/secure_token.rb @@ -3,7 +3,7 @@ module ActiveRecord extend ActiveSupport::Concern module ClassMethods - # Example using has_secure_token + # Example using #has_secure_token # # # Schema: User(token:string, auth_token:string) # class User < ActiveRecord::Base @@ -18,11 +18,11 @@ module ActiveRecord # 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. + # <tt>SecureRandom::base58</tt> 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 - # <tt>validates_uniqueness_of</tt> can. You're encouraged to add a unique index in the database to deal - # with this even more unlikely scenario. + # {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(attribute = :token) # Load securerandom only when has_secure_token is used. require 'active_support/core_ext/securerandom' diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb index 23dc6465af..5a408e7b8e 100644 --- a/activerecord/lib/active_record/serialization.rb +++ b/activerecord/lib/active_record/serialization.rb @@ -1,5 +1,5 @@ module ActiveRecord #:nodoc: - # = Active Record Serialization + # = Active Record \Serialization module Serialization extend ActiveSupport::Concern include ActiveModel::Serializers::JSON diff --git a/activerecord/lib/active_record/statement_cache.rb b/activerecord/lib/active_record/statement_cache.rb index 95986c820c..f6b0efb88a 100644 --- a/activerecord/lib/active_record/statement_cache.rb +++ b/activerecord/lib/active_record/statement_cache.rb @@ -7,12 +7,14 @@ module ActiveRecord # Book.where(name: "my book").where("author_id > 3") # end # - # The cached statement is executed by using the +execute+ method: + # The cached statement is executed by using the + # [connection.execute]{rdoc-ref:ConnectionAdapters::DatabaseStatements#execute} method: # # cache.execute([], Book, Book.connection) # - # The relation returned by the block is cached, and for each +execute+ call the cached relation gets duped. - # Database is queried when +to_a+ is called on the relation. + # The relation returned by the block is cached, and for each + # [execute]{rdoc-ref:ConnectionAdapters::DatabaseStatements#execute} + # call the cached relation gets duped. Database is queried when +to_a+ is called on the relation. # # If you want to cache the statement without the values you can use the +bind+ method of the # block parameter. diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb index 919bc58ba5..1b407f7702 100644 --- a/activerecord/lib/active_record/store.rb +++ b/activerecord/lib/active_record/store.rb @@ -16,7 +16,8 @@ module ActiveRecord # 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 PostgreSQL specific columns like +hstore+ or +json+ there is no need for - # the serialization provided by +store+. Simply use +store_accessor+ instead to generate + # 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. # @@ -43,7 +44,7 @@ module ActiveRecord # store_accessor :settings, :privileges, :servants # end # - # The stored attribute names can be retrieved using +stored_attributes+. + # The stored attribute names can be retrieved using {.stored_attributes}[rdoc-ref:rdoc-ref:ClassMethods#stored_attributes]. # # User.stored_attributes[:settings] # [:color, :homepage] # diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index f1141a8613..ea7927a435 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -5,7 +5,7 @@ module ActiveRecord class DatabaseAlreadyExists < StandardError; end # :nodoc: class DatabaseNotSupported < StandardError; end # :nodoc: - # <tt>ActiveRecord::Tasks::DatabaseTasks</tt> is a utility class, which encapsulates + # 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 Rake tasks provided by Active Record. @@ -18,15 +18,15 @@ module ActiveRecord # # 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. + # * +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: + # Example usage of DatabaseTasks outside Rails could look as such: # # include ActiveRecord::Tasks # DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml') diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index e759475cfb..a572c109d8 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -1,5 +1,5 @@ module ActiveRecord - # = Active Record Timestamp + # = Active Record \Timestamp # # Active Record automatically timestamps create and update operations if the # table has fields named <tt>created_at/created_on</tt> or @@ -17,7 +17,7 @@ module ActiveRecord # # Active Record keeps all the <tt>datetime</tt> and <tt>time</tt> columns # time-zone 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. + # and converted back to the current <tt>Time.zone</tt> when pulled from the database. # # This feature can be turned off completely by setting: # diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 1a2988ea77..8de82feae3 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -17,10 +17,10 @@ module ActiveRecord # = Active Record Transactions # - # Transactions are protective blocks where SQL statements are only permanent + # \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 + # 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. @@ -40,20 +40,20 @@ module ActiveRecord # # == Different Active Record classes in a single transaction # - # Though the transaction class method is called on some Active Record class, + # 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: + # 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. + # The #transaction method is also available as a model instance method. # For example, you can also do this: # # balance.transaction do @@ -80,7 +80,8 @@ module ActiveRecord # # == +save+ and +destroy+ are automatically wrapped in a transaction # - # Both +save+ and +destroy+ come wrapped in a transaction that ensures + # 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 @@ -89,7 +90,7 @@ module ActiveRecord # 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 + # The #after_commit callback is the only one that is triggered once the update # is committed. See below. # # == Exception handling and rolling back @@ -98,11 +99,11 @@ module ActiveRecord # be propagated (after triggering the ROLLBACK), so you should be ready to # catch those in your application code. # - # One exception is the <tt>ActiveRecord::Rollback</tt> exception, which will trigger + # 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 <tt>ActiveRecord::StatementInvalid</tt> exceptions - # inside a transaction block. <tt>ActiveRecord::StatementInvalid</tt> exceptions indicate that an + # *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 @@ -128,11 +129,11 @@ module ActiveRecord # end # # One should restart the entire transaction if an - # <tt>ActiveRecord::StatementInvalid</tt> occurred. + # ActiveRecord::StatementInvalid occurred. # # == Nested transactions # - # +transaction+ calls can be nested. By default, this makes all database + # #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: # @@ -144,7 +145,7 @@ module ActiveRecord # end # end # - # creates both "Kotori" and "Nemu". Reason is the <tt>ActiveRecord::Rollback</tt> + # 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. @@ -171,19 +172,19 @@ module ActiveRecord # http://dev.mysql.com/doc/refman/5.7/en/savepoint.html # for more information about savepoints. # - # === Callbacks + # === \Callbacks # # There are two types of callbacks associated with committing and rolling back transactions: - # +after_commit+ and +after_rollback+. + # #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 + # #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 + # #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 @@ -234,7 +235,7 @@ module ActiveRecord # This callback is called after a create, update, or destroy are rolled back. # - # Please check the documentation of +after_commit+ for options. + # Please check the documentation of #after_commit for options. def after_rollback(*args, &block) set_options_for_callbacks!(args) set_callback(:rollback, :after, *args, &block) @@ -323,7 +324,7 @@ module ActiveRecord _run_before_commit_callbacks end - # Call the +after_commit+ callbacks. + # Call the #after_commit callbacks. # # Ensure that it is not called if the object was never persisted (failed create), # but call it after the commit of a destroyed object. @@ -336,7 +337,7 @@ module ActiveRecord force_clear_transaction_record_state end - # Call the +after_rollback+ callbacks. The +force_restore_state+ argument indicates if the record + # Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record # state should be rolled back to the beginning or just to the last savepoint. def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc: if should_run_callbacks @@ -348,7 +349,7 @@ module ActiveRecord clear_transaction_record_state end - # Add the record to the current transaction so that the +after_rollback+ and +after_commit+ callbacks + # Add the record to the current transaction so that the #after_rollback and #after_commit callbacks # can be called. def add_to_transaction if has_transactional_callbacks? @@ -457,23 +458,23 @@ module ActiveRecord !_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty? end - # Updates the attributes on this particular ActiveRecord object so that - # if it's associated with a transaction, then the state of the ActiveRecord + # 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 + # 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 ActiveRecord object inside of a transaction carries that transaction's + # 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 ActiveRecord object + # the TransactionState, and rolls back or commits the Active Record object # as appropriate. # - # Since ActiveRecord objects can be inside multiple transactions, this + # Since Active Record objects can be inside multiple transactions, this # method recursively goes through the parent of the TransactionState and - # checks if the ActiveRecord object reflects the state of the object. + # checks if the Active Record object reflects the state of the object. def sync_with_transaction_state update_attributes_from_transaction_state(@transaction_state) end diff --git a/activerecord/lib/active_record/type.rb b/activerecord/lib/active_record/type.rb index 74dfe88349..e210e94f00 100644 --- a/activerecord/lib/active_record/type.rb +++ b/activerecord/lib/active_record/type.rb @@ -22,13 +22,13 @@ module ActiveRecord delegate :add_modifier, to: :registry # Add a new type to the registry, allowing it to be referenced as a - # symbol by ActiveRecord::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 + # 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 <tt>adapter: :postgresql</tt>. 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. + # raised unless you specify an +:override+ option. <tt>override: true</tt> will + # cause your type to be used instead of the native type. <tt>override: + # false</tt> will cause the native type to be used over yours if one exists. def register(type_name, klass = nil, **options, &block) registry.register(type_name, klass, **options, &block) end diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 4113ca4561..6677e6dc5f 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -1,8 +1,9 @@ module ActiveRecord - # = Active Record RecordInvalid + # = Active Record \RecordInvalid # - # Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the - # +record+ method to retrieve the record which did not validate. + # 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! @@ -25,26 +26,26 @@ module ActiveRecord end end - # = Active Record Validations + # = Active Record \Validations # - # Active Record includes the majority of its validations from <tt>ActiveModel::Validations</tt> + # Active Record includes the majority of its validations from ActiveModel::Validations # all of which accept the <tt>:on</tt> argument to define the context where the # validations are active. Active Record will always supply either the context of # <tt>:create</tt> or <tt>:update</tt> dependent on whether the model is a - # <tt>new_record?</tt>. + # {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 <tt>validate: false</tt>. - # The regular Base#save method is replaced with this when the validations - # module is mixed in, which it is by default. + # 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(options={}) perform_validations(options) ? super : false end - # Attempts to save the record just like Base#save but will raise a +RecordInvalid+ - # exception instead of returning +false+ if the record is not valid. + # Attempts to save the record just like {ActiveRecord::Base#save}[rdoc-ref:Base#save] but + # will raise a ActiveRecord::RecordInvalid exception instead of returning +false+ if the record is not valid. def save!(options={}) perform_validations(options) ? super : raise_validation_error end @@ -52,12 +53,12 @@ module ActiveRecord # Runs all the validations within the specified context. Returns +true+ if # no errors are found, +false+ otherwise. # - # Aliased as validate. + # Aliased as #validate. # # If the argument is +false+ (default is +nil+), the context is set to <tt>:create</tt> if - # <tt>new_record?</tt> is +true+, and to <tt>:update</tt> if it is not. + # {new_record?}[rdoc-ref:Persistence#new_record?] is +true+, and to <tt>:update</tt> if it is not. # - # Validations with no <tt>:on</tt> option will run no matter the context. Validations with + # \Validations with no <tt>:on</tt> option will run no matter the context. \Validations with # some <tt>:on</tt> option will only run in the specified context. def valid?(context = nil) context ||= default_validation_context diff --git a/activerecord/lib/active_record/validations/associated.rb b/activerecord/lib/active_record/validations/associated.rb index 47ccef31a5..32fbaf0a91 100644 --- a/activerecord/lib/active_record/validations/associated.rb +++ b/activerecord/lib/active_record/validations/associated.rb @@ -24,7 +24,8 @@ module ActiveRecord # # 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+. + # guaranteed to be valid, you also need to use + # {validates_presence_of}[rdoc-ref:Validations::ClassMethods#validates_presence_of]. # # Configuration options: # diff --git a/activerecord/lib/active_record/validations/presence.rb b/activerecord/lib/active_record/validations/presence.rb index 23a3985d35..7e85ed43ac 100644 --- a/activerecord/lib/active_record/validations/presence.rb +++ b/activerecord/lib/active_record/validations/presence.rb @@ -31,7 +31,7 @@ module ActiveRecord # This is due to the way Object#blank? handles boolean values: # <tt>false.blank? # => true</tt>. # - # This validator defers to the ActiveModel validation for presence, adding the + # 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 @@ -39,7 +39,8 @@ module ActiveRecord # # 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+. + # it is both present and valid, you also need to use + # {validates_associated}[rdoc-ref:Validations::ClassMethods#validates_associated]. # # Configuration options: # * <tt>:message</tt> - A custom error message (default is: "can't be blank"). @@ -57,7 +58,7 @@ module ActiveRecord # or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The method, # proc or string should return or evaluate to a +true+ or +false+ value. # * <tt>:strict</tt> - Specifies whether validation should be strict. - # See <tt>ActiveModel::Validation#validates!</tt> for more information. + # See ActiveModel::Validation#validates! for more information. def validates_presence_of(*attr_names) validates_with PresenceValidator, _merge_attributes(attr_names) end diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 5706bbd903..aa2794f120 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -172,7 +172,8 @@ module ActiveRecord # # === Concurrency and integrity # - # Using this validation method in conjunction with ActiveRecord::Base#save + # 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 @@ -209,12 +210,12 @@ module ActiveRecord # This could even happen if you use transactions with the 'serializable' # isolation level. The best way to work around this problem is to add a unique # index to the database table using - # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the - # rare case that a race condition occurs, the database will guarantee + # {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 will raise an ActiveRecord::StatementInvalid + # {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 |