Forms for nested objects in Rails
I am having trouble creating a form to edit StudentReferrals
. Each Student has some basic information like name/birthday/studentid. In addition to that information, students are referred to take a list of classes. I want to have a form that allows someone to fill out the student info, and then select up to 10 classes that the student is required to take. In addition to the classes, each "Student+Course" combo has a credits_required
field that says how many credits of a class that student is required to take.
The list of classes that a student can take comes from the Course
model
I have 3 models:
class StudentReferral < ActiveRecord::Base
has_many :student_referral_courses, :dependent => :destroy
has_many :courses, :through => :student_referral_courses
# Fields: name, studentid, advisor_name, birthday
end
class StudentReferralCourse < ActiveRecord::Base
belongs_to :student_referral
belongs_to :course
validates_presence_of :credits_required
# Fields: (student_referral_id, course_id, credits_required)
attr_accessor :course1, ..., :course9
attr_accessor :credits1, ..., :credits9
after_create :add_courses
def add_courses
self.student_referral_courses.destroy_all
unless self.course1.blank?
self.student_referral_courses.create! :course_id => self.course1, :student_referral_id => self.id, :credits_required => self.credits1
end
unless self.course2.blank?
self.student_referral_courses.create! :course_id => self.course2, :student_referral_id => self.id, :credits_required => self.credits2
end
...
end
class Course < ActiveRecord::Base
# Fields: department, name
end
And I have a form to created/edit the student referrals that is like the following:
<%= form_for(@student_referral) do |f| %>
<% if @student_referral.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@student_referral.errors.count, "error") %> prohibited this student referral from being saved:</h2>
<ul>
<% @student_referral.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset class="form">
<legend>Student Information</legend>
<table cellpadding="3" cellspacing="0" border="0" class="vert">
<tr><th class="subr"><%= f.label :studentid %></th><td><%= f.text_field :studentid %></td></tr>
<tr><th class="subr"><%= f.label :name %></th><td><%= f.text_field :name %></td></tr>
<tr><th class="subr"><%= f.label :birthday %></th><td><%= f.date_select :birthday, :start_year => 1990 %></td></tr>
<tr><th class="subr"><%= f.label :advisor %></th><td><%= f.text_field :advisor %></td></tr>
</table>
</fieldset>
<fieldset class="form">
<legend>Course Information</legend>
&开发者_如何转开发lt;span>You <b>MUST</b> select the credits required for each course.</span>
<ol>
<li><%= select(:student_referral, :course1, Course.all(:order => "dept,name ASC").collect {|p| [ "#{p.dept}: #{p.name}", p.id ] }, { :include_blank => '' })%>
<%= select_tag 'student_referral[credits1]', options_for_select(['Select One',5.0,4.5,4.0,3.5,3.0,2.5,2.0,1.5,1.0,0.5]) %></li>
<li><%= select(:student_referral, :course2, Course.all(:order => "dept,name ASC").collect {|p| [ "#{p.dept}: #{p.name}", p.id ] }, { :include_blank => '' })%>
<%= select_tag 'student_referral[credits2]', options_for_select(['Select One',5.0,4.5,4.0,3.5,3.0,2.5,2.0,1.5,1.0,0.5]) %></li>
...
</ol>
</fieldset>
<%= f.submit :class => "l-button black" %>
<% end %>
My problem is that I cannot seem to create or edit any of these records without doing a terrible hack using the validation. I have 10 attr_accessible
fields for course1
to course9
and same for credits that I use on an after_create
macro. However, this does not let me see any validation errors from the course (like if they do not put any credits)
I tried using accepts_nested_attributes_for :student_referral_courses
but I can't seem to get it to do what I want. I really want to do this the Rails way and I feel like I am doing a terrible hack.
Try adding the has_many :through's to course i.e.
class Course < ActiveRecord::Base
has_many :student_referrals, :dependent => :destroy
has_many :student_referral_courses, :through => :student_referrals
end
精彩评论