0

我正在提交一个表单,该表单id为子资源及其父资源的id. 我不知道如何让表单提交停止将子 ID 复制为父资源的 ID。

技术栈:

  • 导轨 3.2.8
  • MongoMapper
  • 简单表格(尽管它包装的股票 form_for 也会出现同样的问题)

相关摘录routes.rb

namespace :mock do 
  resources :patients do
    resources :allergies
  end
end

我的模型在Mock::Patient和中定义Mock::Patient::Allergy

在我的 Allergy 资源视图部分 _form.html.erb 中,我有以下打开表单助手的用法(我使用简单表单,但使用库存 form_for 助手会出现相同的结果):

<%= simple_form_for [@mock_patient, @mock_allergy], :url => mock_patient_allergy_path(@mock_allergy),  do |f| %>

在渲染时,它正在提交到此路由:

/mock/patients/:patient_id/allergies/:id

所以我的 allergies_controller.rb 文件确实收到了更新操作(在编辑操作的情况下)。

但是,当我查看参数时,params[:patient_id] 与 params[:id] 相同。两者实际上都是正在编辑的特定嵌套过敏资源的 id 值。父资源(在这种情况下为患者)丢失了其上下文。

因此,我开始在表单中包含一个隐藏字段:

<%= hidden_field_tag('patient_id', @mock_patient.id) if @mock_patient %>

当我在提交表单之前查看页面源时,果然可以看到正确 patient_id的值。

似乎有一些内置的表单处理逻辑将父资源的 id 替换为子资源的 id。

我的模型文件,使用 Mongo Mapper 是:

class Mock::Patient
  include MongoMapper::Document
  # other Patient model keys here
  many :allergies, :class => Mock::Patient::Allergy 
end

class Mock::Patient::Allergy
  include MongoMapper::EmbeddedDocument
  # other Allergy model keys here
  belongs_to :patient, :class => Mock::Patient
end

回顾一下,我可以修改表单标签以提交到正确的路由,但是受控接收的参数哈希被抬高 - 丢失了父资源上下文。

我尝试过的表单标签的其他变体无济于事:

<%= simple_form_for @mock_allergy, :url => mock_patient_allergy_path(@mock_allergy),  do |f| %>

<%= simple_form_for @mock_allergy, :html => { :class => 'form-horizontal' } do |f| %>

在上述两种情况下,生成的基本路由模板都很好,它到达了我的 allergies_controller,但是当我去检查时params[:patient_id],我得到了一个不正确的值。它实际上是params[:id].

具体例子

我的表单标签行:

<%= simple_form_for @mock_allergy, :url => mock_patient_allergy_path(@mock_patient, @mock_allergy) do |f| %>

这会生成一个页面,当我查看源代码时,会报告:

<form accept-charset="UTF-8" 
action="/mock/patients/5092c815fdb5424df800000d/allergies/5092c815fdb5424df800001c" 
class="simple_form form-horizontal" 
id="edit_mock_patient_allergy_5092c815fdb5424df800001c" method="post" 
novalidate="novalidate"> 

但是当它碰到我的控制器时,他希望根据 on params[:patient_id] 找到一个 Mock::Patient,它没有得到我期望的 '5092c815fdb5424df800000d' 值。在我的浏览器上,错误页面表明收到的参数是:

{ "patient_id"=>"5092c815fdb5424df800001c",
          "id"=>"5092c815fdb5424df800001c" }

这两个ID是相同的,问题就出在这里。

建议?

4

1 回答 1

0

解决了:

在我的更新方法中,成功后来自脚手架的重定向是:

redirect_to @mock_allergy

代替:

redirect_to mock_patient_allergy_path(@mock_patient, @mock_allergy)

所以,我被踢到了一个正确形成的路线,但有一个虚假的病人 ID。

我的另一个错误是,在为 Allergy 建模时,我应该使用 aembedded_in :patient而不是belongs_to :patient线。

派生问题:

为什么它,that@mock_allergy和 的实例Mock::Patient::Allergy,知道它是一个嵌套资源,却不能生成包含正确的正确路径patient_id

于 2012-11-01T20:18:08.650 回答