module ActiveRecord::Associations::ClassMethods

def belongs_to(name, scope = nil, options = {})

belongs_to :company, touch: :employees_last_updated_at
belongs_to :company, touch: true
belongs_to :post, counter_cache: true
belongs_to :project, readonly: true
belongs_to :attachable, polymorphic: true
class_name: "Coupon", foreign_key: "coupon_id"
belongs_to :valid_coupon, ->(o) { where "discounts > #{o.payments_count}" },
belongs_to :author, class_name: "Person", foreign_key: "author_id"
belongs_to :person, primary_key: "name", foreign_key: "person_name"
belongs_to :firm, foreign_key: "client_of"
Option examples:

See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
combination with the :polymorphic options.
object that is the inverse of this belongs_to association. Does not work in
Specifies the name of the has_one or has_many association on the associated
[:inverse_of]
will be updated with the current time in addition to the updated_at/on attribute.
when this record is either saved or destroyed. If you specify a symbol, that attribute
If true, the associated object will be touched (the updated_at/on attributes set to now)
[:touch]
Note that accepts_nested_attributes_for sets :autosave to true.

By default, only save the associated object if it's a new record.
If false, never save or destroy the associated object.
saving the parent object.
If true, always save the associated object or destroy it if marked for destruction, when
[:autosave]
If +false+, don't validate the associated objects when saving the parent object. +false+ by default.
[:validate]
to the +attr_readonly+ list in the associated classes (e.g. class Post; attr_readonly :comments_count; end).
Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
Specify this association is a polymorphic association by passing +true+.
[:polymorphic]
using +attr_readonly+.
Note: Specifying a counter cache will add it to that model's list of readonly attributes
option (e.g., counter_cache: :my_custom_counter.)
cache column by providing a column name instead of a +true+/+false+ value to this
return the count cached, see note below). You can also specify a custom counter
#{table_name}_count is created on the associate class (such that Post.comments_count will
is used on the associate class (such as a Post class) - that is the migration for
named #{table_name}_count (such as +comments_count+ for a belonging Comment class)
class is created and decremented when it's destroyed. This requires that a column
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 +increment_counter+
[:counter_cache]
orphaned records behind.
a has_many relationship on another class because of the potential to leave
This option should not be specified when belongs_to is used in conjunction with
:delete, the associated object is deleted *without* calling its destroy method.
If set to :destroy, the associated object is destroyed when this object is. If set to
[:dependent]
By default this is id.
Specify the method that returns the primary key of associated object used for the association.
[:primary_key]
association will use "taggable_type" as the default :foreign_type.
suffix. So a class that defines a belongs_to :taggable, polymorphic: true
association. By default this is guessed to be the name of the association with a "_type"
Specify the column used to store the associated object's type, if this is a polymorphic
[:foreign_type]
of "favorite_person_id".
belongs_to :favorite_person, class_name: "Person" will use a foreign key
association will use "person_id" as the default :foreign_key. Similarly,
of the association with an "_id" suffix. So a class that defines a belongs_to :person
Specify the foreign key used for the association. By default this is guessed to be the name
[:foreign_key]
if the real class name is Person, you'll have to specify it with this option.
from the association name. So belongs_to :author will by default be linked to the Author class, but
Specify the class name of the association. Use it only if that name can't be inferred
[:class_name]

=== Options

The declaration can also include an options hash to specialize the behavior of the association.
* Post#create_author! (similar to post.author = Author.new; post.author.save!; post.author)
* Post#create_author (similar to post.author = Author.new; post.author.save; post.author)
* Post#build_author (similar to post.author = Author.new)
* Post#author=(author) (similar to post.author_id = author.id)
* Post#author (similar to Author.find(author_id))
A Post class declares belongs_to :author, which will add:

=== Example

