我怎样才能建立这种特定的关系?

时间:2018-02-23 18:07:21

标签: ruby-on-rails

  • 学校有一个或多个教师,教师有一个或多个科目

同一位教师可以在不同的学校和不同的科目教学,例如:

Dan在学校A和B学校的物理课程中教授英语和数学

我尝试在这三种模式之间使用了很多,但我不知道如何在特定教师中添加许多学校和许多科目

这是我试过的

class Teacher < ApplicationRecord
    has_many :school_teacher_subjects
    has_many :schools, through: :school_teacher_subjects
    has_many :subjects, through: :school_teacher_subjects
end

class School < ApplicationRecord
    has_many :school_teacher_subjects
    has_many :teachers, through: :school_teacher_subjects
    has_many :subjects, through: :school_teacher_subjects
end

class Subject < ApplicationRecord   
    has_many :school_teacher_subjects
    has_many :teachers, through: :school_teacher_subjects
    has_many :schools, through: :school_teacher_subjects
end

class SchoolTeacherSubject < ApplicationRecord
  belongs_to :teacher
  belongs_to :school
  belongs_to :subject
end

我想要的是,在教师新/编辑表格中,我可以通过这种方式同时在数据库中保存一个或多个学校和一个或多个科目:

+----+------------+-----------+------------+
| id | teacher_id | school_id | subject_id |
+----+------------+-----------+------------+
|  1 |          2 |         2 |          4 |
|  2 |          2 |         2 |          1 |
|  3 |          1 |         3 |          2 |
|  4 |          1 |         3 |          6 |
+----+------------+-----------+------------+

但我所能做的就是:

+----+------------+-----------+------------+
| id | teacher_id | school_id | subject_id |
+----+------------+-----------+------------+
| 72 |          8 |         2 |          2 |
| 74 |          2 |           |          2 |
| 75 |          2 |           |          6 |
| 76 |          1 |         3 |            |
| 77 |          1 |           |          2 |
| 78 |          1 |           |          6 |
+----+------------+-----------+------------+

我在做什么:

我的控制器和表格

def new
    @teacher = Teacher.new
    @schools = School.all.order(name: :asc)
    @subjects = Subject.all.order(name: :asc)
end

def edit
    @teacher = Teacher.find(params[:id])
    @schools = School.all.order(name: :asc)
    @subjects = Subject.all.order(name: :asc)
end

def create
    @teacher = Teacher.new(teacher_params)

    respond_to do |format|
      if @teacher.save
        format.html { redirect_to  admin_teacher_index_path, notice: 'Escola criada com sucesso.' }
      else
        format.html { render :new }
      end
    end
end

def update
    @teacher = Teacher.find(params[:id])

    respond_to do |format|
      if @teacher.update(teacher_params)
        format.html { redirect_to  admin_teacher_index_path, notice: 'Escola editada com sucesso.' }
      else
        format.html { render :edit }
      end
    end
end

private
    def teacher_params
      params.require(:teacher).permit(:full_name, :genre, :status, school_ids: [], subject_ids: [])
    end

FORM.HTML.ERB

<div class="row mb-3">
    <div class="col">
        <%= f.label :school_ids, 'Escolas(s)' %>
        <%= f.collection_select(:school_ids, @schools, :id, :name, {:include_blank => "Selecione uma ou mais"}, {:class => "multiple-select2 custom-select", multiple: true}) %>
    </div>
</div>

<div class="row mb-3">
    <div class="col">
        <%= f.label :subject_ids, 'Disciplina(s)' %>
        <%= f.collection_select(:subject_ids, @subjects, :id, :name, {:include_blank => "Selecione uma ou mais"}, {:class => "multiple-select2 custom-select", multiple: true}) %>
    </div>
</div>

1 个答案:

答案 0 :(得分:1)

您遇到的一个问题是,教师可以在许多学校教授许多科目,但在您的表格中,您可以独立选择学校和科目。学校和科目必须一起选择。我不认为你可以通过两个多选并传递两个数组(school_ids和subject_ids)来实现。事实上,教师可以在两所学校教授一门课程,这不能用你的表格来实施。你需要一个更复杂的形式。我会以一种形式,你可以使用cocoon gem动态添加新行(科目和学校相关)。

<强>模型

class Teacher < ApplicationRecord
  has_many :school_teacher_subjects
  has_many :schools, through: :school_teacher_subjects
  has_many :subjects, through: :school_teacher_subjects
  # NEW
  accept_nested_attributes_for :school_teacher_subjects, 
      reject_if: :all_blank, allow_destroy: true
end

class School < ApplicationRecord
  has_many :school_teacher_subjects
  has_many :teachers, through: :school_teacher_subjects
  has_many :subjects, through: :school_teacher_subjects
end

class Subject < ApplicationRecord   
  has_many :school_teacher_subjects
  has_many :teachers, through: :school_teacher_subjects
  has_many :schools, through: :school_teacher_subjects
end

class SchoolTeacherSubject < ApplicationRecord
  belongs_to :teacher
  belongs_to :school
  belongs_to :subject
end

<强>控制器

private
  def teacher_params
    # CHANGED
    params.require(:teacher).permit(:full_name, :genre, :status,
      :school_teacher_subjects_attributes => [ :school_id, :subject_id, :id, :_destroy ])
  end

查看(主要表单):

<Teacher fields (fullname, genre, status, etc)>
<.............................................>

<div class="row mb-3">
  <div class="col">
    <%= f.simple_fields_for :school_teacher_subjects do |sts| %>
      <%= render 'sts_fields', f: sts %>
    <% end %>
    <%= link_to_add_association 'Add new class', f, 
      :school_teacher_subjects,
      :partial => 'sts_fields', 
      :force_non_association_create => true,
      :data => {"association-insertion-method" => "before", "association-insertion-node" => 'this'}
    %>

  </div>
</div>

查看(主题和学校的部分表格)sts_fields.html.erb:

<div class="nested-fields">
  <div class="row">
    <div class="col-xs-2">
      <%= link_to_remove_association 'Remove', f %>
    </div>
    <div class="col-xs-5">
      <%= f.collection_select :subject_id, @subjects, :id, :name %>
    </div>
    <div class="col-xs-5">
      <%= f.collection_select :school_id, @schools, :id, :name %>
    </div>
  </div>
</div>