“一对多”Rails表单创建

时间:2014-08-30 14:31:36

标签: ruby-on-rails

我有一个班级协会有很多学生。我想创建一个表格,我可以创建一个学生,并为他分配一个教室。我在创建表单时遇到了问题。

模型/ classroom.rb

class Classroom < ActiveRecord::Base
  has_many :students
end

模型/ student.rb

class Student < ActiveRecord::Base
  belongs_to :classroom
end

我想创建一个新学生并将其分配到某个教室。

<%= form_for(@student) do |f|%>


<%= f.label :name %>
<%= f.text_field :name %>

<br />
<br />

<%= f.label :student.classroom.number %>       #Is this correct? 
<%= f.text_field :student.classroom.number %>  #Is this correct?

<%= f.submit %>

<%end%>

每个模型的属性都是

1.9.3-p448 :026 > Classroom
 => Classroom(id: integer, number: string, created_at: datetime, updated_at: datetime) 
1.9.3-p448 :027 > Student
 => Student(id: integer, name: string, created_at: datetime, updated_at: datetime, classroom_id: string) 

students_controller

class StudentsController < ApplicationController
  def index
    @students = Student.all
  end

  def show
    @student = Student.find(params[:id])
  end

  def new
    @student = Student.new
  end

  def create
    @student = Student.new(article_params)
    respond_to do |format|
    if @student.save
      format.html {redirect_to(@student, notice: 'Student was successfully created.')}
    else
      format.html {render action: "new"}
    end
end
  end

  private
    def article_params
      params.require(:student).permit(:name, :classroom_id)
    end
  end

classroom_controller

class ClassroomsController < ApplicationController
  def index
    @classrooms = Classroom.all
  end

  def show
    @classroom = Classroom.find(params[:id])
  end

  def new
    @classroom = Classroom.new
  end

  def create
    @classroom = Classroom.new(article_params)
    respond_to do |format|
    if @classroom.save
      format.html {redirect_to(@classroom, notice: 'Classroom was successfully created.')}
    else
      format.html {render action: "new"}
    end  
end
  end

  private
    def article_params
      params.require(:classroom).permit(:number)
    end
  end

2 个答案:

答案 0 :(得分:1)

假设您要将Student分配给现有的Classroom

首先,确保Student模型在attr_accessible中具有以下内容:

attr_accessible :classroom_id

在您的表单中,您应该可以执行以下操作:

,而不是您的第二个标签/ text_field
<%= f.label :classroom %>
<%= f.select(:classroom_id, Classroom.all.pluck(:number)) %>

请注意,对于f.select方法,您必须传递您正在设置的属性,而不是关联名称(即classroom_id而不是classroom

另请注意,最佳做法是将与从模型(即Classroom.all.pluck(:number))收集信息相关联的逻辑移动到控制器中的实例变量中,

e.g。 @classrooms = Classroom.all.pluck(:number)

并在视图中使用@classrooms实例变量。

除此之外,您还应该阅读更多有关符号的内容。你在:student.classroom.number尝试过的事情并没有按照你的想法去做。这里有一个很好的问题:When to use symbols instead of strings in Ruby?

答案 1 :(得分:1)

如果您已经知道要将他添加到哪个教室,您可以设置隐藏字段将其设置为教室本身:

<%= f.hidden_field, :classroom_id, value: here_you_put_the_classroom_id $>

不要忘记在控制器允许的参数中添加:classroom_id。

如果您希望选择选择要放入学生的教室,您可以采取另一种方法,您可以创建一个通过所有教室的选择字段。

<% classroom_array = Classroom.all.map { |classroom| [classroom.name, classroom.id] } %>
<%= options_for_select(classroom_array) %>

不要忘记再次添加允许的参数。 希望它有所帮助。

<强> *** *** UPDATE

options_for_select应该在de select标签内,如下所示:

<% classroom_array = Classroom.all.map { |classroom| [classroom.number, classroom.id] } %> 
<%= f.label :classroom %> 
<%= f.select(:classroom_id, options_for_select(classroom_array)) %>

***更新2 ***

只要您将教室ID作为参数传递,Pluck也可以是一个选项。因此,代码可以重构为:

<%= f.label :classroom %>
<%= f.select :classroom_id, Classroom.all.pluck(:name, :id) %>