I'm working on a project for a class where I have a very large form with Nested Models. Here are the models that are important to the form, as well as their associations:
Course: has_many :time_blocks, has_many :tags, through: :taggings, belongs_to :institution, has_many :roles, has_many :users, through: :roles
TimeBlock: belongs_to :course
- Tag: has_many :taggings
- Tagging: belongs_to :tag, belongs_to :taggable_type
- Institution: has_many :courses, has_many :users
- Role: belongs_to :course, belongs_to :user
I am able to create the Nested Form correctly, but I can't get the Nested Models to update correctly. Here is the controller, the form is very long, but I have provided the params for the Nested Models. Note, I cleared out the values from the params, but some of the params have ID values because they exist in the db. I've also included the CoursesHelper to show the helper methods I'm using in the controller.
app/controllers/courses_controller.rb
def new
@course = current_user.courses.new
@course.institution = Institution.new
4.times { @course.tags.build }
7.times { @course.time_blocks.build }
end
def create
@course = Course.new(params[:course])
@course.institution = Institution.new(params[:institution])
filled_tags = set_tags(params[:tag])
@course.tags.build(filled_tags)
filled_time_blocks = set_time_blocks(params[:time_block])
@course.time_blocks.build(filled_time_blocks)
if @course.save
Role.create!(
user_id: current_user.id,
course_id: @course.id,
title: 'instructor'
)
redirect_to @course
else
(4 - filled_tags.count).times { @course.tags.build }
(7 - filled_time_blocks.count).times { @course.time_blocks.build }
flash.now[:errors] = @course.errors.full_messages
render :new
end
end
def edit
end
def update
filled_time_blocks = set_time_blocks(params[:time_block])
filled_time_blocks.each do |time_block|
@course.time_blocks.update_attributes(time_block)
end
filled_tags = set_tags(params[:tag])
filled_tags.each { |tag| @course.tags.update_attributes(tag) }
# @course.tags.update_attributes(filled_tags)
# @course.time_blocks.update_attributes(filled_time_blocks)
fail
if @course.update_attributes(params[:course])
redirect_to @course
else
flash.now[:errors] = @course.errors.full_messages
render :edit
end
end
app/helpers/courses_helper.rb
def set_time_blocks(entries)
result = []
days = entries[:day_of_week].reject! { |day| day.blank? }
days.each do |day|
time_block = {}
time_block[:day_of_week] = day
time_block[:start_time] = entries[day][:start_time]
time_block[:end_time] = entries[day][:end_time]
time_block[:id] = entries[day][:id]
result << time_block
end
result
end
def set_tags(entries)
[].tap do |tags|
entries.each do |entry|
tags << entry unless entry.values.all?(&:blank?)
end
end
end
def find_course
if params.include?(:id)
@course = Course.find(params[:id])
else
flash[:notice] = "Sorry, Could Not Find Course."
redirect_to current_user
end
end
TimeBlock Params
{"sun"=>{"start_time"=>"", "end_time"=>"", "id"=>""}, "mon"=>{"start_time"=>"", "end_time"=>"", "id"=>"3"}, "tue"=>{"start_time"=>"", "end_time"=>"", "id"=>"4"}, "wed"=>{"start_time"=>"", "end_time"=>"", "id"=>"5"}, "thu"=>{"start_time"=>"", "end_time"=>"", "id"=>"6"}, "fri"=>{"start_time"=>"", "end_time"=>"", "id"=>"7"}, "sat"=>{"start_time"=>"", "end_time"=>"", "id"=>""}, "day_of_week"=>[]}
Tag Params
[{"name"=>"", "id"=>"4"}, {"name"=>"", "id"=>""}, {"name"=>"", "id"=>""}, {"name"=>"", "id"=>""}]
accepts_nested_attributes_for
? – sevenseacataccepts_nested_attributes_for
you should not be writing any manual code. – KULKING