belongs_to :author would add among others author.nil?.)
(+association+ is replaced with the symbol passed as the first argument, so

if the record is invalid.
Does the same as create_association, but raises ActiveRecord::RecordInvalid
[create_association!(attributes = {})]
has already been saved (if it passed the validation).
with +attributes+, linked to this object through a foreign key, and that
Returns a new object of the associated type that has been instantiated
[create_association(attributes = {})]
with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
Returns a new object of the associated type that has been instantiated
[build_association(attributes = {})]
Assigns the associate object, extracts the primary key, and sets it as the foreign key.
[association=(associate)]
Returns the associated object. +nil+ is returned if none is found.
[association(force_reload = false)]

this object holds an id:
Methods will be added for retrieval and query for a single associated object, for which

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
if this class contains the foreign key. If the other class contains the foreign key,
Specifies a one-to-one association with another class. This method should only be used
def belongs_to(name, scope = nil, options = {})
  reflection = Builder::BelongsTo.build(self, name, scope, options)
  Reflection.add_reflection self, name, reflection
end

def has_and_belongs_to_many(name, scope = nil, options = {}, &extension)

has_and_belongs_to_many :categories, -> { readonly }
has_and_belongs_to_many :categories, join_table: "prods_cats"
has_and_belongs_to_many :nations, class_name: "Country"
has_and_belongs_to_many :projects, -> { includes :milestones, :manager }
has_and_belongs_to_many :projects
Option examples:

Note that accepts_nested_attributes_for sets :autosave to true.

By default, only save associated objects that are new records.
If false, never save or destroy the associated objects.
saving the parent object.
If true, always save the associated objects or destroy them if marked for destruction, when
[:autosave]
If +false+, don't validate the associated objects when saving the parent object. +true+ by default.
[:validate]
If true, all the associated objects are readonly through the association.
[:readonly]
the association will use "project_id" as the default :association_foreign_key.
So if a Person class makes a +has_and_belongs_to_many+ association to Project,
By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
Specify the foreign key used for the association on the receiving side of the association.
[:association_foreign_key]
default :foreign_key.
a +has_and_belongs_to_many+ association to Project will use "person_id" as the
of this class in lower-case and "_id" suffixed. So a Person class that makes
Specify the foreign key used for the association. By default this is guessed to be the name
[:foreign_key]
MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work.
WARNING: If you're overwriting the table name of either class, the +table_name+ method
Specify the name of the join table if the default based on lexical order isn't what you want.
[:join_table]
Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
from the association name. So has_and_belongs_to_many :projects will by default be linked to the
Specify the class name of the association. Use it only if that name can't be inferred
[:class_name]

=== Options

The declaration may include an options hash to specialize the behavior of the association.
* Developer#projects.create (similar to c = Project.new("developer_id" => id); c.save; c)
* Developer#projects.build (similar to Project.new("developer_id" => id))
* Developer#projects.exists?(...)
* Developer#projects.find(id)
* Developer#projects.size
* Developer#projects.empty?
* Developer#projects.clear
* Developer#project_ids=
* Developer#project_ids
* Developer#projects=
* Developer#projects.destroy
* Developer#projects.delete
* Developer#projects<<
* Developer#projects
A Developer class declares has_and_belongs_to_many :projects, which will add:

=== Example

has_and_belongs_to_many :categories would add among others categories.empty?.)
(+collection+ is replaced with the symbol passed as the first argument, so

saved (if it passed the validation).
with +attributes+, linked to this object through the join table, and that has already been
Returns a new object of the collection type that has been instantiated
[collection.create(attributes = {})]
with +attributes+ and linked to this object through the join table, but has not yet been saved.
Returns a new object of the collection type that has been instantiated
[collection.build(attributes = {})]
Uses the same rules as ActiveRecord::Base.exists?.
Checks whether an associated object with the given conditions exists.
[collection.exists?(...)]
Uses the same rules as ActiveRecord::Base.find.
meets the condition that it has to be associated with this object.
Finds an associated object responding to the +id+ and that
[collection.find(id)]
Returns the number of associated objects.
[collection.size]
Returns +true+ if there are no associated objects.
[collection.empty?]
Removes every object from the collection. This does not destroy the objects.
[collection.clear]
Replace the collection by the objects identified by the primary keys in +ids+.
[collection_singular_ids=ids]
Returns an array of the associated objects' ids.
[collection_singular_ids]
Replaces the collection's content by deleting and adding objects as appropriate.
[collection=objects]
This does not destroy the objects.
Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
[collection.destroy(object, ...)]
This does not destroy the objects.
Removes one or more objects from the collection by removing their associations from the join table.
[collection.delete(object, ...)]
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
(collection.push and collection.concat are aliases to this method).
Adds one or more objects to the collection by creating associations in the join table
[collection<<(object, ...)]
An empty array is returned if none are found.
Returns an array of all the associated objects.
[collection(force_reload = false)]

Adds the following methods for retrieval and query:

uses one index per table during the lookup.
However, in MySQL it is advised to add a compound index for both of the columns as MySQL only
It's also a good idea to add indexes to each of those columns to speed up the joins process.

end
end
end
t.integer :project_id
t.integer :developer_id
create_table :developers_projects, id: false do |t|
def change
class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration

join table with a migration such as this:
The join table should not have a primary key or a model associated with it. You must manually generate the

the tables "catalog_categories" and "catalog_products" generate a join table name of "catalog_categories_products".
If your tables share a common prefix, it will only appear once at the beginning. For example,
custom :join_table option if you need to.
but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the
to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes",
lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers"
up to the shortest length, then the longer string is considered of higher
means that if the strings are of different lengths, and the strings are equal when compared
Note that this precedence is calculated using the < operator for String. This
will give the default join table name of "developers_projects" because "D" precedes "P" alphabetically.
guessed using the lexical order of the class names. So a join between Developer and Project
intermediate join table. Unless the join table is explicitly specified as an option, it is
Specifies a many-to-many relationship with another class. This associates two classes via an
def has_and_belongs_to_many(name, scope = nil, options = {}, &extension)
  if scope.is_a?(Hash)
    options = scope
    scope   = nil
  end
  builder = Builder::HasAndBelongsToMany.new name, self, options
  join_model = builder.through_model
  middle_reflection = builder.middle_reflection join_model
  Builder::HasMany.define_callbacks self, middle_reflection
  Reflection.add_reflection self, middle_reflection.name, middle_reflection
  include Module.new {
    class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def destroy_associations
      association(:#{middle_reflection.name}).delete_all(:delete_all)
      association(:#{name}).reset
      super
    end
    RUBY
  }
  hm_options = {}
  hm_options[:through] = middle_reflection.name
  hm_options[:source] = join_model.right_reflection.name
  [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate].each do |k|
    hm_options[k] = options[k] if options.key? k
  end
  has_many name, scope, hm_options, &extension
end

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

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 = 0").order("name") }, class_name: "Person"
has_many :comments, -> { includes :author }
has_many :comments, -> { order "posted_on" }
Option examples:

See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
with :through or :as options.
that is the inverse of this has_many association. Does not work in combination
Specifies the name of the belongs_to association on the associated object
[:inverse_of]
Note that accepts_nested_attributes_for sets :autosave to true.

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 +false+, don't validate the associated objects 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]
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]
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 exception to be raised if there are any associated records.
* :nullify causes the foreign keys to be set to +NULL+. Callbacks are not executed.
* :delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
* :destroy causes all the associated objects to also be destroyed.

: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 method that returns the primary key used for the association. By default this is +id+.
[:primary_key]
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

The declaration can also include an options hash to specialize the behavior of the association.
* 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

has_many :clients would add among others clients.empty?.)
(*Note*: +collection+ is replaced with the symbol passed as the first argument, so

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::Base.exists?.
Checks whether an associated object with the given conditions exists.
[collection.exists?(...)]
Finds an associated object according to the same rules as ActiveRecord::Base.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]
direct.
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, ...)]
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 array is returned if none are found.
Returns an array of all the associated objects.
[collection(force_reload = false)]

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

