以 rails 方式编辑关联模型

Editing associated models the rails way

我有一个模型"Student"和每个学生has_manyparents(parentstable中的母亲和父亲)。在我的 UI 中,我希望能够在同一页面上添加 parents 和学生。因此,当我单击 "Add student" 时,将呈现视图 'students/new'。在这个视图中,到目前为止,我有添加学生 (<% form_for @student....) 的常规内容。但是现在我还想在同一页面上提供为这个学生添加母亲和父亲的表格。我知道我可以在某个地方放置一个 link 到 'parents/new',但我认为那不是真正的 user-friendly。

我有哪些选择,你会推荐什么?

在您的 form 中,您可以添加 fields_for 助手

<%= fields_for @student.father do |father| %>
  <% father.text_field :name %> # will be appropriate father name
  ....
<% end %>

也检查rails fields_for

您最好的选择是使用 nested_formsaccepts_nested_attributes_for,如下所示

#student.rb
Class Student < ActiveRecord::Base
has_many :parents
accepts_nested_attributes_for :parents
end

#students_controller.rb

def new
@student = Student.new
@student.parents.build
end

def create
@student = Student.new(student_params)
if @student.save
redirect_to @student
else
render 'new'
end

private

def student_params
params.require(:student).permit(:id, :student_attr_1, :student_attrr_2, parents_attributes: [:id, :father, :mother])
end

#students/new

<%= form_for @student do |f| %>
---student code here ---
<%= f.fields_for :parents do |p| %>
<%= p.label :father, :class => "control-label" %>
<%= p.text_field :father %>
<%= p.label :fmother, :class => "control-label" %>
<%= p.text_field :mother %>
<% end %>

我会使用 ObjectForm 概念:

Here is one good article about this pattern.

下面是实现的介绍:

Class Student < ActiveRecord::Base
  has_many :parents
end

class CompleteStudentForm
  include ActiveModel::Model

  attr_acessor :name, :age #student attributes
  attr_accessor :father_name, :mother_name #assuming that Parent model has only the :name attribute

  validates_presence_of :name, :age
  # simply add custom validation messages for fields
  validates_presence_of :father_name, message: 'Fill your father name'
  validates_presence_of :mother_name, message: 'Fill your mother name'

  def save
    persist! if valid?
  end

  private
  def persist!
    student = Student.new(name: @name, age: @age)
    student.parents << Parent.new(name: @father_name)
    student.parents << Parent.new(name: @mother_name)
    student.save!
  end
end


class StudentController 

  def create
    @student = CompleteStudentForm.new(params[:complete_student_form])

    if @student.save
      redirect_to :show, @student
    else
      render :new
    end
  end
end