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