def has_one(name, scope = nil, options = {})

has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable
has_one :club, through: :membership
has_one :boss, readonly: :true
has_one :attachment, as: :attachable
has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person"
has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment"
# key value to NULL rather than destroying it
has_one :credit_card, dependent: :nullify # updates the associated records foreign
has_one :credit_card, dependent: :destroy # destroys the associated credit card
Option examples:

See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
with :through or :as options.
that is the inverse of this has_one association. Does not work in combination
Specifies the name of the belongs_to association on the associated object
[:inverse_of]
Note that accepts_nested_attributes_for sets :autosave to true.

By default, only save the associated object if it's a new record.
when saving the parent object. If false, never save or destroy the associated object.
If true, always save the associated object or destroy it if marked for destruction,
[:autosave]
If +false+, don't validate the associated object when saving the parent object. +false+ by default.
[:validate]
association is a polymorphic +belongs_to+.
Specifies type of the source association used by has_one :through queries where the source
[:source_type]
:favorite on Favorite, unless a :source is given.
has_one :favorite, through: :favorites will look for a
Only use it if the name cannot be inferred from the association.
Specifies the source association name used by has_one :through queries.
[:source]
or belongs_to association on the join model.
source reflection. You can only use a :through query through a has_one
:primary_key, and :foreign_key are ignored, as the association uses the
Specifies a Join Model through which to perform the query. Options for :class_name,
[:through]
Specifies a polymorphic interface (See belongs_to).
[:as]
Specify the method that returns the primary key used for the association. By default this is +id+.
[:primary_key]
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_one+ association
Specify the foreign key used for the association. By default this is guessed to be the name
[:foreign_key]
* :restrict_with_error causes an error to be added to the owner if there is an associated object
* :restrict_with_exception causes an exception to be raised if there is an associated record
* :nullify causes the foreign key to be set to +NULL+. Callbacks are not executed.
* :delete causes the associated object to be deleted directly from the database (so callbacks will not execute)
* :destroy causes the associated object to also be destroyed

