我有一组相当复杂的模型和关联,我希望我的应用程序的用户能够以单一形式输入所有这些的信息。这似乎是表单对象的工作。所以我做到了,它工作正常。但是我很难理解如何动态添加表单字段。因此,如果教授对象has_many
论文如何将表单添加到表单中,因为表单对象不具有accepts_nested_parameters_for
之类的内容?
我做了一个你可以看到的最小工作示例。该示例适用于添加三个彼此相关的模型。但是,我不知道如何动态添加表单字段并将它们与某些模型的新实例相关联。 https://github.com/blackfist/formobj。我将表单对象和控制器放在这里,但如果您需要更多上下文,请查看回购。
关于这方面的内容有很多教程,但我无法找到统一的来源。例如,有关表单对象的教程,但没有动态添加的字段。或者当您获得ccepts_nested_parameters_for
时动态添加字段的示例。另外,我看到很多指向link_to_function的东西,我理解在Rails 4中不推荐使用。所以我不想在这里使用它作为解决方案。
这是表单对象
class ProfessorForm
include ActiveModel::Model
attr_accessor :prof_name, :prof_subject,
:uni_name, :uni_state, :uni_city, :paper_title, :paper_date,
:paper_publication
validates :prof_name, presence: true
validates :uni_name, presence: true
validates :paper_title, presence:true
def save
if valid?
persist!
true
else
false
end
end
def model_name
Professor.model_name
end
private
def persist!
@uni = University.create!(name: uni_name, city:uni_city, state: uni_state)
@pro = @uni.professors.create!(name: prof_name, subject: prof_subject)
@pap = @pro.papers.create!(title: paper_title, date:paper_date, publication: paper_publication)
end
end
和教授控制员
class ProfessorsController < ApplicationController
def index
@professors = Professor.all
end
def new
@professor_form = ProfessorForm.new
end
def create
@professor_form = ProfessorForm.new(professor_params)
respond_to do |format|
if @professor_form.save
format.html {redirect_to professors_url, notice: 'Professor created successfully.' }
else
format.html { render :new }
end
end
end
private
def professor_params
params.require(:professor).permit(:prof_name, :prof_subject,
:uni_name, :uni_city, :uni_state, :paper_title, :paper_date,
:paper_publication)
end
end
答案 0 :(得分:0)
要动态添加或删除相关模型的字段,您可以尝试Ryan Bates的gem 'nested_forms'。它允许您在单个表单提交中添加多个记录。我不认为表单对象可以解决您的问题。
基本上安装完成后,您可以将以下代码放入视图中:
<%= f.fields_for :papers do |paper_form| %>
<%= paper_form.text_field :name %>
<%= paper_form.link_to_remove "Remove this paper" %>
<% end %>
<p><%= f.link_to_add "Add a paper", :papers %></p>
link_to_add
和link_to_remove
创建或删除字段,并在提交中动态创建多个记录。
此外,我不确定您的表单对象是否需要attr_reader :model_name
才能正常工作。
答案 1 :(得分:0)
我知道很久以前就问过这个问题了,但仍然试着回答这个问题,突然之间它会对某人有所帮助。
我建议使用virtus gem。它允许您在表单类上定义属性。因此,您可以创建Paper类:
class Paper
include Virtus.model
attribute :title, String
attribute :date, Date
attribute :publication, String
end
并将其包含在表单类中。因此,您的ProfessorForm
将如下所示:
class ProfessorForm
include ActiveModel::Model
include Virtus.model
attribute :name
attribute :subject
attribute :papers, Array[Paper]
...
end
控制器中的 professor_params
将以这种方式定义:
def professor_params
params.require(ProfessorForm.new).permit(...)
end
并更改create
方法以迭代纸张数组并创建它们:
def create
@professor_form = ProfessorForm.new(professor_params)
respond_to do |format|
if @professor_form.valid?
professor = Professor.create!(name: professor_params[:name], subject: professor_params[:subject])
professor_params[:papers].each do |professor_paper|
professor.papers.create!(title: professor_paper[:title], date: professor_paper[:date], publication: professor_paper[:publication])
else
format.html { render :new }
end
end
end
我没有提及University
及其与Professor
的关联,但也可以这样做。