module ActiveRecord::Associations::ClassMethods

def has_many(name, scope = nil, **options, &extension)

has_many :comments, strict_loading: true
has_many :subscribers, through: :subscriptions, disable_joins: true
has_many :subscribers, through: :subscriptions, source: :user
has_many :reports, -> { readonly }
has_many :tags, as: :taggable
has_many :comments, dependent: :nullify
has_many :tracks, -> { order("position") }, dependent: :destroy
has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person"
has_many :comments, -> { includes(:author) }
has_many :comments, -> { order("posted_on") }
Option examples:

associated records to be deleted in a background job.
Specifies an instance method to be called on the owner. The method must return true in order for the
[:ensuring_owner_was]
association.
When set to +true+, enforces strict loading every time the associated record is loaded through this
[:strict_loading]
association objects.
Useful for defining methods on associations, especially when they should be shared between multiple
Specifies a module or array of modules that will be extended into the association object returned.
[:extend]
See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
that is the inverse of this #has_many association.
Specifies the name of the #belongs_to association on the associated object
[:inverse_of]
:autosave to true.
Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets

may need to be explicitly saved in any user-defined +before_save+ callbacks.
+before_save+ callback. Because callbacks are run in the order they are defined, associated objects
By default, only save associated objects that are new records. This option is implemented as a
when saving the parent object. If false, never save or destroy the associated objects.
If true, always save the associated objects or destroy them if marked for destruction,
[:autosave]
If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
[:validate]
association is a polymorphic #belongs_to.
Specifies type of the source association used by #has_many :through queries where the source
[:source_type]
:subscriber on Subscription, unless a :source is given.
has_many :subscribers, through: :subscriptions will look for either :subscribers or
Only use it if the name cannot be inferred from the association.
Specifies the source association name used by #has_many :through queries.
[:source]
+has_many+ alone do not perform a join.
due to database limitations. This option is only applicable on has_many :through associations as
will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
Specifies whether joins should be skipped for an association. If set to true, two or more queries
[:disable_joins]
section above.)
the appropriate join model records when they are saved. (See the 'Association Join Models'
join model. This allows associated records to be built which will automatically create
a good idea to set the :inverse_of option on the source association on the
If you are going to modify the association (rather than just read from it), then it is

:through association directly.
as appropriate. Otherwise, the collection is read-only, so you should manipulate the
and the records on the :through model will be automatically created and removed
If the association on the join model is a #belongs_to, the collection can be modified

source reflection.
:primary_key and :foreign_key are ignored, as the association uses the
of association, including other :through associations. Options for :class_name,
Specifies an association through which to perform the query. This can be any other type
[:through]
Specifies a polymorphic interface (See #belongs_to).
[:as]
when you customized the name of your :counter_cache on the #belongs_to association.
This option can be used to configure a custom named :counter_cache. You only need this option,
[:counter_cache]
database would still contain a foreign key pointing to the now deleted post.
called on a post, only published comments are destroyed. This means that any unpublished comments in the
has_many :comments, -> { where published: true }, dependent: :destroy and destroy is
For example, if a Post model defines
If using dependent: :destroy on a scoped association, only the scoped objects are destroyed.

the associated records.
a #belongs_to, and the records which get deleted are the join records, rather than
If using with the :through option, the association on the join model must be

* :restrict_with_error causes an error to be added to the owner if there are any associated objects.
* :restrict_with_exception causes an ActiveRecord::DeleteRestrictionError exception to be raised if there are any associated records.
on polymorphic associations. Callbacks are not executed.
* :nullify causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
* :delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
constraint actions will occur inside the same transaction that deletes its owner.
this option if the association is backed by foreign key constraints in your database. The foreign key
* :destroy_async destroys all the associated objects in a background job. WARNING: Do not use
* :destroy causes all the associated objects to also be destroyed.
* nil do nothing (default).

:dependent behavior may affect other callbacks.
similar callbacks may affect the :dependent behavior, and the
callbacks, and Rails executes callbacks in order. Therefore, other
their owner is destroyed. Note that these are implemented as
Controls what happens to the associated objects when
[:dependent]
Specify the name of the column to use as the primary key for the association. By default this is +id+.
[:primary_key]
default :foreign_type.
has_many :tags, as: :taggable association will use "taggable_type" as the
specified on "as" option with a "_type" suffix. So a class that defines a
association. By default this is guessed to be the name of the polymorphic association
Specify the column used to store the associated object's type, if this is a polymorphic
[:foreign_type]
a good idea to set the :inverse_of option.
If you are going to modify the association (rather than just read from it), then it is

association will use "person_id" as the default :foreign_key.
of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
Specify the foreign key used for the association. By default this is guessed to be the name
[:foreign_key]
specify it with this option.
to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
from the association name. So has_many :products will by default be linked
Specify the class name of the association. Use it only if that name can't be inferred
[:class_name]
=== Options

end
end
find_or_create_by(first_name: first_name, last_name: last_name)
first_name, last_name = name.split(" ", 2)
def find_or_create_by_name(name)
has_many :employees do
Extension examples:

factory-type methods to be used as part of the association.
association. This is useful for adding new finders, creators, and other
The +extension+ argument allows you to pass a block into a has_many

=== Extensions

has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
has_many :employees, -> { joins(:address) }
has_many :comments, -> { where(author_id: 1) }
Scope examples:

query when you access the associated collection.
lambda) to retrieve a specific set of records or customize the generated
You can pass a second argument +scope+ as a callable (i.e. proc or

=== Scopes

The declaration can also include an +options+ hash to specialize the behavior of the association.
* Firm#clients.reload
* Firm#clients.create! (similar to c = Client.new(firm_id: id); c.save!)
* Firm#clients.create (similar to c = Client.new(firm_id: id); c.save; c)
* Firm#clients.build (similar to Client.new(firm_id: id))
* Firm#clients.exists?(name: 'ACME') (similar to Client.exists?(name: 'ACME', firm_id: firm.id))
* Firm#clients.find (similar to Client.where(firm_id: id).find(id))
* Firm#clients.size (similar to Client.count "firm_id = #{id}")
* Firm#clients.empty? (similar to firm.clients.size == 0)
* Firm#clients.clear
* Firm#client_ids=
* Firm#client_ids
* Firm#clients=
* Firm#clients.destroy
* Firm#clients.delete
* Firm#clients<<
* Firm#clients (similar to Client.where(firm_id: id))
A Firm class declares has_many :clients, which will add:

=== Example

An empty Relation is returned if none are found.
Returns a Relation of all of the associated objects, forcing a database read.
[collection.reload]
if the record is invalid.
Does the same as collection.create, but raises ActiveRecord::RecordInvalid
[collection.create!(attributes = {})]
already exists in the DB, not if it is a new (unsaved) record!
been saved (if it passed the validation). *Note*: This only works if the base model
with +attributes+, linked to this object through a foreign key, and that has already
Returns a new object of the collection type that has been instantiated
[collection.create(attributes = {})]
been saved.
with +attributes+ and linked to this object through a foreign key, but have not yet
Returns one or more new objects of the collection type that have been instantiated
[collection.build(attributes = {}, ...)]
Uses the same rules as ActiveRecord::FinderMethods#exists?.
Checks whether an associated object with the given conditions exists.
[collection.exists?(...)]
Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
[collection.find(...)]
Returns the number of associated objects.
[collection.size]
Returns +true+ if there are no associated objects.
[collection.empty?]
Join models are directly deleted.
If the :through option is true no destroy callbacks are invoked on the join models.
database if dependent: :delete_all, otherwise sets their foreign keys to +NULL+.
are associated with dependent: :destroy, deletes them directly from the
Removes every object from the collection. This destroys the associated objects if they
[collection.clear]
method loads the models and calls collection=. See above.
Replace the collection with the objects identified by the primary keys in +ids+. This
[collection_singular_ids=ids]
Returns an array of the associated objects' ids
[collection_singular_ids]
dependent: :nullify to override this.
direct by default. You can specify dependent: :destroy or
option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
Replaces the collections content by deleting and adding objects as appropriate. If the :through
[collection=objects]
instead, not the objects themselves.
If the :through option is used, then the join records are destroyed

each record, regardless of any dependent option, ensuring callbacks are run.
Removes one or more objects from the collection by running destroy on
[collection.destroy(object, ...)]
dependent: :nullify to override this.
nullified) by default, but you can specify dependent: :destroy or
If the :through option is used, then the join records are deleted (rather than

and deleted if they're associated with dependent: :delete_all.
Objects will be in addition destroyed if they're associated with dependent: :destroy,
Removes one or more objects from the collection by setting their foreign keys to +NULL+.
[collection.delete(object, ...)]
This will also run validations and callbacks of associated object(s).
parent object, unless the parent object is a new record.
Note that this operation instantly fires update SQL without waiting for the save or update call on the
Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
[collection<<(object, ...)]
An empty Relation is returned if none are found.
Returns a Relation of all the associated objects.
[collection]

has_many :clients would add among others clients.empty?.
+collection+ is a placeholder for the symbol passed as the +name+ argument, so

collections of associated objects will be added:
Specifies a one-to-many association. The following methods for retrieval and query of
def has_many(name, scope = nil, **options, &extension)
  reflection = Builder::HasMany.build(self, name, scope, options, &extension)
  Reflection.add_reflection self, name, reflection
end