从表单为联接表创建新记录。选择输入

时间:2018-07-19 06:56:45

标签: ruby-on-rails

使用RoR的第一步,试图将我的头放在基本概念上。练习之后:我有学生和班级,都是Active Record实体,彼此之间有很多对很多(has_and_belongs_to_many)。现在,我有了一个创建新学生的表格。在此表单上还有一个表单。选择来为学生选择班级,但是我无法使它起作用,我无法让控制器为联接表创建新记录。

Schoolclass.rb

class Schoolclass < ApplicationRecord
  has_and_belongs_to_many :pupils
end

Pupil.rb

class Pupil < ApplicationRecord
  has_and_belongs_to_many :schoolclasses
end

_form.html.erb的相关部分

<div class="field">
  <%= form.label :schoolclass %>
  <%= form.select(schoolclass.id, schoolclasses_for_select) %>
</div>

schoolclasses_for_select只是用于填充选择框的帮助器

def schoolclasses_for_select
  Schoolclass.all.collect{ |s| [s.name, s.schoolyear] }
end

我在控制器上尝试的所有操作都失败了。不知何故,我最终以控制器试图将schoolclass(作为字符串)作为属性传递给新Pupil或以MethodNotFound错误结束。以我的理解,它应该像这样工作:

@klass = params[:schoolclass]
pupil.schoolclasses << @klass

但不是。

在此先感谢您的帮助。

Edit1:创建代码

def create        
  @pupil = Pupil.new(pupil_params)

  respond_to do |format|
  if @pupil.save       
    format.html { redirect_to @pupil, notice: 'Pupil was successfully created.' }
    format.json { render :show, status: :created, location: @pupil }
  else
    format.html { render :new }
    format.json { render json: @pupil.errors, status: :unprocessable_entity }
  end
end

结束

def pupil_params
  params.require(:pupil).permit(:nachname, :vorname, :schoolclass)
end

那是起作用的部分。我没有设法找到正确的Schoolclass记录并将其传递给学生。

1 个答案:

答案 0 :(得分:1)

问题

  • 您的form.select的第一个参数应为字段名称,即:schoolclass_id。您仍然可以保留标签Schoolclass
  • 我相信您希望id的学校课程在选定时通过参数传递。为此,请将您的选择选项更改为Schoolclass.all.collect{ |s| [s.name, s.id] }
  • 最大,您的协会说,一个学生可以上多个课,但是您的表格不支持。您以其他方式处理了吗?

修复

因此,请执行以下操作(这不支持多个学校班级选择):

<%= form.select :schoolclass_id, Schoolclass.all.collect{ |s| [s.name, s.id] } %>

在您的控制器中

def create        
  @pupil = Pupil.new(pupil_params)

  # Find schoolclass from `schoolclass_id` and associate it to `@pupil`
  schoolclass = Schoolclass.find(params[:pupil][:schoolclass_id])  # Handle case when schoolclass not selected in form
  @pupil.schoolclasses |= [schoolclass]

  respond_to do |format|
    ...
  end
end

private

def pupil_params
  params.require(:pupil).permit(:nachname, :vorname)
end