ruby-on-rails - 复杂 Rails 表单最佳实践
问题描述
我有一个相对复杂的表单,我正在尝试有效地编写代码。大多数嵌套表单的在线示例都处理非常清晰的层次关系,我的没有。
下面是数据模型。表单的基本工作是创建一个“工作条目”记录,同时创建一个新的“实体”记录 - 这是一个人。几种关系以这种形式出现。
已创建“作业”。在用户点击此表单之前,作业有一对多的“问题”。但是,他们必须填写问题的“答案”。他们还选择许多预先创建的“工作角色”之一。
问题是如何为所有这些相互关联的模型利用“form_with”和“fields_for”。
我的假设是放弃内置的帮助程序,只使用 form_tag 并手动将所有内容滚动在一起。但也许有一种“正确”的方式来滚动不一定遵守亲子关系的表格?在我的示例中,由于许多子对象已经有记录,所以没有纯顶级对象开始,但也许我错了,实体应该是起点?
- 实体 has_many Job_Roles
- 实体 has_many Job_Entries
- Job 有很多 Job_Roles
- Job has_many Job_Entries
- 工作有_很多问题
- 问题有很多答案
- 答案belong_to Entity
- 问题有很多答案
- 机构 has_many Job_Entries 等...
解决方案
Mike 提出的嵌套表单是解决您问题的一种方式。没关系 - 但对于复杂的表单,有很多验证,它可能不是最好的解决方案)。您可以考虑改用 FormObject 模式。
FormObject 是一个简单的 ruby 类,你可以将它保存在Forms
文件夹中并使用如下:
class JobEntryForm
include ActiveModel::Model
attr_accessor :customer_id, :agency_id, :name, :question_text #you can use atributes from different models
validates :customer_id, presence: true #you can validate yu attributes as you want - your in necessity to use model validation
def initialize(attributes:)
@customer_id = attributes[:customer_id]
@agency_id = attributes[:agency_id]
@name = attributes[:name]
@question_text = attributes[:question_text]
end
#implement whatever you need
end
比你的控制器:
@form = JobEntryForm.new
你的看法:
<%= form_for @form do |f| %>
<%= f.label :customer_id, 'Customer' %>:
<%= f.text_field :customer_id %>
...
<%= f.submit %>
<% end %>
并且 - 最后 - 在您的控制器创建方法中:
def create
@form = CreateJobEntry.new.call(attributes: form_params) #service object to keep your controller clean.
end
推荐阅读
- javascript - useEffect 中的 setState 在酶中不起作用
- git - 如何解决:“对不起,不能拆分这个大块”?
- azure - 在 Azure DevOps 中运行 az cli 命令
- raspberry-pi - 在 Raspberry pi 3 上未以单声道接收 UDP
- regex - 如何使用 OR 比较 Google 表格中的多个 RIGHT 函数来缩短公式?
- mysql - 如何从 amfphp 数组在 AS3(ActionScript 3.0)中的文本输入中显示字符串值?
- javascript - How to export csv object in react
- postgresql - 如何在 Postgresql 中进行主动活动 HA 节点设置
- python - 将 selenium webdriver 字段写入 txt 文件
- java - 如果另一个地图的键不存在,如何将元素添加到地图