Формы для вложенных объектов в Rails - PullRequest
2 голосов
/ 17 сентября 2011

У меня проблемы с созданием формы для редактирования StudentReferrals. Каждый студент имеет некоторую основную информацию, такую ​​как имя / день рождения / студент. В дополнение к этой информации учащиеся должны взять список классов. Я хочу, чтобы у меня была форма, позволяющая кому-то заполнить информацию о студенте, а затем выбрать до 10 классов, которые студент должен пройти. В дополнение к классам, каждая комбинация «Студент + курс» имеет поле credits_required, в котором указано, сколько кредитов за класс требуется для этого студента.

Список классов, которые может взять студент, взят из Course модели

У меня есть 3 модели:

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

И у меня есть форма для создания / редактирования рефералов учащихся, которая выглядит следующим образом:

<%= 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>
<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 %>

Моя проблема в том, что я не могу создать или отредактировать какую-либо из этих записей без ужасного взлома с использованием проверки. У меня есть 10 attr_accessible полей для course1 до course9 и то же самое для кредитов, которые я использую в макросе after_create. Тем не менее, это не позволяет мне видеть какие-либо ошибки проверки курса (например, если они не ставят кредиты)

Я пытался использовать accepts_nested_attributes_for :student_referral_courses, но я не могу заставить его делать то, что я хочу. Я действительно хочу сделать это в стиле Rails и чувствую, что совершаю ужасный хак.

1 Ответ

0 голосов
/ 23 сентября 2011

Попробуйте добавить has_many: through's к курсу, т.е.

class Course < ActiveRecord::Base<br> has_many :student_referrals, :dependent => :destroy<br> has_many :student_referral_courses, :through => :student_referrals<br> end

...