April 6, 2021
This blog is part of our Rails 7 series.
build_association
and create_association
constructors?When we declare either a belongs_to
or has_one
association,
the declaring class automatically gains the following methods
related to the association:
In the above methods
_association
is replaced with the symbol(association name)
passed as the first argument while declaring the associations.
For example:
class Book < ApplicationRecord
belongs_to :author
end
@book.build_author(name: 'John Doe', email: '[email protected]')
#=> Returns a new Author object, instantiated with the passed attributes
#=> Links through the book's object foreign key
#=> New author object won't be saved in the database
@book.create_author(name: 'John Doe', email: '[email protected]')
#=> Returns a new Author object, instantiated with the passed attributes
#=> Links through the book's object foreign key
#=> The new author object will be saved in the database after passing all of the validations specified on the Author model
The build_association
and create_association
constructors
were only supported by
belongs_to
and has_one
associations.
Consider the example below.
We have a model, Member,
that has a has_one
association
with the CurrentMembership model.
It also has a has_one :through
association
with the Club model.
class Member < ApplicationRecord
has_one :current_membership
has_one :club, through: :current_membership
end
@member.build_club
#=> NoMethodError (undefined method `build_club' for #<Member:0x00007f9ea2ebd3e8>)
#=> Did you mean? build_current_membership
@member.create_club
#=> NoMethodError (undefined method `create_club' for #<Member:0x00007f9ea2ebd3e8>)
#=> Did you mean? create_current_membership
Users are allowed to use constructors
(build_association
and create_association
)
on has_one :through
associations
along with belongs_to
and has_one
associations.
class Member < ApplicationRecord
has_one :current_membership
has_one :club, through: :current_membership
end
@member.build_club
#=> #<Club:0x00007f9ea01a8ce0>
@member.create_club
#=> #<Club:0x00007f9ea01a8ce0>
Check out this pull request for more details.
If this blog was helpful, check out our full blog archive.