【问题标题】:Using Namespace nested resources with MongoMapper EmbeddedDocument with form_for将命名空间嵌套资源与 MongoMapper EmbeddedDocument 和 form_for 一起使用
【发布时间】:2012-10-22 10:15:00
【问题描述】:

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

技术栈:

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

来自routes.rb的相关摘录:

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

我的模型在Mock::PatientMock::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相同,问题就出在这里。

建议?

【问题讨论】:

    标签: namespaces ruby-on-rails-3.2 mongomapper form-for nested-resources


    【解决方案1】:

    已解决:

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

    redirect_to @mock_allergy
    

    代替:

    redirect_to mock_patient_allergy_path(@mock_patient, @mock_allergy)
    

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

    我的另一个错误是,在对过敏建模时,我应该使用 embedded_in :patient 而不是 belongs_to :patient 行。

    派生问题:

    为什么@mock_allergyMock::Patient::Allergy 的实例知道它是一个嵌套资源,却无法生成包含正确patient_id 的正确路径?

    【讨论】:

      猜你喜欢
      • 2017-01-24
      • 2011-02-12
      • 2013-01-14
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 2011-01-03
      相关资源
      最近更新 更多