its owner is destroyed:
Controls what happens to the associated object when
[:dependent]
if the real class name is Person, you'll have to specify it with this option.
from the association name. So has_one :manager will by default be linked to the Manager class, but
Specify the class name of the association. Use it only if that name can't be inferred
[:class_name]
Options are:

The declaration can also include an options hash to specialize the behavior of the association.

=== Options

* Account#create_beneficiary! (similar to b = Beneficiary.new("account_id" => id); b.save!; b)
* Account#create_beneficiary (similar to b = Beneficiary.new("account_id" => id); b.save; b)
* Account#build_beneficiary (similar to Beneficiary.new("account_id" => id))
* Account#beneficiary=(beneficiary) (similar to beneficiary.account_id = account.id; beneficiary.save)
* Account#beneficiary (similar to Beneficiary.where(account_id: id).first)
An Account class declares has_one :beneficiary, which will add:

=== Example

has_one :manager would add among others manager.nil?.)
(+association+ is replaced with the symbol passed as the first argument, so

if the record is invalid.
Does the same as create_association, but raises ActiveRecord::RecordInvalid
[create_association!(attributes = {})]
has already been saved (if it passed the validation).
with +attributes+, linked to this object through a foreign key, and that
Returns a new object of the associated type that has been instantiated
[create_association(attributes = {})]
yet been saved.
with +attributes+ and linked to this object through a foreign key, but has not
Returns a new object of the associated type that has been instantiated
[build_association(attributes = {})]
associated object when assigning a new one, even if the new one isn't saved to database.
and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
Assigns the associate object, extracts the primary key, sets it as the foreign key,
[association=(associate)]
Returns the associated object. +nil+ is returned if none is found.
[association(force_reload = false)]

The following methods for retrieval and query of a single associated object will be added:

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
if the other class contains the foreign key. If the current class contains the foreign key,
Specifies a one-to-one association with another class. This method should only be used
def has_one(name, scope = nil, options = {})
  reflection = Builder::HasOne.build(self, name, scope, options)
  Reflection.add_reflection self, name, reflection
end