A belongs_to relationship creates a one-to-one correspondence with another model. In database terms, this relationship says that this class contains a foreign key. If the foreign key contains another class, has_one should be used instead.
Methods added by belongs_to
When you declare a belongs_to relationship, the declaring class automatically receives five methods related to the relationship:
association
association=(associate)
build_association(attributes = {})
create_association(attributes = {})
create_association!(attributes = {})
reload_association
In all four methods, association is replaced by the character passed as the first argument to belongs_to. For example, we have a declaration:
classBook < ApplicationRecord
belongs_to :author
end
Each instance of the Book model will have these methods:
author
author=
build_author
create_author
create_author!
reload_author
NOTE: When establishing a new has_one or belongs_to association, you must use the build_ prefix to build the association, as opposed to the association.build method used for has_many or has_and_belongs_to_many associations. To create an association, use the create_ prefix.
association
The association method returns the associated object, if any. If there is no object, returns nil.
@author = @book.author
If the associated object has already been retrieved from the database for that object, the cached version is returned. To override this behavior (and force it to read from the database), call #reload_association on the parent object.
@author = @book.reload_author
association=(associate)
The association= method binds an associated object to that object. In effect, this means extracting the primary key from the related entity and assigning its value to the foreign key.
@book.author = @author
build_association(attributes = {})
The build_association method returns a new object of the associated type. This object will be an instance with the attributes passed in, a relationship will be established with the foreign key of this object, but the associated object will not be saved yet.
@author = @book.build_author(author_number: 123,
author_name: “John Doe”)
create_association(attributes = {})
The create_association method returns a new object of the associated type. This entity will be an instance with the attributes passed in, a relationship will be established with the entity’s foreign key, and if it passes the validations defined in the associated model, the associated entity will be saved.
@author = @book.create_author(author_number: 123,
author_name: “John Doe”)
create_association!(attributes = {})
Works the same as create_association above, but calls ActiveRecord::RecordInvalid if the record is invalid.
(options-for-belongs-to) Options for belongs_to
While Rails uses reasonable defaults that work in many situations, there are times when you want to change the behavior of a belongs_to relationship. This customization is easily done by passing options and scoped blocks when creating a link. For example, this link uses two of these options:
classBook < ApplicationRecord
belongs_to :author, dependent: :destroy,
counter_cache: true
end
The belongs_to relationship supports these options:
:autosave
:class_name
:counter_cache
:dependent
:foreign_key
:primary_key
:inverse_of
:polymorphic
:touch
:validate
:optional
:autosave
If you set the :autosave option to true, Rails will save any loaded related members and destroy members marked for destruction whenever the parent object is saved. But setting :autosave to false is not the same as not setting the :autosave option. If the :autosave option is not present, then new related objects will be saved, but updated related objects will not be saved.
:class_name
If the name of another model cannot be derived from the link name, you can use the :class_name option to provide the name of the model. For example, if the book is owned by the author, but the actual name of the model containing the authors is Patron, you can set this as follows:
classBook < ApplicationRecord
belongs_to :author, class_name: “Patron”
end
:counter_cache
The :counter_cache option can be used to make finding the number of owned objects more efficient. Consider these models:
classBook < ApplicationRecord
belongs_to :author
end
classAuthor<ApplicationRecord
has_many:books
end
With these declarations, requesting the @author.books.size value requires a database call to execute the COUNT(*) request. To avoid this, you can add a counter cache to the owned model:
classBook < ApplicationRecord
belongs_to :author, counter_cache: true
end
classAuthor<ApplicationRecord
has_many:books
end
With this declaration, Rails will cache the actual value and then return that value in response to the size method.
:polymorphic
Passing true for the :polymorphic option indicates that this is a polymorphic relationship. Polymorphic relationships have been discussed in detail previously.
:touch
If you set the :touch option to true, then the updated_at or updated_on timestamps on the associated object will be set to the current time whenever that object is saved or destroyed:
classBook < ApplicationRecord
belongs_to :author, touch: true
end
classAuthor<ApplicationRecord
has_many:books
end
In this case, saving or destroying the book will update the timestamp on the associated author. You can also define a specific timestamp attribute to update:
classBook < ApplicationRecord
belongs_to :author, touch: :books_updated_at
end
:validate
If you set the :validate option to true, then related objects will be validated whenever you save that object. It defaults to false: related objects are not validated when this object is saved.
:optional
If you set :optional to true, then the presence of related objects will not be validated. The default is set to false.
Scopes for belongs_to
Sometimes you want to customize the query used by belongs_to. Such customization can be achieved with a scope block. For example:
classBook < ApplicationRecord
belongs_to :author, -> { where active: true },
dependent: :destroy
end
Within a scope block, any standard query methods can be used. Next, we will discuss the following ones:
where
includes
readonly
select
where
The where method allows you to specify the conditions that the associated object must meet.
classBook < ApplicationRecord
belongs_to :author, -> { where active: true }
end
includes
The includes method can be used to define second-order relationships that should be lazily loaded when using this relationship. For example, consider these models:
class LineItem < ApplicationRecord
belongs_to :book
end
classBook < ApplicationRecord
belongs_to :author
has_many :line_items
end
classAuthor<ApplicationRecord
has_many:books
end
If you often get authors directly from the elements (@line_item.book.author), then you can improve code efficiency by including the authors in the relationship between the book and its elements: NOTE: There is no need to use includes for nearest links – that is, if there is a Book belongs_to :author , the author is automatically lazy loaded when needed.