Rails 7 allows constructors (build_association and create_association) on has_one :through associations

Akanksha Jain

Akanksha Jain

April 6, 2021

This blog is part of our  Rails 7 series.


What are 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:

  1. build_association(attributes = {})
  2. create_association(attributes = {})

In the above methods _association is replaced with the symbol(association name) passed as the first argument while declaring the associations. For example:

1class Book < ApplicationRecord
2  belongs_to :author
3end
4
5@book.build_author(name: 'John Doe', email: '[email protected]')
6#=> Returns a new Author object, instantiated with the passed attributes
7#=> Links through the book's object foreign key
8#=> New author object won't be saved in the database
9
10@book.create_author(name: 'John Doe', email: '[email protected]')
11#=> Returns a new Author object, instantiated with the passed attributes
12#=> Links through the book's object foreign key
13#=> The new author object will be saved in the database after passing all of the validations specified on the Author model

Before Rails 7

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.

1class Member < ApplicationRecord
2  has_one :current_membership
3  has_one :club, through: :current_membership
4end
5
6@member.build_club
7#=> NoMethodError (undefined method `build_club' for #<Member:0x00007f9ea2ebd3e8>)
8#=> Did you mean?  build_current_membership
9
10@member.create_club
11#=> NoMethodError (undefined method `create_club' for #<Member:0x00007f9ea2ebd3e8>)
12#=> Did you mean?  create_current_membership

After Rails 7

Users are allowed to use constructors (build_association and create_association) on has_one :through associations along with belongs_to and has_one associations.

1class Member < ApplicationRecord
2  has_one :current_membership
3  has_one :club, through: :current_membership
4end
5
6@member.build_club
7#=> #<Club:0x00007f9ea01a8ce0>
8
9@member.create_club
10#=> #<Club:0x00007f9ea01a8ce0>

Check out this pull request for more details.

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.