【问题标题】:Rails 4 Nested Form not Passing Nested Attributes in ParamsRails 4嵌套表单未在参数中传递嵌套属性
【发布时间】:2016-03-04 14:53:25
【问题描述】:

当我提交表单时,它在参数中传递了{"utf8"=>"✓", "authenticity_token"=>"blah", "client"=>{"first_name"=>"jack", "last_name"=>"kool","complaints"=>{"symptom"=>"burnt"},我得到了Unpermitted Parameters: complaints,因为投诉嵌套在客户端中,它应该传递complaints_attributes,就像我在强参数中设置的一样,我不知道为什么不是。

class ClientsController < ApplicationController

 def new
  @client = Client.new
 end

 def edit
  @client = Client.find(params[:id])
 end

 def create
  @client = Client.new(client_params)

  if @client.save
   redirect_to @client
  else
   render 'new'
  end  
end

def update
 @client = Client.find(params[:id])

 if @client.update(client_params)
  redirect_to @client
 else
  render 'edit'
 end
end

private

 def client_params
   params.require(:client).permit(:first_name, :last_name, complaints_attributes: [ :symptom, :id ])
 end
end

客户端模型:

class Client < ActiveRecord::Base
 has_many :complaints
 has_one :personal_disease_history
 has_one :family_disease_history
 has_many :surgeries
 has_many :hospitalizations
 has_many :medications
 has_many :allergies

 validates :first_name, :last_name, presence: true

 accepts_nested_attributes_for :complaints
end

投诉模式:

class Complaint < ActiveRecord::Base
 belongs_to :client
end

表格:

<%= form_for :client, url: clients_path, html: { class: "form-inline" } do |f| %>
 <div class="panel panel-success">
  <div class="panel-heading">
   <h3 class="panel-title">Health History Form</h3>
  </div>
 <div class="panel-body">
  <div class="form-blocks"><legend>Name</legend>
    <div class="form-group">
      <%= f.label :first_name, class: "sr-only" %>
      <%= f.text_field :first_name, class: "form-control", placeholder: "First Name"  %>
    </div>
    <div class="form-group">
      <%= f.label :last_name, class: "sr-only" %>
      <%= f.text_field :last_name, class: "form-control", placeholder: "Last Name"  %>
    </div>
  </div>
  <div class="form-blocks"><legend>Complaints</legend>
    <div class="form-group">
      <%= f.fields_for :complaints do |builder| %>
        <%= builder.label :symptom, class: "sr-only" %>
        <%= builder.text_field :symptom, class: "form-control", placeholder: "Symptom"  %>
      <% end %>
    </div>
  </div>
 <div>
  <%= f.submit "Submit Form", class: "btn btn-primary btn-lg"%>
 </div>
<% end %>

【问题讨论】:

  • 在控制器中,尝试使用.build 构建您的客户端模型,而不是在其上调用.new。这应该将相关的投诉构建到客户端。
  • 如果这不起作用,一个临时的解决方案是在您的客户端控制器创建操作中说 Complaint.create(params["complaints"])。
  • @harishsr 添加.build 代替.new 会产生无方法错误
  • @toddmetheny 您的建议将记录保存到投诉数据库表中,但“症状”为空,我仍然看到“未经允许的参数:投诉”。肯定有进步,但我需要数据持续存在。
  • 您的投诉表上是否提及客户?

标签: ruby-on-rails-4 nested-forms strong-parameters


【解决方案1】:

在客户端控制器中创建操作,尝试在 if @client.save 中这样说:

Complaint.create(symptom: params[
"client"]["complaints"]["symptom"], client_id: @client.id)

unpermitted 参数与嵌套属性问题有关,但这应该得到实际的记录保存。如果还不行,请在提交周围发布堆栈跟踪。

还有其他一些想法:但是 (1) 您在允许的参数中有投诉属性,但您可以将其更改为投诉 bc,这就是参数中的内容。

【讨论】:

  • 这确实有效,但正如你所说,它看起来很hacky。由于参数不在私有client_params 方法中,此方法是否还会打开安全漏洞?有什么让它不那么hacky的想法吗?无论如何,感谢您的帮助。
  • @rymcmahon 如果可行,请接受答案 :) 为了让它不那么老套,你可以尝试让它像以前一样作为嵌套属性工作。您的 form_for 可能需要同时传递两个对象。很难解释,但类似于 form_for [:client, :complaint] 而不仅仅是 form_for :client。
  • 我找到了一个不那么老套的解决方案。我将&lt;%= form_for :client, url: clients_path, html: { class: "form-inline" } do |f| %&gt; 更改为&lt;%= form_for (@client), html: { class: "form-inline" } do |f| %&gt; 并将@client.complaints.build 添加到客户端的新操作中。感谢您的领导。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多