Is there a way to update a field relative to a many-to-many associations via form_for?
Theses are my models:
class Grad < ActiveRecord::Base
belongs_to :school
has_many :grad_courses
has_many :courses, through: :grad_courses
accepts_nested_attributes_for :grad_courses, :courses
end
class Course < ActiveRecord::Base
belongs_to :school
has_many :grad_courses
has_many :grads, through: :grad_courses
end
class GradCourse < ActiveRecord::Base
belongs_to :grad
belongs_to :course
end
Here is the many-to-many migration with the extra property (semester):
create_table "grad_courses", force: :cascade do |t|
t.integer "grad_id"
t.integer "course_id"
t.integer "semester"
t.datetime "created_at"
t.datetime "updated_at"
end
What i'm trying to do is add and update the relations with the semester information dynamically with a form collection set (using form_for and chosen).
<%= form_for @grad, html: {class: "form-horizontal"} do |f| %>
...
<% (1..@grad.max).each do |semester| %>
<div class="form-group">
<%= f.label :course_ids, "#{semester}º semestre", class: "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= f.collection_select :course_ids, @courses, :id, :name, {include_blank: true}, {multiple: true, :class=>'chosen-select form-control'} %>
</div>
</div>
<% end %>
...
<% end %>
This way, it is creating and updating the grad_courses, but without the semester.
I've tried lot of things, but didn't had success.
I'm able to manage the semester's info directly, like in this post: http://stackoverflow.com/questions/2168442/many-to-many-relationship-with-the-same-model-in-rails#=
I could pass an array with a hidden field, and manage the form manually, but it would take too much work, so I was wondering if there is an easy way to do this.
Something like :grad_course[:course_id][:semester] in :grad params? Is it possible?
the grad_course_controller:
def update
respond_to do |format|
if @grad.update(grad_params)
format.html { redirect_to @grad, notice: 'Cursos adicionados com sucesso' }
else
format.html { render :edit }
end
end
end
private
def set_grad
@grad = Grad.find(params[:id])
end
def set_courses
@courses = Course.where(school_id: @grad.school_id)
@gc = GradCourse.where(grad_id: @grad.id)
end
list through.
def grad_params
params.require(:grad).permit(:name, :min, :max, :school_id, course_ids: [] )
end
Update
I've been trying to solve this using Peter's advices, so I tried nested_attributes and fields_for. But I'm having problems with it too.
I need one collection_sellect for each semester (from 1 to Grad.max number), where the options will be the courses available for that semester (@courses), and for the selected ones a grad_course relation needs to be created or updated.
The problem with field_for is that one field is generated for every grad_course relation, and since each field is related with the grad_course.id I`m not able to add new ones properly.
Here is one of the tries i've made with fields for:
<%= f.fields_for :grad_courses do |builder| %>
<p>
<%= builder.text_field :semester %><br />
<%= builder.collection_select :course_id, @courses, :id, :name, {include_blank: true}, {multiple: true, :class=>'chosen-select form-control'} %>
</p>
<% end %>
with these changes in the grad_controller:
def grad_params
params.require(:grad).permit(:name, :min, :max, :school_id, course_ids: [], grad_courses_attributes: [:id, :course_id, :grad_id, :semester ])
end