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.
1class Entry < ApplicationRecord 2 # Schema 3 # entryable_type, entryable_id, ... 4 delegated_type :entryable, types: %w[ Message Comment ] 5end 6 7class Message 8 # Schema 9 # subject, ... 10end 11 12class Comment 13 # Schema 14 # content, ... 15end
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.
1class Entry < ApplicationRecord 2 delegated_type :entryable, types: %w[ Message Comment ] 3 accepts_nested_attributes_for :entryable 4end 5 6params = { 7 entry: { 8 entryable_type: 'Message', 9 entryable_attributes: { subject: 'Delegated Type' } 10 } 11} 12 13message_entry = Entry.create(params[:entry]) 14 15params = { 16 entry: { 17 entryable_type: 'Comment', 18 entryable_attributes: { content: 'Looks Cool!' } 19 } 20} 21 22comment_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.
1class Entry < ApplicationRecord 2 def self.create_with_comment(content) 3 # Validation logic goes here 4 create! entryable: Comment.new(content: content) 5 end 6end
Please check out this pull request for more details.