Rails 7 adds accepts_nested_attributes_for support for delegated_type

Ashik Salman

Ashik Salman

November 23, 2021

This blog is part of our  Rails 7 series.

Rails 6.1 introduced the delegated_type to Active Record which makes it easier for models to share responsibilities. Please see our blog to read more about delegated_type.

class Entry < ApplicationRecord
  # Schema
  #  entryable_type, entryable_id, ...
  delegated_type :entryable, types: %w[ Message Comment ]
end

class Message
  # Schema
  #  subject, ...
end

class Comment
  # Schema
    #  content, ...
end

The accepts_nested_attributes_for option is very helpful while handling nested forms. We can easily create and update associated records by passing details along with main object parameters when the accepts_nested_attributes_for option is enabled.

Before

The accepts_nested_attributes_for option is not available for delegated_type, hence we can't use nested forms for associated objects configured via delegated_type.

Rails 7 onwards

Rails 7 adds accepts_nested_attributes_for support to delegated_type, which allows to create and update records easily without needing to write specific methods or logic.

class Entry < ApplicationRecord
  delegated_type :entryable, types: %w[ Message Comment ]
  accepts_nested_attributes_for :entryable
end

params = {
  entry: {
    entryable_type: 'Message',
    entryable_attributes: { subject: 'Delegated Type' }
  }
}

message_entry = Entry.create(params[:entry])

params = {
  entry: {
    entryable_type: 'Comment',
    entryable_attributes: { content: 'Looks Cool!' }
  }
}

comment_entry = Entry.create(params[:entry])

If we want to deal with more logic or validations while creating the entryable objects, we'll have to create a method specifically and do the logic there.

class Entry < ApplicationRecord
  def self.create_with_comment(content)
    # Validation logic goes here
    create! entryable: Comment.new(content: content)
  end
end

Please 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.