我正在开发一个Rails应用程序,该应用程序每小时一次以大JSON blob的形式提取外部配置数据。我的应用程序具有在满足某些约束条件时自动执行的服务。约束被指定为一对(JSON路径,可接受的值),并且如果指定路径上的当前JSON摄取等于指定值,则认为约束。
服务不是数据库中引用约束的唯一内容,并且这些不同对象中的每一个都可以具有多个约束。出于这个原因,约束具有它们自己的模型/表,并且被引用而不是引用它们的所有者,其可以是服务或其他对象。此外,在服务上存在特殊处理的约束,该约束控制关于该服务的通知紧急性,该服务也被指定为约束。这是我的模特
class Constraint < ActiveRecord::Base
attr_accessible path, value
end
class ServiceConstraints < ActiveRecord::Base
belongs_to :service
belongs_to :constraint, dependent: :destroy
self.primary_key = :constraint
attr_accesible :service_id, :constraint_id, :constraint_attributes
accepts_nested_attributes_for :constraint
end
class Service < ActiveRecord::Base
#a bunch of other stuff irrelevant to the question
belongs_to :urgency_constraint, class_name: Constraint
has_many :service_constraints, class_name: ServiceConstraint
has_many :constraints, :through => :service_constraints, class_name: Constraint
accepts_nested_attributes_for :urgency_constraint, allow_destroy: true
accepts_nested_attributes_for :service_constraints, allow_destroy: true
attr_accessible :name, :service_constraints_attributes
end
我试图让表单设置处理这个,这样当我编辑服务时,我可以直接添加一个或多个约束,即我可以点击添加约束&#39;并且出现两个新字段,用户可以在其中输入约束路径和值。洗涤,冲洗,必要时重复。用户还应该能够更改已存在的约束的路径和值的内容,并完全删除约束。我并不担心约束表中的重复(路径,值)对。
表格(以haml为单位)
# app/views/services/_form.haml
= form_for(service) do |f|
-# stuff for the other fields
%table
%thead
%tr
%td Constraint Path
%td Constraint Values
%td
%tbody#service-constraints
= f.fields_for :service_constraints do |ff|
= render 'service_constraint_fields', f: ff
%tfoot
%tr
%td
- sac = service.additional_constraints.new
- ff = instantiate_builder("service[service_constraints_attributes][0][constraint_attributes]", service.service_constraints.new, {})
= link_to 'add a constraint', '#', 'data-insertion-node' => "#service-constraints", 'data-insertion-content' => CGI::escapeHTML(render 'service_constraint_fields', f: ff), 'class' => 'add-nested-fields'
# app/views/services/_service_constraint_fields.haml
%tr.service-constraint-fields
= f.fields_for :constraint do |ff|
%td
= ff.text_field :path
%td
= ff.text_field :value
%td
= link_to "remove", "#", "data-removal-node" => ".service-constraint-fields", "class" => "remove-nested-fields"
我试图这样做&#34; Rails方式&#34;,据说这意味着我不需要修改我的控制器。只要没有使用约束,控制器目前工作正常。这里开始我的问题,从不同角度攻击这个问题我遇到了几个问题
首先,正如您所看到的,我正在使用&#34; _service_constraint_fields&#34;部分填充数据插入内容,然后在添加约束时使用JavaScript动态插入到页面中。点击。但是,因为form_builder绑定的ServiceConstraint对象具有constraint_id = nil,所以partial中的fields_for迭代空集合,因此没有插入<td>
元素,只是空<tr>
。 / p>
其次,我手动将约束和service_constraint连接行添加到数据库。它们在表单中正确呈现,但是当我保存表单(没有任何修改)时,我收到此错误:
ActiveRecord::RecordNotFound - Couldn't find Constraint with ID=3 for ServiceConstraint with ID=:
以下是service_params
提交的
{"name"=>"MyBogus", "service_constraints_attributes"=>{"0"=>{"constraint_attributes"=>{"path"=>"a.b.c", "value"=>"some value", "id"=>"3"}, "id"=>""}}}
我无法弄清楚service_constraint
id字段为空的原因。