Nested attributes let you save data for related models in one form. It helps keep things simple when models are connected.
Nested attributes in Ruby on Rails
class ParentModel < ApplicationRecord
has_many :child_models
accepts_nested_attributes_for :child_models
endUse accepts_nested_attributes_for in the parent model to allow nested data.
Rails will handle saving or updating the child models automatically.
class Book < ApplicationRecord
has_many :chapters
accepts_nested_attributes_for :chapters
endclass Author < ApplicationRecord
has_one :profile
accepts_nested_attributes_for :profile
endallow_destroy: true lets you delete child records through the form.class Project < ApplicationRecord
has_many :tasks
accepts_nested_attributes_for :tasks, allow_destroy: true
endThis example shows a Library model with many Books. The form sends nested book data inside the library data. The controller permits nested attributes and saves all together.
class Library < ApplicationRecord has_many :books accepts_nested_attributes_for :books end # In controller class LibrariesController < ApplicationController def new @library = Library.new @library.books.build end def create @library = Library.new(library_params) if @library.save redirect_to @library else render :new end end private def library_params params.require(:library).permit(:name, books_attributes: [:title, :author]) end end # Example params from form: # { # library: { # name: "City Library", # books_attributes: { # "0" => { title: "Ruby Basics", author: "Jane" }, # "1" => { title: "Rails Guide", author: "John" } # } # } # }
Remember to permit nested attributes in the controller using permit.
Use build to prepare nested objects for the form.
Nested attributes work best for simple related data, not very complex associations.
Nested attributes let you save parent and child models together.
Use accepts_nested_attributes_for in the parent model.
Permit nested params in the controller to allow saving related data.
Practice
accepts_nested_attributes_for do in a Rails model?Solution
Step 1: Understand the purpose of
This method is used in a parent model to allow it to accept attributes for its associated child models.accepts_nested_attributes_forStep 2: Recognize what it enables in Rails
It enables saving or updating child model data through the parent model's form or controller.Final Answer:
Allows a parent model to accept and save attributes for its associated child models. -> Option CQuick Check:
accepts_nested_attributes_for = Accept nested child attributes [OK]
- Confusing it with database table creation
- Assuming it validates nested attributes automatically
- Thinking it generates controller code
tasks inside a parent model?Solution
Step 1: Identify the correct argument type
The method expects a symbol representing the association name, which is plural if the association is has_many.Step 2: Match the association name
Since the child model istasks(plural), the correct syntax isaccepts_nested_attributes_for :tasks.Final Answer:
accepts_nested_attributes_for :tasks -> Option AQuick Check:
Use symbol with plural association name [OK]
- Using singular instead of plural for has_many
- Passing string instead of symbol
- Omitting colon before association name
Project with nested tasks_attributes?
class Project < ApplicationRecord
has_many :tasks
accepts_nested_attributes_for :tasks
end
class Task < ApplicationRecord
belongs_to :project
end
# In ProjectsController
params = { project: { name: 'Build App', tasks_attributes: [{ title: 'Design UI' }, { title: 'Write Tests' }] } }
@project = Project.new(params[:project])
@project.saveSolution
Step 1: Check model setup for nested attributes
The Project model usesaccepts_nested_attributes_for :tasks, allowing nested task attributes.Step 2: Analyze controller params and save
The params includetasks_attributeswith two tasks. CallingProject.newwith these params and thensavewill save the project and its tasks together.Final Answer:
A new project and two associated tasks will be saved in the database. -> Option AQuick Check:
Nested attributes save parent and children together [OK]
- Assuming tasks are ignored without explicit permit
- Thinking save fails without controller strong params shown
- Believing tasks save without association
def project_params params.require(:project).permit(:name, tasks_attributes: [:title]) end @project = Project.new(project_params) @project.saveAssuming the models are set up correctly with
accepts_nested_attributes_for :tasks.Solution
Step 1: Understand strong parameters for nested attributes
When updating nested records, Rails expects the:idkey to identify existing child records.Step 2: Check the permit call
Thepermitcall only allows:titleinsidetasks_attributes, missing:id. This causes update failures or errors.Final Answer:
Thepermitmethod is missing the:idkey insidetasks_attributes. -> Option DQuick Check:
Permit :id for nested updates [OK]
- Omitting :id in nested strong params
- Confusing require and permit methods
- Placing accepts_nested_attributes_for in controller
Survey model with many questions. You want to allow users to add, update, and remove questions through the survey form. Which combination of code is needed to correctly handle nested attributes and allow question removal?Solution
Step 1: Enable nested attributes with destroy option
To allow removal of nested records,accepts_nested_attributes_formust includeallow_destroy: true.Step 2: Permit necessary keys in controller
The controller must permit:idto identify records,:contentfor data, and:_destroyto mark records for deletion.Final Answer:
In Survey model: accepts_nested_attributes_for :questions, allow_destroy: true In controller: permit questions_attributes with :id, :content, :_destroy -> Option BQuick Check:
allow_destroy and permit :_destroy for removals [OK]
- Forgetting allow_destroy in model
- Not permitting :_destroy in strong params
- Permitting only :content without :id
Ready to prove it?
Pass the test and this pattern moves unknown
